首页
社区
课程
招聘
[旧帖] [违规!转载没注明][分享]Crackme破解分析 0.00雪花
发表于: 2009-5-31 10:20 1578

[旧帖] [违规!转载没注明][分享]Crackme破解分析 0.00雪花

2009-5-31 10:20
1578
Crackme破解分析
,第一次见如此注册方式的CRACKME.分析一下, 
根据提示信息很容易找到关键代码。 

00401288  /$Content$nbsp; 55            push    ebp                ;  在这里下断点 
00401289  |.  8BEC          mov     ebp, esp 
0040128B  |.  81C4 FCFEFFFF add     esp, -104 
00401291  |.  C785 FCFEFFFF>mov     dword ptr [ebp-104> 
0040129B  |.  68 80000000   push    80                 ; /Count = 80 (128.) 
004012A0  |.  8D45 80       lea     eax, [ebp-80]      ; | 
004012A3  |.  50            push    eax                ; |Buffer 
004012A4  |.  68 ED030000   push    3ED                ; |ControlID = 3ED (1005.) 
004012A9  |.  FF35 0C304000 push    dword ptr [40300C] ; |hWnd = 00190644 (’b2c_2k5’,class=’DLGCLASS’) 
004012AF  |.  E8 3A010000   call    <jmp.&user32.GetDl>; \GetDlgItemTextA 
004012B4  |.  83F8 05       cmp     eax, 5             ;  注册名位数与5比较 
004012B7  |.  0F82 C7000000 jb      00401384           ;  小于5位就跳向失败 
004012BD  |.  68 80000000   push    80                 ; /Count = 80 (128.) 
004012C2  |.  8D85 00FFFFFF lea     eax, [ebp-100]     ; | 
004012C8  |.  50            push    eax                ; |Buffer 
004012C9  |.  68 EE030000   push    3EE                ; |ControlID = 3EE (1006.) 
004012CE  |.  FF35 0C304000 push    dword ptr [40300C] ; |hWnd = 00190644 (’b2c_2k5’,class=’DLGCLASS’) 
004012D4  |.  E8 15010000   call    <jmp.&user32.GetDl>; \GetDlgItemTextA 
004012D9  |.  83F8 08       cmp     eax, 8             ;  注册码位数与8比较 
004012DC  |.  0F85 A2000000 jnz     00401384           ;  注册码不等于8位就跳向失败 
从这里可以得知: 
注册名必须大于5位 
注册码必须等于8位 

004012E2  |.  8D95 00FFFFFF lea     edx, [ebp-100]     ;  使EDX等于输入的注册码 
004012E8  |.  52            push    edx 
004012E9  |.  E8 82010000   call    00401470           ;  将输入的注册码转换成对应的大写 
004012EE  |.  50            push    eax 
004012EF  |.  E8 92000000   call    00401386 
004012F4  |.  83F8 00       cmp     eax, 0             ;  输入注册码了吗? 
004012F7  |.  0F84 87000000 je      00401384           ;  没有输入注册码就跳向失败 
004012FD  |.  33D2          xor     edx, edx           ;  EDX清零,准备开始计算 
004012FF  |.  35 33644752   xor     eax, 52476433      ;  XOR (输入的注册码,0x52476433),结果设为A 
00401304  |.  35 56244752   xor     eax, 52472456      ;  XOR (A,0x52472456),结果设为B 
00401309  |.  2D 00000004   sub     eax, 4000000       ;  B减去0x4000000结果设为C 

这是对注册码的处理,先将注册码中小写的部分转换成对应的大写形式。 
设输入的注册码为;CODE 
则对注册码的处理过程为:XOR [XOR(CODE,0x52476433),0x52472456], 
作者:逍遥风 
因为XOR(0x52476433,0x52472456)=0x4065 

所以:对注册码处理的过程就相当与 XOR (CODE,0x4065)结果设为B 

C=B-0x4000000 

0040130E  |.  BB 01000000   mov     ebx, 1                ;  使EBX等于1 
00401313  |.  C1C3 10       rol     ebx, 10               ;  ROL (EBX,10) 
00401316  |.  8D75 80       lea     esi, [ebp-80]         ;  使ESI等于注册名 
00401319  |>  803E 00       /cmp     byte ptr [esi], 0 
0040131C  |.  74 0D         |je      short 0040132B 
0040131E  |.  0FB616        |movzx   edx, byte ptr [esi]  ;  取注册名每一位的ASCII码 
00401321  |.  C1C2 10       |rol     edx, 10              ;  ROL (注册名ASCII,10) 
00401324  |.  03C2          |add     eax, edx             ;  C与注册名ASCII码累加计算 
00401326  |.  2BC3          |sub     eax, ebx             ;  每一次计算的结果减去定值0x10000 
00401328  |.  46            |inc     esi                  ;  每计算一次ESI加1 
00401329  |.^ EB EE         \jmp     short 00401319       ;  循环计算 
0040132B  |>  8BD8          mov     ebx, eax              ;  使EBX等于计算结果,结果设为D 
0040132D  |.  C1CB 10       ror     ebx, 10               ;  ROR(计算结果,10) 
00401330  |.  66:81FB 90C3  cmp     bx, 0C390             ;  计算结果的低位与0x0C390相比较 
00401335  |.  75 4D         jnz     short 00401384        ;  不相等就注册失败 

第一个关键的地方。在这里程序把上一步计算结果与注册名的ASCII码累加,并减去定值。 
将最后计算结果的低位与定值0x0C390比较,如果不相等就跳向失败。 
所以现在就要根据0x0C390这个值来逆推出注册码的相关部分。 

先简化一下计算过程,理清一下思路: 
取计算结果C,以注册名lovetc为例 
程序的计算过程是 
  
C+6C0000-10000+6F0000-10000+。。。+630000-10000 

把它简化,那么就是:C+6C+6F+76+65+74+63-6=C390  
现在求C 
C+28D-6=C+287=C390 
C390-287=C=C190 
则C=C190,回归到程序中,C的形式就应该为C190****(8位)  

联系上文,看看C是怎么得来的 
XOR(A ,0x4065) = B 
B - 0x4000000 = C 
现在根据C就可以求出B了,简化后的过程就为 
B - 400 = C,所以B = C + 400 = C190 + 400 = C590 
所以B的形式就应该为:C590****(8位) 
现在推倒一下A(即CODE注册码)的情况,但是我们现在并不知道B到底等于什么。 
但是注意一下,如果要根据B来求A,就要 XOR(B ,0x4065) = A 
B具体等于什么并不清楚,但是B是一个8位数,4065只有4位,这两者XOR运算的结果只会在B的后4位发生变化。 
即: 
C509XXXX XOR 4065 = (C509)(ABCD) 
C509YYYY XOR 4065 = (C509)(EFGH)         
                       |        |------------------X,Y的值只影响这部分    
                       |-------------------不论X,Y等于什么,这部分不变 
所以就可以推出 
注册名:lovetc 
对应注册码的形式应该为:C509**** 

00401337  |.  8985 FCFEFFFF mov     [ebp-104], eax         ;  保存累加计算的结果D 
0040133D  |.  B9 04000000   mov     ecx, 4                 ;  使ECX等于4 
00401342  |.  33D2          xor     edx, edx               ;  EDX清零 
00401344  |.  33DB          xor     ebx, ebx               ;  EBX清零 
00401346  |>  83F9 00       /cmp     ecx, 0                ;  计算完了吗? 
00401349  |.  74 0A         |je      short 00401355        ;  计算完就跳走0040134B  |.  8AD8          |mov     bl, al                ;  两位两位取计算结果D 
0040134D  |.  03D3          |add     edx, ebx              ;  累加,计算结果设为E 
0040134F  |.  C1C8 08       |ror     eax, 8                ;  取下一位 
00401352  |.  49            |dec     ecx                   ;  每计算一次ECX减1 
00401353  |.^ EB F1         \jmp     short 00401346        ;  循环计算 
00401355  |>  81FA 85020000 cmp     edx, 285               ;  计算结果与0x285比较 
0040135B  |.  75 27         jnz     short 00401384         ;  不相等就注册失败  

这里,程序对上一步的计算结果D,进行累加计算。 

也就是说,我们以输入的注册码,C5091234为例,上一步将C5091234进行计算的结果为C3905251 

在这里将C3905251进行计算的过程就是 
E=C3+90+52+51 = 1F6 

但是,程序要求E必须等于285。又要开始逆推了。 

C3和90已经可以看作是定值了,C3+90=152   
  
因为:E=C3+90+XX+YY=285 所以XX+YY=285-152=132,即后两位相加的和必须为132 
现在根据这个条件可得到很多结果,任何选一组:BB + 77 = 132 

所以这时:D = C390BB77, 
那么 XOR (BB77,4065)= FB12  ,所一个可能的注册码就是:C509FB12 

重新载如,看还有什么要求,经过了重复的步骤,现在来到这里 
0040135D  |.  8D9D FCFEFFFF lea     ebx, [ebp-104] 
00401363  |.  FFD3          call    ebx                    ;  关键CALL,跟进 
00401365  |.  83FF 00       cmp     edi, 0                 ;  EDI与0比较 
00401368  |.  75 1A         jnz     short 00401384         ;  EDI不等于0就跳向失败 
到底在这里做什么呢?跟进关键CALL看看。 
0012FB9C  ^\77 BB           ja      short 0012FB59         ;  注意这里 
            |—|——————77BB?巧合?与上一步任意取得值77+BB=132有关吗? 
              
0012FB9E    90              nop 
0012FB9F    C3              retn 
为了证明这里的77BB与上一步计算所取的值77+BB=132是否有关,再选一组相加等于132的值 
CC+66=132。转换回要输入的注册码就是C5098C03。再次来到关键CALL 
这次,关键CALL的内容发生了变化 
0012FB9C    66:CC           int3 
            |—|———————————— CC+66=132 
0012FB9E    90              nop 
0012FB9F    C3              retn 
现在就可以看出,关键CALL的第一步如何去做是由我们选定的值决定的。联系关键CALL后面的代码 
00401365  |.  83FF 00       cmp     edi, 0                 ;  EDI与0比较 
00401368  |.  75 1A         jnz     short 00401384         ;  EDI不等于0就跳向失败 

可以知道,程序要求在经过关键CALL后,EDI的值必须为0。所以,关键CALL的作用就是使EDI=0 

联系赋值操作,和寄存器清零操作,想想使EDI等于0有哪些方法? 
1)mov edi,0  这样代码就是BF00 可是BF+00不等于132 
2)xor edi,edi 这样代码就是33FF,33+FF = 132 

呵呵~!看到曙光了 
即满足相加等于132,又满足可以使EDI等于0 
所以,FF33就是我们需要的值,将他转换成要输入的注册码 
(C509)[XOR(FF33,4065)] 
   |            | 
固定值         BF65  
所以注册码就是C509BF65,即 
注册名:lovetc 
注册码:C509BF65

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
lea     edx, [ebp-100]     ;  使EDX等于输入的注册码
lea     esi, [ebp-80]         ;  使ESI等于注册名
這兩個地方我不明白
2009-6-13 21:52
0
雪    币: 47147
活跃值: (20380)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
3
又是一篇将转载没注明的。不提倡通过转载来得到邀请码,实际操作上,对于转载行为,一般不会给邀请码的。
标 题: 趣味CRACKME破解分析(发散思维)
作 者: 逍遥风
时 间: 2006-08-13,16:26
链 接: http://bbs.pediy.com/showthread.php?t=30483
2009-6-13 22:01
0
游客
登录 | 注册 方可回帖
返回
//