一个vb.net crackme分析
 

标题:一个vb.net crackme分析
链接:http://www.unpack.cn/viewthread.php?tid=20746&extra=page%3D1
贴者:noirlucifer
日期:2007-12-25 19:39

  今天又去crackmes.de逛了逛发现了个新的crackme,于是就有了下文.
  拿到手peid查壳:Microsoft Visual C# / Basic .NET,立即ildasm一下.然后找到ok_click事件,代码如下:
  
  .method private instance void  OK_Click(object sender,
                                          class [mscorlib]System.EventArgs e) cil managed
  {
    // 代码大小       279 (0x117)
    .maxstack  4
    .locals init (string V_0,
             string V_1,
             string V_2,
             string V_3,
             string V_4,
             string V_5,
             string V_6,
             string V_7,
             string V_8,
             string V_9,
             string V_10,
             string V_11,
             string V_12,
             string V_13)
    IL_0000:  ldarg.0
    IL_0001:  callvirt   instance void Crackme3.LoginForm1::chkdbg()
    IL_0006:  ldstr      "6AE199A93C381BF6D5DE27491139D3F9"           
    IL_000b:  stloc.s    V_11                                                 //v11= 6AE199A93C381BF6D5DE27491139D3F9                                 
    IL_000d:  ldstr      "9F6CF82DEB99289E14AEA9DCC24E54CB"
    IL_0012:  stloc.s    V_9                                                  //v9=9F6CF82DEB99289E14AEA9DCC24E54CB
    IL_0014:  ldstr      "ABDF74354GFDDF344HJ4667HVHJVDGG"
    //v12=ABDF74354GFDDF344HJ4667HVHJVDGG(这个v12起到key的作用,后面的encode,decode都要用到它)
    IL_001b:  ldloc.s    V_11
    IL_001d:  ldloc.s    V_12
    IL_001f:  call       string Crackme3.Crypto::StringEncrypt(string,
                                                               string)
    IL_0024:  stloc.s    V_6                                                  //v6=encrypt(v11,v12)
    IL_0026:  ldloc.s    V_11
    IL_0028:  ldloc.s    V_12
    IL_002a:  call       string Crackme3.Crypto::StringEncrypt(string,
                                                               string)
    IL_002f:  stloc.s    V_4                                                     //v4=encrypt(v11,v12)
    IL_0031:  ldstr      "1p9vPg/XReKyDADJx7O1juK6KwsNneaLV+iztkVVjptfLHbxO+"    //这是个经过encrypt的值记为s1
    + "suSRX8V/lZ+ZJ3"
    IL_0036:  ldloc.s    V_12                                                 
    IL_0038:  call       string Crackme3.Crypto::StringDecrypt(string,
                                                               string)
    IL_003d:  stloc.2                                                             //l2=decrypt(s1,v12)
    IL_003e:  ldstr      "8+k/OamDIWXKRS7UrbAfiizNVwtnb3+WNSzdENYNaWNQp4uCP1"     //这也是个经过encrypt的值记为s2
    + "NbjLAzIAf2eKJq"
    IL_0043:  ldloc.s    V_12
    IL_0045:  call       string Crackme3.Crypto::StringDecrypt(string,
                                                               string)
    IL_004a:  stloc.0                                                              //l0=decrypt(s2,v12)
    IL_004b:  ldarg.0
    IL_004c:  callvirt   instance void Crackme3.LoginForm1::chkdbg()               //检查调试器,用的isdebuggerpresent.
    IL_0051:  ldarg.0
    IL_0052:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox Crackme3.LoginForm1::get_UsernameTextBox()
    IL_0057:  callvirt   instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()     //获取用户名
    IL_005c:  call       string Crackme3.Crypto::GetHash(string)                                             //计算用户名的md5值
    IL_0061:  stloc.s    V_10                                                                                //v10=md5(用户名)
    IL_0063:  ldarg.0
    IL_0064:  callvirt   instance void Crackme3.LoginForm1::chkdbg()                                         //检查调试器
    IL_0069:  ldarg.0
    IL_006a:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox Crackme3.LoginForm1::get_PasswordTextBox()
    IL_006f:  callvirt   instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()      //获取注册码
    IL_0074:  call       string Crackme3.Crypto::GetHash(string)                                             //计算注册码的md5值
    IL_0079:  stloc.s    V_8                                                                                 //v8=md5(注册码)
    IL_007b:  ldarg.0
    IL_007c:  callvirt   instance void Crackme3.LoginForm1::chkdbg()                                         //检查调试器
    IL_0081:  ldloc.s    V_10
    IL_0083:  ldloc.s    V_12
    IL_0085:  call       string Crackme3.Crypto::StringEncrypt(string,                                 
                                                               string)
    IL_008a:  stloc.s    V_7                                                                                //v7=encrypt(v10,v12)
    IL_008c:  ldarg.0
    IL_008d:  callvirt   instance void Crackme3.LoginForm1::chkdbg()                                        //检查调试器
    IL_0092:  ldloc.s    V_8
    IL_0094:  ldloc.s    V_12
    IL_0096:  call       string Crackme3.Crypto::StringEncrypt(string,
                                                               string)
    IL_009b:  stloc.s    V_5                                                                                //v5=encrypt(v8,v12)
    IL_009d:  ldarg.0
    IL_009e:  callvirt   instance void Crackme3.LoginForm1::chkdbg()
    IL_00a3:  ldloc.s    V_7
    IL_00a5:  ldloc.s    V_12
    IL_00a7:  call       string Crackme3.Crypto::StringDecrypt(string,
                                                               string)
    IL_00ac:  stloc.3                                                                                       //l3=decrypt(v7,v12)
    IL_00ad:  ldarg.0
    IL_00ae:  callvirt   instance void Crackme3.LoginForm1::chkdbg()                                         //检查调试器
    IL_00b3:  ldloc.s    V_5
    IL_00b5:  ldloc.s    V_12
    IL_00b7:  call       string Crackme3.Crypto::StringDecrypt(string,
                                                               string)
    IL_00bc:  stloc.1                                                                                      // l1=decrypt(v5,v12)
    IL_00bd:  ldarg.0
    IL_00be:  callvirt   instance void Crackme3.LoginForm1::chkdbg()                                        //检查调试器
    IL_00c3:  ldloc.2
    IL_00c4:  ldloc.3
    IL_00c5:  ldc.i4.0
    IL_00c6:  call       int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::CompareString(string,                 //比较l2和l3
                                                                                                                      string,
                                                                                                                      bool)
    IL_00cb:  ldc.i4.0
    IL_00cc:  bne.un.s   IL_00d9
    IL_00ce:  ldloc.0
    IL_00cf:  ldloc.1
    IL_00d0:  ldc.i4.0
    IL_00d1:  call       int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::CompareString(string,                //比较l0和l1
                                                                                                                      string,
                                                                                                                      bool)
    IL_00d6:  ldc.i4.0
    IL_00d7:  beq.s      IL_00dc
    IL_00d9:  ldc.i4.0
    IL_00da:  br.s       IL_00dd
    IL_00dc:  ldc.i4.1
    IL_00dd:  ldloc.s    V_11
    IL_00df:  ldloc.3
    IL_00e0:  ldc.i4.0
    IL_00e1:  call       int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::CompareString(string,               //比较v11和l3
                                                                                                                      string,
                                                                                                                      bool)
    IL_00e6:  ldc.i4.0
    IL_00e7:  bne.un.s   IL_00f5
    IL_00e9:  ldloc.s    V_9
    IL_00eb:  ldloc.1
    IL_00ec:  ldc.i4.0
    IL_00ed:  call       int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Operators::CompareString(string,               //比较v9和l1
                                                                                                                      string,
                                                                                                                      bool)
    IL_00f2:  ldc.i4.0
    IL_00f3:  beq.s      IL_00f8
    IL_00f5:  ldc.i4.0
    IL_00f6:  br.s       IL_00f9
    IL_00f8:  ldc.i4.1
    IL_00f9:  or
    IL_00fa:  brfalse.s  IL_0105
    IL_00fc:  ldstr      "Yes, you found the secret username & password! Wel"
    + "l Done!"
    IL_0101:  stloc.s    V_13
    IL_0103:  br.s       IL_010c
    IL_0105:  ldstr      "I'm sorry, please try again."
    IL_010a:  stloc.s    V_13
    IL_010c:  ldloc.s    V_13
    IL_010e:  ldc.i4.0
    IL_010f:  ldnull
    IL_0110:  call       valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.MsgBoxResult [Microsoft.VisualBasic......]
    IL_0115:  pop
    IL_0116:  ret
  } // end of method LoginForm1::OK_Click
  
  总结以下算法
  l0=decrypt(s2,v12)
  l1=decrypt(v5,v12)
  l2=decrypt(s1,v12)
  l3=decrypt(v7,v12)
  v4 =encrypt(v11,v12)
  v5=encrypt(v8,v12)
  v6 =encrypt(v11,v12)
  v8=md5(注册码)
  v7=encrypt(v10,v12)
  v9 =9F6CF82DEB99289E14AEA9DCC24E54CB
  v10=md5(用户名)
  v11=6AE199A93C381BF6D5DE27491139D3F9
  v12=ABDF74354GFDDF344HJ4667HVHJVDGG
  注册成功的条件为(l2=l3并且l0=l1)或者(l1=v9并且l3=v11)
  1.先来分析后一种情况:
  l1=decrypt(v5,v12)                1'
  v5=encrypt(v8,v12)                2'
  v8=md5(注册码)                    3'
  
  现在只要求出v8就可以求出注册码了
  由1'和2'可知
  v8=decrypt(v5,v12)=decrypt(encrypt(l1,v12),v12)=l1=v9=9F6CF82DEB99289E14AEA9DCC24E54CB
  用户名=richerd
  同理
  v7=v11=6AE199A93C381BF6D5DE27491139D3F9
  注册码=peugeot
  至此得到了一组固定的注册码
  以上md5破解均在http://www.cmd5.com/上面完成
  2.现在来分析第1种情况即l2=l3并且l0=l1
  l0=decrypt(s2,v12)                1'
  l1=decrypt(v5,v12)                2'
  l0=l1                             3'
  v5=encrypt(v8,v12)                4'
  v8=md5(注册码)                    5'
  l0是固定的因为s2,v12是固定的,所以由1,2,3可得v5=s2
  再由4得v8=decrypt(v5,v12)=decrypt(s2,v12)=l0,所以求出lo就乐意求出注册码了,但是怎么求出l0呢.
  首先我用ildasm反编译,然后转存,然后用ilasm编译但出现错误.我手上也没有.vs.net,想想算了用程序本身吧!
  先运行程序,然后启动od然后附加进程,不知为什么直接用od加载后运行会卡死.然后在code段下f2断点(直接下断
  ShowWindow不行,哪位解释下),断下后再下ShowWindow断点,输入用户名和注册码按ok,此时断下,返回后往上找到过
  程首部如下:
  00EA11E2    53              push    ebx
  00EA11E3    55              push    ebp
  00EA11E4    83EC 18         sub     esp, 18
  00EA11E7    8BF1            mov     esi, ecx
  00EA11E9    8BCE            mov     ecx, esi
  00EA11EB    3909            cmp     dword ptr [ecx], ecx
  00EA11ED    E8 7670BEFF     call    00A88268                         //检测调试器
  00EA11F2    8B1D 006C3C02   mov     ebx, dword ptr [23C6C00]
  00EA11F8    8B05 046C3C02   mov     eax, dword ptr [23C6C04]
  00EA11FE    894424 14       mov     dword ptr [esp+14], eax
  00EA1202    8B3D 086C3C02   mov     edi, dword ptr [23C6C08]
  00EA1208    8BD7            mov     edx, edi                         
  00EA120A    8BCB            mov     ecx, ebx
  00EA120C    FF15 2482A800   call    dword ptr [A88224]               //encrypt
  00EA1212    8BD7            mov     edx, edi
  00EA1214    8BCB            mov     ecx, ebx
  00EA1216    FF15 2482A800   call    dword ptr [A88224]
  00EA121C    8B0D 0C6C3C02   mov     ecx, dword ptr [23C6C0C]         //这个就是s1
  00EA1222    8BD7            mov     edx, edi                         //这个就是v12
  00EA1224    FF15 2882A800   call    dword ptr [A88228]               //decrypt
  00EA122A    894424 08       mov     dword ptr [esp+8], eax           //eax地址保存的就是decrypt的结果
  00EA122E    8B0D 106C3C02   mov     ecx, dword ptr [23C6C10]           也就是我们要找的                                                                     
  00EA1234    8BD7            mov     edx, edi                           l2=67F3A873D1F7CECA8C3C4C1211AE2355
  00EA1236    FF15 2882A800   call    dword ptr [A88228]               //这个decrypt能算出
  00EA123C    894424 04       mov     dword ptr [esp+4], eax             l0=23EB5D0DDB99AF268BC17C9A63D32AD5
  00EA1240    8BCE            mov     ecx, esi                         
  00EA1242    3909            cmp     dword ptr [ecx], ecx
  00EA1244    E8 1F70BEFF     call    00A88268
  00EA1249    8BCE            mov     ecx, esi
  00EA124B    8B01            mov     eax, dword ptr [ecx]
  00EA124D    FF90 10060000   call    dword ptr [eax+610]
  00EA1253    8BC8            mov     ecx, eax
  00EA1255    8B01            mov     eax, dword ptr [ecx]
  00EA1257    FF90 64010000   call    dword ptr [eax+164]                 //GetText
  00EA125D    8BC8            mov     ecx, eax
  00EA125F    FF15 2082A800   call    dword ptr [A88220]                   //md5
  00EA1265    8BE8            mov     ebp, eax
  00EA1267    8BCE            mov     ecx, esi
  00EA1269    3909            cmp     dword ptr [ecx], ecx
  00EA126B    E8 F86FBEFF     call    00A88268
  00EA1270    8BCE            mov     ecx, esi
  00EA1272    8B01            mov     eax, dword ptr [ecx]
  00EA1274    FF90 18060000   call    dword ptr [eax+618]
  00EA127A    8BC8            mov     ecx, eax
  00EA127C    8B01            mov     eax, dword ptr [ecx]
  00EA127E    FF90 64010000   call    dword ptr [eax+164]                   //GetText
  00EA1284    8BC8            mov     ecx, eax
  00EA1286    FF15 2082A800   call    dword ptr [A88220]                    //md5          
  00EA128C    894424 10       mov     dword ptr [esp+10], eax
  00EA1290    8BCE            mov     ecx, esi
  00EA1292    3909            cmp     dword ptr [ecx], ecx
  00EA1294    E8 CF6FBEFF     call    00A88268
  00EA1299    8BD7            mov     edx, edi                         
  00EA129B    8BCD            mov     ecx, ebp                       
  00EA129D    FF15 2482A800   call    dword ptr [A88224]                    //encrypt
  00EA12A3    8BE8            mov     ebp, eax                         
  00EA12A5    8BCE            mov     ecx, esi
  00EA12A7    3909            cmp     dword ptr [ecx], ecx
  00EA12A9    E8 BA6FBEFF     call    00A88268
  00EA12AE    8BD7            mov     edx, edi                       
  00EA12B0    8B4C24 10       mov     ecx, dword ptr [esp+10]         
  00EA12B4    FF15 2482A800   call    dword ptr [A88224]                  //encrypt
  00EA12BA    894424 0C       mov     dword ptr [esp+C], eax         
  00EA12BE    8BCE            mov     ecx, esi
  00EA12C0    3909            cmp     dword ptr [ecx], ecx
  00EA12C2    E8 A16FBEFF     call    00A88268
  00EA12C7    8BD7            mov     edx, edi                         
  00EA12C9    8BCD            mov     ecx, ebp                         
  00EA12CB    FF15 2882A800   call    dword ptr [A88228]                   //decrypt
  00EA12D1    8BE8            mov     ebp, eax                       
  00EA12D3    8BCE            mov     ecx, esi
  00EA12D5    3909            cmp     dword ptr [ecx], ecx
  00EA12D7    E8 8C6FBEFF     call    00A88268
  00EA12DC    8BD7            mov     edx, edi                       
  00EA12DE    8B4C24 0C       mov     ecx, dword ptr [esp+C]           
  00EA12E2    FF15 2882A800   call    dword ptr [A88228]                   //decrypt
  00EA12E8    8BF8            mov     edi, eax                        
  00EA12EA    8BCE            mov     ecx, esi
  00EA12EC    3909            cmp     dword ptr [ecx], ecx
  00EA12EE    E8 756FBEFF     call    00A88268
  00EA12F3    6A 00           push    0
  00EA12F5    8BD5            mov     edx, ebp
  00EA12F7    8B4C24 0C       mov     ecx, dword ptr [esp+C]
  00EA12FB    E8 D0375C5D     call    Microsof.5E464AD0                   //StirngCompare
  00EA1300    85C0            test    eax, eax
  00EA1302    75 11           jnz     short 00EA1315
  00EA1304    6A 00           push    0
  00EA1306    8BD7            mov     edx, edi
  00EA1308    8B4C24 08       mov     ecx, dword ptr [esp+8]
  00EA130C    E8 BF375C5D     call    Microsof.5E464AD0                   //StirngCompare
  00EA1311    85C0            test    eax, eax
  00EA1313    74 04           je      short 00EA1319
  00EA1315    33F6            xor     esi, esi
  00EA1317    EB 05           jmp     short 00EA131E
  00EA1319    BE 01000000     mov     esi, 1
  00EA131E    893424          mov     dword ptr [esp], esi
  00EA1321    6A 00           push    0
  00EA1323    8BD5            mov     edx, ebp
  00EA1325    8BCB            mov     ecx, ebx
  00EA1327    E8 A4375C5D     call    Microsof.5E464AD0                  //StirngCompare
  00EA132C    85C0            test    eax, eax
  00EA132E    75 14           jnz     short 00EA1344
  00EA1330    893424          mov     dword ptr [esp], esi
  00EA1333    6A 00           push    0
  00EA1335    8BD7            mov     edx, edi
  00EA1337    8B4C24 18       mov     ecx, dword ptr [esp+18]
  00EA133B    E8 90375C5D     call    Microsof.5E464AD0                  //StirngCompare
  00EA1340    85C0            test    eax, eax
  00EA1342    74 04           je      short 00EA1348
  00EA1344    33D2            xor     edx, edx
  00EA1346    EB 05           jmp     short 00EA134D
  00EA1348    BA 01000000     mov     edx, 1
  00EA134D    8B0424          mov     eax, dword ptr [esp]
  00EA1350    0BC2            or      eax, edx
  00EA1352    74 08           je      short 00EA135C
  00EA1354    8B0D 146C3C02   mov     ecx, dword ptr [23C6C14]
  00EA135A    EB 06           jmp     short 00EA1362
  00EA135C    8B0D 186C3C02   mov     ecx, dword ptr [23C6C18]
  00EA1362    6A 00           push    0
  00EA1364    33D2            xor     edx, edx
  00EA1366    E8 0D10655D     call    Microsof.5E4F2378                    //MessageBox
  
  现在得到了l0=23EB5D0DDB99AF268BC17C9A63D32AD5,l2=67F3A873D1F7CECA8C3C4C1211AE2355
  但这两个md5码都找不到对应的值或许是作者的一个陷阱吧!
  所以这个Crackme的用户名和注册码为固定的 richard(用户名)和peugeot(注册码)
  谢谢看完本文,如有错误,请不吝指教!
上一篇   下一篇