欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

winxp总管破解笔记(二)(完结篇) (15千字)

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了:)

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功