160个Crackme之030学习笔记

第30个CM程序,这个程序有好几个窗体,先在File菜单上选择“password”命令进入主窗体,输入“1234567890”,点击“OK”按钮,弹出错误提示框,在About菜单上点击弹出关于信息,没什么用处:


      


第一步、查壳:



无壳,这个程序是VB5.0编程:
第二步、爆破
用OD载入cracking4all.1.exe,智能搜索字符串:



在004033A5这一行双击进入CPU窗口:



向上查看至00403370处,指令是“je cracking.0040345E”,跳过了成功提示,来到失败提示处,所以将这里nop掉试一下:



修改后的文件保存为cracking4all.1.nop.exe,运行,在password窗口中输入任何字符或者不输入字符,点击“OK”按钮时,均弹出成功提示框,说明破解成功:



第三步、追码:
将00403370处的nop指令撤消修改,观察代码:
向上查看至0040334E处,指令要调用MSVBVM50.__vbaVarTstEq函数,这就是关键比较了,[eax]=[ecx]则失败,不等则成功;



继续向上看,__vbaVarTstEq函数的两个要比较的参数分别是[eax]= ss:[ebp-0x38],[ecx]= ss:[ebp-0xC8],实际参数地址应该是ss:[ebp-0x38+0x8]【ebp-0x30】与ss:[ebp-0xC8+0x8]【ebp-0xC0】,从堆栈窗口中看到,ss:[ebp-0xC0]= “qBQSYdXUe_B\V”,也就是说输入的password经计算后等于“qBQSYdXUe_B\V”才行:
再向上查看,有点吃力了,还是用SmatrCheck/VB Decompiler这两个VB的专用反编译工具及监控工具SoftSnoop来配合OD使用吧:
先将VB Decompiler的解析导入OD中(VB Decompiler直接生成的map文件导入OD中没发现注释有什么改变,可能有什么地方不对;要先用VB Decompiler生成bas文件,再利用bas转map工具转换成map文件后导入OD才行),从SmatrCheck/VB Decompiler/SoftSnoop这三个工具中均可以看到“OK”按钮事件开始于004030F0处:OD中在此地址下断,然后F9运行程序,在File菜单上选择“password”命令进入主窗体,输入“1234567890”,点击“OK”按钮,程序中断于004030F0处:



F8向下,一直到004031A8处,得到password字符串存入[eax]中;
从004031D3至004031DA处,得到假码的长度,并存入ss:[ebp-0x108]中,作为下一步循环的次数:
[Asm] 纯文本查看 复制代码

004031D3   .  51                 push ecx                                              ; /var18 =0012F4B8
004031D4   .  52                 push edx                                              ; |retBuffer8 =0012F488
004031D5   .  BE 01000000        mov esi,0x1                                           ; |
004031DA > .  FF15 18614000      call dword ptr ds:[<&MSVBVM50.__vbaLenVar>]           ; \var_58=Len(var_28)=Len(password.text)
004031E0   .  50                 push eax                                              ;  [eax+8]=len(password.text)
004031E1   .  FF15 74614000      call dword ptr ds:[<&MSVBVM50.__vbaI2Var>]            ; msvbvm50.__vbaI2Var
004031E7 > .  8985 F8FEFFFF      mov dword ptr ss:[ebp-0x108],eax                      ;  var_108=CInt(Me)
004031ED   .  8BFE               mov edi,esi

从004031EF到0040332A是一个大循环。循环次数是假码的长度值:[其中004031FC、00403206、00403312、00403319等处由导入的注释有点小问题,不知道该怎么说好,前面两个是将标志位ZF用00000001h来表示了,后面两个地址处是将di、si用00000001h来表示,感觉不太合适,需要自己根据情况修改调整一下。]
[Asm] 纯文本查看 复制代码

004031EF   >  66:3BBD F8FEFFFF   cmp di,word ptr ss:[ebp-0x108]                        ;  di与10比较:从1到len(password.text)循环
004031F6   .  8B1D 6C614000      mov ebx,dword ptr ds:[<&MSVBVM50.__vbaStrVarVal>]     ; msvbvm50.__vbaStrVarVal
004031FC > .  0F8F 2D010000      jg <cracking.End`If>                                  ; If`00000001h<=0`Then////if di-10<=0时转移
00403202   .  66:83FE 04         cmp si,0x4
00403206 > .  7E 05              jle short <cracking.End`If>                           ;  If`00000001h`>`4`Then////if si-4>0时转移
00403208   .  BE 01000000        mov esi,0x1
0040320D > >  0FBFCF             movsx ecx,di                                          ;  End`If
。。。。。。。。。
00403309 > .  FF15 00614000      call dword ptr ds:[<&MSVBVM50.__vbaFreeVarList>]      ;  call`undef`'Ignore`this`'__vbaFreeVarList(00000006,`2,`var_68,`2,`2,`var_98,`var_A8)
0040330F   .  83C4 1C            add esp,0x1C
00403312 > .  66:46              inc si                                                ;  si=00000001h`+`1///si自加1 si=si+1
00403314   .  B8 01000000        mov eax,0x1
00403319 > .  66:03C7            add ax,di                                             ;  00000001h=00000001h`+`di///ax=ax+di
0040331C > .  0F80 44020000      jo cracking.00403566                                  ; If`Err.Number<>0`Then
00403322 > .  0F80 3E020000      jo cracking.00403566                                  ;If`Err.Number<>0`Then`GoTo`loc_00403566
00403328   .  8BF8               mov edi,eax
0040332A > .^ E9 C0FEFFFF        jmp cracking.004031EF                                 ; GoTo`loc_004031EF

到0040322B处,依次取假码的每一个字符,存入var_68即SS:[ebp-0x68]中;
[Asm] 纯文本查看 复制代码

00403210   .  8D45 A8            lea eax,dword ptr ss:[ebp-0x58]
00403213   .  8D55 D8            lea edx,dword ptr ss:[ebp-0x28]
00403216   .  50                 push eax                                              ; /Length8 = 0x0
00403217   .  51                 push ecx                                              ; |Start = 0x12F4B8
00403218   .  8D45 98            lea eax,dword ptr ss:[ebp-0x68]                       ; |
0040321B   .  52                 push edx                                              ; |dString8 = 0012F488
0040321C   .  50                 push eax                                              ; |RetBUFFER = NULL
0040321D   .  C745 B0 01000000   mov dword ptr ss:[ebp-0x50],0x1                       ; |
00403224   .  C745 A8 02000000   mov dword ptr ss:[ebp-0x58],0x2                       ; |
0040322B > .  FF15 38614000      call dword ptr ds:[<&MSVBVM50.#rtcMidCharVar_632>]    ; \var_68=Mid(var_28,`di,`1) /取假码的每一个字符

继续到0040325C处,将2000(0x7D0)存入ss:[ebp-0x70]中,在00403263处循环取“2000”的每一个字符,存入var_98即SS:[ebp-0x98]中;
[Asm] 纯文本查看 复制代码

00403231   .  B8 02000000        mov eax,0x2
00403236   .  8D8D 78FFFFFF      lea ecx,dword ptr ss:[ebp-0x88]
0040323C   .  0FBFD6             movsx edx,si
0040323F   .  8985 78FFFFFF      mov dword ptr ss:[ebp-0x88],eax
00403245   .  8945 88            mov dword ptr ss:[ebp-0x78],eax
00403248   .  51                 push ecx                                              ; /Length8 =0x12F4B8
00403249   .  8D45 88            lea eax,dword ptr ss:[ebp-0x78]                       ; |
0040324C   .  52                 push edx                                              ; |Start = 0x12F488
0040324D   .  8D8D 68FFFFFF      lea ecx,dword ptr ss:[ebp-0x98]                       ; |
00403253   .  50                 push eax                                              ; |dString8 =NULL
00403254   .  51                 push ecx                                              ; |RetBUFFER = 0012F4B8
00403255   .  C745 80 01000000   mov dword ptr ss:[ebp-0x80],0x1                       ; |
0040325C   .  C745 90 D0070000   mov dword ptr ss:[ebp-0x70],0x7D0                     ; |0x7D0的10进制数值为2000
00403263 > .  FF15 38614000      call dword ptr ds:[<&MSVBVM50.#rtcMidCharVar_632>]    ; \var_98=Mid(2000,`si,`1) ///循环取“2000”的每一个字符

00403269处到00403288处将取得的假码字符转换成16进制数值,转存到ss:[ebp-0x118]中;
[Asm] 纯文本查看 复制代码

00403269   .  8D55 98            lea edx,dword ptr ss:[ebp-0x68]
0040326C   .  8D45 C0            lea eax,dword ptr ss:[ebp-0x40]
0040326F   .  52                 push edx
00403270   .  50                 push eax
00403271 > .  FFD3               call ebx                                              ;  var_40=CStr(var_68)
00403273   .  50                 push eax                                              ; /String = NULL
00403274   .  FF15 0C614000      call dword ptr ds:[<&MSVBVM50.#rtcAnsiValueBstr_516>] ; \rtcAnsiValueBstr
0040327A   .  0FBFD0             movsx edx,ax
0040327D   .  8D8D 68FFFFFF      lea ecx,dword ptr ss:[ebp-0x98]
00403283   .  8D45 BC            lea eax,dword ptr ss:[ebp-0x44]
00403286   .  51                 push ecx
00403287   .  50                 push eax
00403288   .  8995 E8FEFFFF      mov dword ptr ss:[ebp-0x118],edx

0040328E处到00403291处,将每一位假码字符对应的“2000”的字符转换成16进制数值,存入[ax]中;
[Asm] 纯文本查看 复制代码

0040328E > .  FFD3               call ebx                                              ;  var_44=CStr(var_98)
00403290   .  50                 push eax                                              ; /String = NULL
00403291   .  FF15 0C614000      call dword ptr ds:[<&MSVBVM50.#rtcAnsiValueBstr_516>] ; \rtcAnsiValueBstr

00403297到004032AA处,假码与对应的“2000”的每一位字符的16进制数值进行异或运算,存入[edx],并从ASCII码转为字符,存入var_A8即SS:[ebp-0x118]中;
[Asm] 纯文本查看 复制代码

00403297   .  8B95 E8FEFFFF      mov edx,dword ptr ss:[ebp-0x118]
0040329D   .  0FBFC8             movsx ecx,ax
004032A0   .  33D1               xor edx,ecx                                           ;  异或运算:
004032A2   .  8D85 58FFFFFF      lea eax,dword ptr ss:[ebp-0xA8]
004032A8   .  52                 push edx
004032A9   .  50                 push eax
004032AA > .  FF15 64614000      call dword ptr ds:[<&MSVBVM50.#rtcVarBstrFromAnsi_608>;  var_A8=Chr(Asc(var_40)`xor`ecx) 【rtcVarBstrFromAnsi:ASCII码转为字符】

004032B0到004032 CD处,将异或运算后转换成的字符先连接起来,存入var_B8中,再复制回var_38中:
[Asm] 纯文本查看 复制代码

004032B0   .  8D4D C8            lea ecx,dword ptr ss:[ebp-0x38]
004032B3   .  8D95 58FFFFFF      lea edx,dword ptr ss:[ebp-0xA8]
004032B9   .  51                 push ecx
004032BA   .  8D85 48FFFFFF      lea eax,dword ptr ss:[ebp-0xB8]
004032C0   .  52                 push edx
004032C1   .  50                 push eax
004032C2 > .  FF15 70614000      call dword ptr ds:[<&MSVBVM50.__vbaVarCat>]           ; var_B8=var_38`&`var_A8
004032C8   .  8BD0               mov edx,eax
004032CA   .  8D4D C8            lea ecx,dword ptr ss:[ebp-0x38]
004032CD > .  FF15 F8604000      call dword ptr ds:[<&MSVBVM50.__vbaVarMove>]          ;  var_38=var_B8

0040332F到0040334E处,将var_38中的字符与“qBQSYdXUe_B\V”进行比较,相同则成功,不同则失败。
[Asm] 纯文本查看 复制代码

0040332F <> > \8D45 C8            lea eax,dword ptr ss:[ebp-0x38]                           ;  End`If
00403332    .  8D8D 38FFFFFF      lea ecx,dword ptr ss:[ebp-0xC8]
00403338    .  50                 push eax                                                  ; /var18 =0012F428
00403339    .  51                 push ecx                                                  ; |var28 = 0012F4A8
0040333A    .  C785 40FFFFFF C827>mov dword ptr ss:[ebp-0xC0],cracking.004027C8             ; |qBQSYdXUe_B\V
00403344    .  C785 38FFFFFF 0880>mov dword ptr ss:[ebp-0xC8],0x8008                        ; |
0040334E    .  FF15 44614000      call dword ptr ds:[<&MSVBVM50.__vbaVarTstEq>]             ; \关键比较:关系运算,if [eax]=[ecx],ax=-1;else ax=0

由异或运算的性质可反推出注册算法,即取“qBQSYdXUe_B\V”与“2000200020002”的每一对应字符的ASCII值进行异或运算,所得结果连接起来即是注册码了:用VB编写的主要代码段如下:
[Visual Basic] 纯文本查看 复制代码

key = "qBQSYdXUe_B\V"
source = "2000200020002"
For i = 1 To 13
    p(i) = Asc(Mid(key, i, 1)) Xor Asc(Mid(source, i, 1))
    password = password & Chr(p(i))
Next
Text1.Text = Trim(password)

计算出的密码是“CrackTheWorld”,验证了一下,是正确的。
附件

030.zip

(134.26 KB, 下载次数: 0)

2019-7-14 08:06 上传
点击文件名下载附件

下载积分: 吾爱币 -1 CB

,含CM原程序、爆破后的程序、注册机、OD的调试文件等。百度链接是:http://pan.baidu.com/s/1skMkJY9,密码: 86pm,160个CM、我已练习过的前30个crackme程序(不含012)都在里面。

THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发
  • 管埋员

    昵称

  • 取消
    昵称