winxp总管破解笔记(二)(完结篇) (15千字)
上一次我们对.net框架的程序有了初步的认识,并且爆破了注册验证,但是研究的路是无止境的,不能只局限于爆破亚,这次我们将深入研究它的算法(后面你会看到虽然算法不难,但由于缺乏动态调试工具,从而难度增加了)。并且由于我的疏忽,做出注册机后一个细节的问题使得注册码仍然不对,于是由此引发diy
msil使它显示正确注册码,已修正我们的注册机(如果有好用的动态工具,这些将很简单,可惜呀:)。
所以在这篇文章里我将谈到两个问题,一是算法,二是如何diy
msil。
先讲算法吧,这是我们最终的目的。
还记得上次我们看到爆破的那个Registered()方法吗,我们将从那里开始来找寻算法的根源。
调出来可以看到这个:
IL_0037: ldloc.0
IL_0038:
ldloc.1
IL_0039: call string WinXP_Manager.MyClsOther/MyClsRegister::FromHDSNGetRegisterCode(string)
IL_003e: ldc.i4.0
IL_003f: call
int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType::StrCmp(string,
string,
bool)
IL_0044: ldc.i4.0
IL_0045: beq.s IL_004f
FromHDSNGetRegisterCode(string)这个就是关键,他生成了用来比较的string,也就是说算法应该是这样:
FromHDSNGetRegisterCode(用户名)=注册码;
那么这个方法是哪里来的呢,就在这个MyClsRegister类中有他的描述,再调出来看看:
.method public static string FromHDSNGetRegisterCode(string strCodeWord)
cil managed
{
// Code size 24 (0x18)
.maxstack 2
.locals init (string V_0,
class WinXP_Manager.MyClsOther/MyClsEncrypt V_1)
IL_0000: nop
IL_0001: ldarg.0
IL_0002:
newobj instance void WinXP_Manager.MyClsOther/MyClsEncrypt::.ctor(string)//newobj用来初始化一个类的对象
IL_0007: stloc.1
IL_0008: ldloc.1
IL_0009: call string WinXP_Manager.MyCls/MyClsSysInfo::GetPySerialNum()//这个我们可以在MyCls中找到,是获得硬盘序列号并作了一些处理(也就是加密转化了)变成了机器码
IL_000e: callvirt instance string WinXP_Manager.MyClsOther/MyClsEncrypt::Encrypt(string)
IL_0013: stloc.0
IL_0014: br.s
IL_0016
IL_0016: ldloc.0
IL_0017: ret
} // end of method MyClsRegister::FromHDSNGetRegisterCode
很好,我们看到了MyClsEncrypt这个类的两个方法,我们再来总结一下:
他先用.ctor(strCodeWord)(这个方法所有的类中都有,是用来初始化类的成员的),然后Encrypt(机器码)。
现在我们的目标就是MyClsEncrypt
先来看初始化的方法:
.method public specialname rtspecialname
instance void .ctor(string strCodeWord)
cil managed//这里可以看到初始化需要传递一个参数进来,strcodeword就是用户名
{
// Code size
172 (0xac)
.maxstack 4
.locals init
(int32 V_0,
int32 V_1,
int32 V_2)
IL_0000: nop
IL_0001:
ldarg.0
IL_0002: call instance void [mscorlib]System.Object::.ctor()
IL_0007: nop
IL_0008: ldarg.0
IL_0009: ldc.i4.s 98
IL_000b: newarr
[mscorlib]System.String//这里初始化一个大小为98的字符数组
IL_0010: stfld
string[] WinXP_Manager.MyClsOther/MyClsEncrypt::strCryptMatrix//存到这里
IL_0015: ldarg.0
IL_0016: ldarg.1
//把参数推栈
IL_0017: stfld string WinXP_Manager.MyClsOther/MyClsEncrypt::CodeWord//存到CodeWord这个变量里
IL_001c: ldarg.0
IL_001d: ldstr
"8x3p5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTU"
+ "VWXYZ1246790"
IL_0022: stfld string WinXP_Manager.MyClsOther/MyClsEncrypt::Matrix//把上面的字符串存到这个变量里
IL_0027: ldc.i4.1
IL_0028: stloc.0
//loc.0=1
IL_0029: ldarg.0
IL_002a: ldarg.0
IL_002b: ldfld string WinXP_Manager.MyClsOther/MyClsEncrypt::Matrix
IL_0030: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Len(string)//算一下长度这里=62
IL_0035: stfld int32 WinXP_Manager.MyClsOther/MyClsEncrypt::LAM//存进来,也就是LAM=62
IL_003a: ldarg.0
IL_003b: ldfld
string[] WinXP_Manager.MyClsOther/MyClsEncrypt::strCryptMatrix
IL_0040: ldc.i4.1
IL_0041: ldarg.0
IL_0042:
ldfld string WinXP_Manager.MyClsOther/MyClsEncrypt::Matrix
IL_0047: stelem.ref //这个用表达式写就是strCryptMatrix[1]=Matrix,具体可以查手册
IL_0048: nop
IL_0049: ldc.i4.2
IL_004a: ldarg.0
IL_004b: ldfld int32
WinXP_Manager.MyClsOther/MyClsEncrypt::LAM
IL_0050: stloc.2
//loc.2=62
IL_0051: stloc.1 //loc.1=2
IL_0052: br.s IL_00a6 //下去看看,发现是一个循环,表达是应该是:while
loc.1<loc.2 do
IL_0054: ldarg.0
IL_0055:
ldarg.0
IL_0056: ldfld string[] WinXP_Manager.MyClsOther/MyClsEncrypt::strCryptMatrix
IL_005b: ldloc.0
IL_005c: ldelem.ref
//推strCryptMatrix[loc.0]
IL_005d: ldc.i4.1
IL_005e: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Left(string,
int32) //从左边取一个
IL_0063: stfld string WinXP_Manager.MyClsOther/MyClsEncrypt::mov1
//存到mov1
IL_0068: ldarg.0
IL_0069: ldarg.0
IL_006a: ldfld string[] WinXP_Manager.MyClsOther/MyClsEncrypt::strCryptMatrix
IL_006f: ldloc.0
IL_0070: ldelem.ref
//推strCryptMatrix[loc.0]
IL_0071: ldarg.0
IL_0072: ldfld int32 WinXP_Manager.MyClsOther/MyClsEncrypt::LAM
IL_0077: ldc.i4.1
IL_0078: sub.ovf
IL_0079: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Right(string,
int32) //从右边取61个
IL_007e: stfld string WinXP_Manager.MyClsOther/MyClsEncrypt::mov2
//存到mov2
IL_0083: ldarg.0
IL_0084: ldfld
string[] WinXP_Manager.MyClsOther/MyClsEncrypt::strCryptMatrix
IL_0089: ldloc.1
IL_008a: ldarg.0
IL_008b: ldfld string WinXP_Manager.MyClsOther/MyClsEncrypt::mov2
IL_0090: ldarg.0
IL_0091: ldfld
string WinXP_Manager.MyClsOther/MyClsEncrypt::mov1
IL_0096:
call string [mscorlib]System.String::Concat(string,
string) //连接字符串
IL_009b: stelem.ref //存入表达式应该是:strCryptMatrix[loc.1]=mov2+mov1
IL_009c: nop
IL_009d: ldloc.0
IL_009e:
ldc.i4.1
IL_009f: add.ovf
IL_00a0:
stloc.0 //loc.0=loc.0+1
IL_00a1: nop
IL_00a2: ldloc.1
IL_00a3: ldc.i4.1
IL_00a4:
add.ovf
IL_00a5: stloc.1 //loc.1=loc.1+1
IL_00a6: ldloc.1
IL_00a7: ldloc.2
IL_00a8:
ble.s IL_0054//循环
IL_00aa: nop
IL_00ab: ret
} // end of method MyClsEncrypt::.ctor
来总结一下,初始化就是对几个成员赋值:
CodeWord=用户名
LAM=62
Matrix=8x3p5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTUVWXYZ1246790
strCryptMatrix[1]=8x3p5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTUVWXYZ1246790
strCryptMatrix[2]=x3p5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTUVWXYZ12467908
strCryptMatrix[3]=3p5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTUVWXYZ12467908x
strCryptMatrix[4]=p5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTUVWXYZ12467908x3
strCryptMatrix[5]=5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTUVWXYZ12467908x3p
.
.
.
strCryptMatrix[62]=08x3p5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTUVWXYZ124679
现在来看看另一个方法:
.method public instance string Encrypt(string
strEncrypted) cil managed //他也要一个参数,strEncrypted=机器码
{
// Code
size 289 (0x121)
.maxstack 5
.locals init (string V_0,
string V_1,
string V_2,
int32 V_3,
int32 V_4,
int32 V_5,
int32 V_6,
int32 V_7)
IL_0000: nop
IL_0001: nop
.try
{
IL_0002: ldarg.1
IL_0003:
stloc.2 //loc.2=机器码
IL_0004: ldarg.0
IL_0005: ldarg.1 //参数推栈
IL_0006:
callvirt instance int32 [mscorlib]System.String::get_Length()
//取长度
IL_000b: stfld int32
WinXP_Manager.MyClsOther/MyClsEncrypt::LS2E //保存
IL_0010: ldarg.0
IL_0011: ldarg.0
IL_0012: ldfld string WinXP_Manager.MyClsOther/MyClsEncrypt::CodeWord
//取用户名
IL_0017: callvirt instance int32
[mscorlib]System.String::get_Length() //长度
IL_001c: stfld int32 WinXP_Manager.MyClsOther/MyClsEncrypt::LCW
//保存
IL_0021: ldarg.0
IL_0022: ldstr ""
IL_0027:
stfld string WinXP_Manager.MyClsOther/MyClsEncrypt::EncryptedLetter
//初始化
IL_002c: ldarg.0
IL_002d:
ldstr ""
IL_0032: stfld
string WinXP_Manager.MyClsOther/MyClsEncrypt::EncryptedString //初始化
IL_0037: ldc.i4.1
IL_0038: stloc.s
V_4 //V_4=1
IL_003a: ldc.i4.1
IL_003b: ldarg.0
IL_003c: ldfld
int32 WinXP_Manager.MyClsOther/MyClsEncrypt::LS2E
IL_0041:
stloc.s V_7 //V_7=LS2E=机器码长度
IL_0043:
stloc.3 //loc.3=1
IL_0044:
br IL_0100 //while loc.3<V_7 do
IL_0049: ldloc.2
IL_004a: ldloc.3
IL_004b: ldc.i4.1
IL_004c: call
string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32,
int32)//取机器码的第loc.3位
IL_0051: stloc.0 //存进来
IL_0052: ldarg.0
IL_0053: ldc.i4.1
IL_0054: ldarg.0
IL_0055: ldfld
string WinXP_Manager.MyClsOther/MyClsEncrypt::Matrix
IL_005a: ldloc.0
IL_005b: ldc.i4.0
IL_005c: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::InStr(int32,
string,
string,
valuetype
[Microsoft.VisualBasic]Microsoft.VisualBasic.CompareMethod)//判断机器码的第loc.3位在Matrix字符串的哪个位置
IL_0061: stfld int32 WinXP_Manager.MyClsOther/MyClsEncrypt::MP
//MP=位置值
IL_0066: ldarg.0
IL_0067: ldarg.0
IL_0068: ldfld
string WinXP_Manager.MyClsOther/MyClsEncrypt::CodeWord
IL_006d:
ldloc.s V_4
IL_006f: ldc.i4.1
IL_0070: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32,
int32)//取用户名的第V_4位
IL_0075: stfld string WinXP_Manager.MyClsOther/MyClsEncrypt::CWL
//存到CWL里
IL_007a: ldc.i4.1
IL_007b:
ldarg.0
IL_007c: ldfld int32 WinXP_Manager.MyClsOther/MyClsEncrypt::LAM
IL_0081: stloc.s V_6 //V_6=LAM=62
IL_0083: stloc.s V_5 //V_5=1
IL_0085: br.s IL_00e2 //while V_5<V_6
do
IL_0087: ldarg.0
IL_0088:
ldfld string[] WinXP_Manager.MyClsOther/MyClsEncrypt::strCryptMatrix
IL_008d: ldloc.s V_5
IL_008f: ldelem.ref //推strCryptMatrix[V_5]
IL_0090:
ldarg.0
IL_0091: ldfld int32 WinXP_Manager.MyClsOther/MyClsEncrypt::MP
IL_0096: ldc.i4.1
IL_0097: call
string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Mid(string,
int32,
int32)//取strCryptMatrix[V_5]的第MP位
IL_009c: ldarg.0
IL_009d:
ldfld string WinXP_Manager.MyClsOther/MyClsEncrypt::CWL
//CWL=用户名的第V_4位
IL_00a2: ldc.i4.0
IL_00a3: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType::StrCmp(string,
string,
bool) //比较上面两个字符
IL_00a8: ldc.i4.0
IL_00a9: bne.un.s
IL_00da //不等就V_5=V_5+1,循环取strCryptMatrix[V_5]的第MP位与CWL比较直到相等
IL_00ab: ldarg.0
IL_00ac: ldarg.0
IL_00ad: ldfld string[] WinXP_Manager.MyClsOther/MyClsEncrypt::strCryptMatrix
IL_00b2: ldloc.s V_5
IL_00b4: ldelem.ref
IL_00b5: ldc.i4.1
IL_00b6: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::Left(string,
int32)//取strCryptMatrix[V_5]的左边第一个字符作为机器码的加密后的编码
IL_00bb: stfld string WinXP_Manager.MyClsOther/MyClsEncrypt::EncryptedLetter
IL_00c0: ldarg.0
IL_00c1: ldarg.0
IL_00c2: ldfld string WinXP_Manager.MyClsOther/MyClsEncrypt::EncryptedString
IL_00c7: ldarg.0
IL_00c8: ldfld
string WinXP_Manager.MyClsOther/MyClsEncrypt::EncryptedLetter
IL_00cd: call string [mscorlib]System.String::Concat(string,
string)
IL_00d2: stfld string WinXP_Manager.MyClsOther/MyClsEncrypt::EncryptedString
//将编码循环连接起来
IL_00d7: nop
IL_00d8:
br.s IL_00e8
IL_00da: nop
IL_00db: nop
IL_00dc: ldloc.s
V_5
IL_00de: ldc.i4.1
IL_00df:
add.ovf
IL_00e0: stloc.s V_5
IL_00e2: ldloc.s V_5
IL_00e4:
ldloc.s V_6
IL_00e6: ble.s
IL_0087
IL_00e8: ldloc.s V_4
IL_00ea: ldc.i4.1
IL_00eb: add.ovf
IL_00ec: stloc.s V_4
IL_00ee: ldloc.s V_4
IL_00f0: ldarg.0
IL_00f1: ldfld int32 WinXP_Manager.MyClsOther/MyClsEncrypt::LCW
IL_00f6: ble.s IL_00fb
IL_00f8: ldc.i4.1
IL_00f9: stloc.s
V_4
IL_00fb: nop
IL_00fc:
ldloc.3
IL_00fd: ldc.i4.1
IL_00fe:
add.ovf
IL_00ff: stloc.3
IL_0100:
ldloc.3
IL_0101: ldloc.s V_7
IL_0103: ble IL_0049
IL_0108: ldarg.0
IL_0109: ldfld
string WinXP_Manager.MyClsOther/MyClsEncrypt::EncryptedString
IL_010e: stloc.1
IL_010f: leave.s
IL_011e
} // end .try
catch [mscorlib]System.Exception
{
IL_0111: call void
[Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class
[mscorlib]System.Exception)
IL_0116: nop
IL_0117: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError()
IL_011c: leave.s IL_011e
}
// end handler
IL_011e: nop
IL_011f: ldloc.1
IL_0120: ret
} // end of method MyClsEncrypt::Encrypt
总结一下用DELPHI源码描述如下:(有点不同,因为他的方法很笨,稍微计算一下就变成下面简单的算法)
var
machinecode,key,resultstr,matrix:string;
lm,lk,i,t,m,resultpos:integer;
begin
matrix:='8x3p5BeabcdfghijklmnoqrstuvwyzACDEFGHIJKLMNOPQRSTUVWXYZ1246790';
machinecode:=Form1.FlatEdit1.Text;
key:= Form1.FlatEdit2.Text;
lm:=strlen(pchar(machinecode));
lk:=strlen(pchar(key));
i:=1;
resultstr:='';
while i<=lm do
begin
if i<=lk
then t:=i
else t:=i-lk*((i-1) div lk);
m:=pos(key[t],matrix)-pos(machinecode[i],matrix);
if m<=0 then
resultpos:=m+63
else
resultpos:=m+1;
resultstr:=resultstr+copy(matrix,resultpos,1);
i:=i+1;
end;
Form1.FlatEdit3.Text:=resultstr;
end;
算法完成了,但是我原先的程序里是错位的,也就是算出的注册码都比正确的前移了一个,我一直没找到原因,如果有个能动态调试的工具可以让我看到推栈里的一个值,我就可以纠正这个错误,但是没有(有个cordbg不会用,也不知道能不能达到目的:),所以我有了个想法,点注册的时候你会发现他弹出一个错误提示框,能不能利用他把正确的注册码弹出来,我不就可以知道错在哪了吗(如果我没出错,就不会有下面的diy
msil了:)
