160个Crackme之029学习笔记

第29个CM程序,和第28个界面差不多,输入name/serial=“52pojie/1234567890”,程序这次没将小写字母转换成大写形式,点击“CHECK”按钮,弹出错误提示框:



第一步、查壳:



无壳,仍是VC++6.0编程:
第二步、爆破
用OD载入CoSH.3.exe,智能搜索字符串:



在004015C5错误标题这一行双击进入CPU窗口:



在错误提示上面的004015C3处是由3个地方跳转来的,来到错误:



再向上一行的004015C1处是跳过错误,来到成功的跳,所以将直接将004015C3处命令改成jmp 004015C1让它跳到正确提示,



保存成可执行文件CoSH.3.jmp.exe,运行一下,不输入任何东西,点击“CHECK”按钮,弹出正确提示,爆破成功。



第三步、追码:
将004015 C3处的跳转指令撤消修改,观察代码,这一次要复杂得多了:
具体分析过程如下,大致分为4部分:(每一部分起止可能不很准确)
1、先判断name和serial的长度,均不能小于5位:
[Asm] 纯文本查看 复制代码

004014F5  |.  E8 AA030000   call <jmp.&MFC42.#CWnd::GetWindowTextLengthA_3876>       ;  得到name长度
004014FA  |.  8945 EC       mov [local.5],eax
004014FD  |.  837D EC 05    cmp [local.5],0x5                                        ;  name长度不小于5位,否则失败
00401501  |.  7F 05         jg short cosh_3.00401508                                 ;  下步取假码
00401503  |.  E9 BB000000   jmp cosh_3.004015C3                                      ;  失败
00401508  |>  8B4D E0       mov ecx,[local.8]
0040150B  |.  83C1 60       add ecx,0x60
0040150E  |.  E8 91030000   call <jmp.&MFC42.#CWnd::GetWindowTextLengthA_3876>       ;  [eax]=[ecx]=len(serial) 得到假码长度
00401513  |.  8945 E8       mov [local.6],eax
00401516  |.  837D E8 05    cmp [local.6],0x5                                        ;  serial长度不小于5位
0040151A  |.  7F 05         jg short cosh_3.00401521
0040151C  |.  E9 A2000000   jmp cosh_3.004015C3
00401521  |>  8B45 E0       mov eax,[local.8]

2、用i=1 to len(name)分别与name的第i位字符的ASC值异或,再转换成相对应的字符,组成一个新的字符串;
[Asm] 纯文本查看 复制代码

00401570  |.  33C0          xor eax,eax
00401572  |.  33DB          xor ebx,ebx
00401574  |.  33C9          xor ecx,ecx
00401576  |.  B9 01000000   mov ecx,0x1
0040157B  |.  33D2          xor edx,edx
0040157D  |.  8B45 E4       mov eax,[local.7]                                        ;  [eax]=name.text
00401580  |>  8A18          /mov bl,byte ptr ds:[eax]                                ;  [bl]=asc(name(i))
00401582  |.  32D9          |xor bl,cl                                               ;  [bl]=[bl] xor 1
00401584  |.  8818          |mov byte ptr ds:[eax],bl                                ;  ds:[eax]=[bl]
00401586  |.  41            |inc ecx                                                 ;  [ecx]=[ecx]+1
00401587  |.  40            |inc eax                                                 ;  [eax]=[eax]+1
00401588  |.  8038 00       |cmp byte ptr ds:[eax],0x0                               ;  cmp asc(name(i+1),0
0040158B  |.^ 75 F3         \jnz short cosh_3.00401580

3、用i=10 to len(name)+10分别与serial的第i位字符的ASC值异或,再转换成相对应的字符,组成一个新的字符串;
[Asm] 纯文本查看 复制代码

0040158D  |.  33C0          xor eax,eax
0040158F  |.  33DB          xor ebx,ebx
00401591  |.  33C9          xor ecx,ecx
00401593  |.  B9 0A000000   mov ecx,0xA                                              ;  [ecx]=0xA
00401598  |.  33D2          xor edx,edx
0040159A  |.  8B45 F0       mov eax,[local.4]                                        ;  [eax]=serial.text
0040159D  |>  8A18          /mov bl,byte ptr ds:[eax]                                ;  [bl]=asc(serial(i))
0040159F  |.  32D9          |xor bl,cl                                               ;  [bl]=[bl] xor 0xA
004015A1  |.  8818          |mov byte ptr ds:[eax],bl                                ;  ds:[eax]=[bl]
004015A3  |.  41            |inc ecx                                                 ;  [ecx]=[ecx]+1
004015A4  |.  40            |inc eax                                                 ;  [eax]=[eax]+1
004015A5  |.  8038 00       |cmp byte ptr ds:[eax],0x0
004015A8  |.^ 75 F3         \jnz short cosh_3.0040159D

4、检查第2部分和第3部分生成的两个新的字符串每一位是否相等:
[Asm] 纯文本查看 复制代码

004015AA  |.  8B45 E4       mov eax,[local.7]                                        ;  name得到的字串
004015AD  |.  8B55 F0       mov edx,[local.4]                                        ;  serial得到的字串
004015B0  |>  33C9          /xor ecx,ecx
004015B2  |.  8A18          |mov bl,byte ptr ds:[eax]
004015B4  |.  8A0A          |mov cl,byte ptr ds:[edx]
004015B6  |.  3AD9          |cmp bl,cl                                               ;  每一位进行比较,有一位不等就跳到错误
004015B8  |.  75 09         |jnz short cosh_3.004015C3
004015BA  |.  40            |inc eax
004015BB  |.  42            |inc edx
004015BC  |.  8038 00       |cmp byte ptr ds:[eax],0x0
004015BF  |.^ 75 EF         \jnz short cosh_3.004015B0
004015C1  |.  EB 16         jmp short cosh_3.004015D9
004015C3      6A 00         push 0x0
004015C5  |.  68 6C304000   push cosh_3.0040306C                                     ;  ERROR
004015CA  |.  68 40304000   push cosh_3.00403040                                     ;  One of the Details you entered was wrong

那么注册算法就很清楚了:
首先serial的长度必须和name的长度相等,且大于4;
其次asc(serial(i)) xor (i+9) = asc(name(i)) xor i。
因为xor的可逆性,所以asc(serial(i)) = asc(name(i)) xor i xor (i+9)
Serial(i)=chr(asc(name(i)) xor i xor (i+9))
最后按序连接每一个字符就得到真码了。具体代码见注册机。
附件

029.zip

(83.7 KB, 下载次数: 0)

2019-7-12 07:39 上传
点击文件名下载附件

下载积分: 吾爱币 -1 CB

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

THE END
喜欢就支持以下吧
点赞0
分享
评论 抢沙发
  • 管埋员的头像-小北的自留地

    昵称

  • 取消
    昵称