首页
社区
课程
招聘
[原创]dc0de's crackme破解分析
发表于: 2006-8-12 12:26 6226

[原创]dc0de's crackme破解分析

2006-8-12 12:26
6226

【破文标题】crackme破解分析
【破文作者】逍遥风
【破解工具】OD
【破解平台】WINXP
【软件简介】Difficulty: 2 - Needs a little brain             (or luck)
            Platform: Windows
            Language: Borland Delphi
----------------------------------------------------------------------

用OD 载入这个CRACKME
根据提示信息很容易来到以下关键代码处;

0045383E  |.  8B86 FC020000 mov     eax, [esi+2FC]
00453844  |.  E8 03F2FDFF   call    00432A4C                    ;  取注册名位数
00453849  |.  8D95 D8D8FFFF lea     edx, [ebp-2728]
0045384F  |.  8B86 00030000 mov     eax, [esi+300]
00453855  |.  E8 F2F1FDFF   call    00432A4C                    ;  取输入的注册码的位数
0045385A  |.  8B85 D8D8FFFF mov     eax, [ebp-2728]             ;  使EAX等于输入的注册码
00453860  |.  E8 B745FBFF   call    00407E1C                    ;  将注册码转换成对应的16进制
00453865  |.  8945 EC       mov     [ebp-14], eax               ;  将16进制数保存
00453868  |.  8B45 FC       mov     eax, [ebp-4]                ;  使EAX等于注册名
0045386B  |.  E8 9C08FBFF   call    0040410C                    ;  取注册名 的位数
00453870  |.  8945 F4       mov     [ebp-C], eax                ;  保存注册名的位数
00453873  |.  8D45 F8       lea     eax, [ebp-8]
00453876  |.  BA 543A4500   mov     edx, 00453A54               ;  ;;;;;;;;;;;;;**====,,=,,========*=**=*=**=*=**=*=*=* (字符串1)
0045387B  |.  E8 6406FBFF   call    00403EE4                    ;  使EDX等于固定字符串1
00453880  |.  8B45 F8       mov     eax, [ebp-8]                ;  使EAX等于字符串1
00453883  |.  E8 8408FBFF   call    0040410C                    ;  取字符串1 的位数
00453888  |.  8BF0          mov     esi, eax                    ;  使ESI=EAX等于字符串1的位数

这时可以得到一个字符串
;;;;;;;;;;;;;**====,,=,,========*=**=*=**=*=**=*=*=*
设它为字符串1

0045388A  |.  85F6          test    esi, esi
0045388C  |.  7E 1E         jle     short 004538AC
0045388E  |.  BB 01000000   mov     ebx, 1
00453893  |>  8D45 F8       /lea     eax, [ebp-8]                ;  EAX等于字符串1
00453896  |.  E8 C90AFBFF   |call    00404364
0045389B  |.  8B55 F8       |mov     edx, [ebp-8]                ;  EDX等于字符串1
0045389E  |.  0FB6541A FF   |movzx   edx, byte ptr [edx+ebx-1]   ;  取字符串1每一位的ASCII码
004538A3  |.  42            |inc     edx                         ;  每一位的ASCII码加1,结果设为A
004538A4  |.  885418 FF     |mov     [eax+ebx-1], dl             ;  保存计算结果A,并用相应的A去替换字符串1中的相应字符
004538A8  |.  43            |inc     ebx                         ;  每计算一次EBX+1
004538A9  |.  4E            |dec     esi                         ;  每计算一次ESI减1
004538AA  |.^ 75 E7         \jnz     short 00453893              ;  循环计算
004538AC  |>  837D F4 00    cmp     dword ptr [ebp-C], 0         ;  注册名位数与0比较
004538B0  |.  0F8E 25010000 jle     004539DB
004538B6  |.  837D F4 0A    cmp     dword ptr [ebp-C], 0A        ;  注册名位数与10比较
004538BA  |.  0F8D 1B010000 jge     004539DB
004538C0  |.  8B45 F8       mov     eax, [ebp-8]                 ;  使EAX等于字符串2
004538C3  |.  E8 4408FBFF   call    0040410C                     ;  取字符串2的位数
004538C8  |.  8BF0          mov     esi, eax                     ;  ESI等于字符串2的位数

经过替换后得到一个新的字符串

<<<<<<<<<<<<<++>>>>-->-->>>>>>>>+>++>+>++>+>++>+>+>+!
设为字符串2
004538CA  |.  85F6          test    esi, esi
004538CC  |.  7E 19         jle     short 004538E7
004538CE  |.  BB 01000000   mov     ebx, 1                       ;  使EBX等于1
004538D3  |.  8D85 DCD8FFFF lea     eax, [ebp-2724]
004538D9  |>  8B55 F8       /mov     edx, [ebp-8]                ;  使EDX等于字符串2
004538DC  |.  8A541A FF     |mov     dl, [edx+ebx-1]             ;  取字符串2每一位的ASCII码
004538E0  |.  8810          |mov     [eax], dl                   ;  保存每一位的ASCII码
004538E2  |.  43            |inc     ebx                         ;  每计算一次EBX加1
004538E3  |.  40            |inc     eax
004538E4  |.  4E            |dec     esi                         ;  每计算一次ESI减1
004538E5  |.^ 75 F2         \jnz     short 004538D9              ;  循环计算
004538E7  |>  8B75 F4       mov     esi, [ebp-C]                 ;  使ESI等于注册名位数
004538EA  |.  85F6          test    esi, esi
004538EC  |.  7E 21         jle     short 0045390F
004538EE  |.  BB 01000000   mov     ebx, 1                       ;  使EBX等于1
004538F3  |>  8B45 F8       /mov     eax, [ebp-8]                ;  使EAX等于字符串2
004538F6  |.  E8 1108FBFF   |call    0040410C                    ;  取字符串2的位数
004538FB  |.  03C3          |add     eax, ebx                    ;  EAX=EAX+EBX,即EAX等于字符串2的位数加计算次数n
004538FD  |.  8B55 FC       |mov     edx, [ebp-4]                ;  使EDX等于注册名
00453900  |.  8A541A FF     |mov     dl, [edx+ebx-1]             ;  取注册名每一位的ASCII码,保存在DL中
00453904  |.  889405 DCD8FF>|mov     [ebp+eax-2724], dl          ;  保存注册名每一位的ASCII码
0045390B  |.  43            |inc     ebx                         ;  每计算一次EBX加1
0045390C  |.  4E            |dec     esi                         ;  每计算一次ESI减1
0045390D  |.^ 75 E4         \jnz     short 004538F3              ;  循环计算,保存注册名每一位的ASCII码。作为表1

0045390F  |>  8B45 F8       mov     eax, [ebp-8]                 ;  使EAX等于字符串2
00453912  |.  E8 F507FBFF   call    0040410C                     ;  取字符串2的位数
00453917  |.  83C0 02       add     eax, 2                       ;  字符串2的位数加2
0045391A  |.  8945 F0       mov     [ebp-10], eax
0045391D  |.  B8 01000000   mov     eax, 1                       ;  使EAX等于1
00453922  |.  33D2          xor     edx, edx                     ;  EDX清零
00453924  |> /8A8C05 DBD8FF>/mov     cl, [ebp+eax-2725]
0045392B  |. |81E1 FF000000 |and     ecx, 0FF
00453931  |. |83F9 3C       |cmp     ecx, 3C                     ;  Switch (cases 21..5D)
00453934  |. |7F 1A         |jg      short 00453950
00453936  |. |74 2E         |je      short 00453966
00453938  |. |83E9 21       |sub     ecx, 21
0045393B  |. |0F84 8E000000 |je      004539CF
00453941  |. |83E9 0A       |sub     ecx, 0A
00453944  |. |74 25         |je      short 0045396B
00453946  |. |83E9 02       |sub     ecx, 2
00453949  |. |74 38         |je      short 00453983
0045394B  |. |E9 81000000   |jmp     004539D1
00453950  |> |83E9 3E       |sub     ecx, 3E
00453953  |. |74 0C         |je      short 00453961
00453955  |. |83E9 1D       |sub     ecx, 1D
00453958  |. |74 41         |je      short 0045399B
0045395A  |. |83E9 02       |sub     ecx, 2
0045395D  |. |74 56         |je      short 004539B5
0045395F  |. |EB 70         |jmp     short 004539D1
00453961  |> |FF45 F0       |inc     dword ptr [ebp-10]          ;  Case 3E ('>') of switch 00453931
00453964  |. |EB 6B         |jmp     short 004539D1
00453966  |> |FF4D F0       |dec     dword ptr [ebp-10]          ;  Case 3C ('<') of switch 00453931
00453969  |. |EB 66         |jmp     short 004539D1
0045396B  |> |8B4D F0       |mov     ecx, [ebp-10]               ;  Case 2B ('+') of switch 00453931
0045396E  |. |0FB68C0D DBD8>|movzx   ecx, byte ptr [ebp+ecx-2725>
00453976  |. |41            |inc     ecx                         ;  将注册名每一位的ASCII码+1
00453977  |. |8B5D F0       |mov     ebx, [ebp-10]               ;  用ASCII码+1后的值去替换注册名中相应的字符
0045397A  |. |888C1D DBD8FF>|mov     [ebp+ebx-2725], cl          ;  组成新的表,设为表2

这里过程十分麻烦

00453981  |. |EB 4E         |jmp     short 004539D1
00453983  |> |8B4D F0       |mov     ecx, [ebp-10]               ;  Case 2D ('-') of switch 00453931
00453986  |. |0FB68C0D DBD8>|movzx   ecx, byte ptr [ebp+ecx-2725>
0045398E  |. |49            |dec     ecx
0045398F  |. |8B5D F0       |mov     ebx, [ebp-10]
00453992  |. |888C1D DBD8FF>|mov     [ebp+ebx-2725], cl
00453999  |. |EB 36         |jmp     short 004539D1
0045399B  |> |8B4D F0       |mov     ecx, [ebp-10]               ;  Case 5B ('[') of switch 00453931
0045399E  |. |80BC0D DBD8FF>|cmp     byte ptr [ebp+ecx-2725], 0
004539A6  |. |75 29         |jnz     short 004539D1
004539A8  |> |40            |/inc     eax
004539A9  |. |80BC05 DBD8FF>||cmp     byte ptr [ebp+eax-2725], 5>
004539B1  |.^|75 F5         |\jnz     short 004539A8
004539B3  |. |EB 1C         |jmp     short 004539D1
004539B5  |> |8B4D F0       |mov     ecx, [ebp-10]               ;  Case 5D (']') of switch 00453931
004539B8  |. |80BC0D DBD8FF>|cmp     byte ptr [ebp+ecx-2725], 0
004539C0  |. |74 0F         |je      short 004539D1
004539C2  |> |48            |/dec     eax
004539C3  |. |80BC05 DBD8FF>||cmp     byte ptr [ebp+eax-2725], 5>
004539CB  |.^|75 F5         |\jnz     short 004539C2
004539CD  |. |EB 02         |jmp     short 004539D1
004539CF  |> |B2 01         |mov     dl, 1                       ;  Case 21 ('!') of switch 00453931
004539D1  |> |40            |inc     eax                         ;  Default case of switch 00453931
004539D2  |. |80FA 01       |cmp     dl, 1
004539D5  |.^\0F85 49FFFFFF \jnz     00453924                    ;  对字符串2进行格式检验
并按照不同的情况,对注册名采取不同的变化方法.主要方法是注册名ASCII码的加1计算,但是根据不同情况,对注册名不同位上的字符计算次数不同.
详细过程不多分析

生成了第2张表,设为表2
它是有注册名每一位的ASCII码加按条件加1得来的来得
例如:注册名lovetc,那么:
     表1就是lovetc
     表2就是mqwivd               

终于来到了算法的核心部分
004539DB  |> \BB 01000000   mov     ebx, 1                       ;  使EBX等于1
004539E0  |>  8B45 F8       /mov     eax, [ebp-8]                ;  使EAX等于字符串2
004539E3  |.  E8 2407FBFF   |call    0040410C                    ;  取字符串2的位数
004539E8  |.  03C3          |add     eax, ebx                    ;  字符串2的位数加计算次数n
004539EA  |.  0FB68405 DBD8>|movzx   eax, byte ptr [ebp+eax-2725>
004539F2  |.  03F8          |add     edi, eax                    ;  EDI=EDI+EAX  (EAX=字符串2位数+计算次数n)
004539F4  |.  43            |inc     ebx                         ;  每计算一次EBX加1
004539F5  |.  83FB 0A       |cmp     ebx, 0A                     ;  计算10次
004539F8  |.^ 75 E6         \jnz     short 004539E0
004539FA  |.  3B7D EC       cmp     edi, [ebp-14]                ;  EDI累加后的结果必须等于注册码的16进制
004539FD  |.  75 0C         jnz     short 00453A0B               ;  才能注册成功
004539FF  |.  B8 943A4500   mov     eax, 00453A94                ;  well done!
00453A04  |.  E8 6339FDFF   call    0042736C
00453A09  |.  EB 0A         jmp     short 00453A15
00453A0B  |>  B8 A83A4500   mov     eax, 00453AA8                ;  wrong
  

总结一些这段代码的意义
1)取字符串2的位数。。。35(16进制)。计算次数设为n (N1=1)
2)EAX=35+n  指向表中对应的数据
  例如:第一次计算35+1=36 ,指向[ebp+eax-2725]中的数据,即
  [ebp+eax-2725]=0012F64C+36-2725=12CF5D
  查看12CF5D处的内容“ D 12CF5D” 发现所指向的就是上文所提到的表1
  表1第一位是0,所以此时 EAX=0
  
  [ebp+eax-2725]=0012F64C+(位数+n)-2725        
                    |        |        |
                  定值     定值      定值
  可以看出,只有n是变化的.
  可以说明对于表中的数据,是按表中字符顺序依次取得的。即 EAX(1)=0,EAX(2)=6D。。。m
  EAX(3)=71。。。q  依次类推。。。
  
3)所以EDI中的指就是:
   定值:12F7C8+EAX(1)+EAX(2)+。。。EAX(10)=最后结果
4)这个最后结果必须要等于注册码的16进制数,方能注册成功

根据EDI最后的累加结果12FA60,可以推出
lovetc
1243744
----------------------------------------------------------------------
大概的过程就是上文所说的
但是根据注册名计算的出表2的过程比较麻烦,需要结合字符串2的情况进行分情况讨论
----------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (8)
雪    币: 47147
活跃值: (20455)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
逍遥风是一天分析一个CrackMe ;)
2006-8-12 12:46
0
雪    币: 443
活跃值: (200)
能力值: ( LV9,RANK:1140 )
在线值:
发帖
回帖
粉丝
3
最初由 kanxue 发布
逍遥风是一天分析一个CrackMe ;)


都被他搞完了!!!

我们乐得学习,呵呵!!

2006-8-12 14:26
0
雪    币: 2256
活跃值: (941)
能力值: (RANK:2210 )
在线值:
发帖
回帖
粉丝
4
呵呵!~
在开学之前抓紧时间
2006-8-12 15:56
0
雪    币: 434
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
谢谢,学习了!
2006-8-12 16:44
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
6
支持下
2006-8-12 16:52
0
雪    币: 461
活跃值: (93)
能力值: ( LV9,RANK:1170 )
在线值:
发帖
回帖
粉丝
7
支持
2006-8-12 22:33
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
新手报到来了~努力学习
2006-8-13 14:03
0
雪    币: 215
活跃值: (82)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
由于工作的原因,很久没有学习了,谢谢
继续学习!
2006-8-29 07:02
0
游客
登录 | 注册 方可回帖
返回
//