首页
社区
课程
招聘
[旧帖] [转帖]一个名为CrackMe02的CrackMe算法分析 0.00雪花
发表于: 2012-1-12 07:21 1538

[旧帖] [转帖]一个名为CrackMe02的CrackMe算法分析 0.00雪花

2012-1-12 07:21
1538
【文章标题】: 一个名为CrackMe02的CrackMe算法分析
【软件名称】: CrackMe02
【软件大小】: 20kb
【下载地址】: 附件
【使用工具】: OD,PEID
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  很明显是一个vc++的程序,直接上od吧。
  
  F9允许后发现是个控制台程序,我们在输入函数后的地方下断,就是40101e吧。
  
  
  0040101E  |.  8B8424 0C1000 MOV EAX,DWORD PTR SS:[ARG.1]
  
  00401025  |.  83C4 08       ADD ESP,8
  
  00401028  |.  83F8 01       CMP EAX,1
  
  0040102B  |.  75 20         JNE SHORT 0040104D
  
  0040102D  |.  8D4C24 00     LEA ECX,[LOCAL.1023]
  
  00401031  |.  51            PUSH ECX                                 ; /Arg1 => OFFSET LOCAL.1023
  
  00401032  |.  E8 D9000000   CALL 00401110                            ; \CrackMe02.00401110
  
  00401037  |.  83C4 04       ADD ESP,4
  复制代码
  
  关键call就是401032这个call的地方,我们跟进去
  
  
  
  00401110  /[        DISCUZ_CODE_31        ]nbsp; 83EC 0C       SUB ESP,0C                               ;

CrackMe02.00401110(guessed Arg1)
  
  00401113  |.  A1 A0A14000   MOV EAX,DWORD PTR DS:[40A1A0]            ; ASCII "ADGNWKQU"
  
  00401118  |.  8B0D A4A14000 MOV ECX,DWORD PTR DS:[40A1A4]            ; ASCII "WKQU"
  
  0040111E  |.  53            PUSH EBX
  
  0040111F  |.  55            PUSH EBP
  
  00401120  |.  8B6C24 18     MOV EBP,DWORD PTR SS:[ARG.1]
  
  00401124  |.  56            PUSH ESI
  
  00401125  |.  57            PUSH EDI                                 ; //Arg2 => ARG.EDI
  
  00401126  |.  894424 10     MOV DWORD PTR SS:[LOCAL.2],EAX           ; ||
  
  0040112A  |.  894C24 14     MOV DWORD PTR SS:[LOCAL.1],ECX           ; ||
  
  0040112E  |.  8BFD          MOV EDI,EBP                              ; ||
  
  00401130  |.  83C9 FF       OR ECX,FFFFFFFF                          ; ||
  
  00401133  |.  33C0          XOR EAX,EAX                              ; ||
  
  00401135  |.  F2:AE         REPNE SCAS BYTE PTR ES:[EDI]             ; ||
  
  00401137  |.  8A15 A8A14000 MOV DL,BYTE PTR DS:[40A1A8]              ; ||
  
  0040113D  |.  F7D1          NOT ECX                                  ; ||
  
  0040113F  |.  49            DEC ECX                                  ; ||
  
  00401140  |.  885424 18     MOV BYTE PTR SS:[LOCAL.0],DL             ; ||
  
  00401144  |.  83F9 08       CMP ECX,8                                ; ||
  
  00401147  |.  75 62         JNE SHORT 004011AB                       ; ||
  复制代码
  
  
  
  以后的汇编实现的功能就是将关键比较的字符串ADGNWKQU压入,然后在401144处进行判断你输入的

长度是否为8,如果不是8则直接跳入失败的地方,所以这里说明输入的注册码的长度为8。
  
  
  00401161  |> /8D741C 10     /LEA ESI,[EBX+ESP+10]                    ; ||
  
  00401165  |. |B9 1A000000   |MOV ECX,1A                              ; ||
  
  0040116A  |. |0FBE042E      |MOVSX EAX,BYTE PTR DS:[EBP+ESI]         ; ||
  
  0040116E  |. |83E8 2F       |SUB EAX,2F                              ; ||
  
  00401171  |. |99            |CDQ                                     ; ||
  
  00401172  |. |F7F9          |IDIV ECX                                ; ||
  
  00401174  |. |52            |PUSH EDX                                ; ||/Arg1
  
  00401175  |. |E8 E6010000   |CALL 00401360                           ; ||\CrackMe02.00401360
  
  0040117A  |. |8A0E          |MOV CL,BYTE PTR DS:[ESI]                ; ||
  
  0040117C  |. |83C4 04       |ADD ESP,4                               ; ||
  
  0040117F  |. |3AC1          |CMP AL,CL                               ; ||
  
  00401181  |. |75 28         |JNE SHORT 004011AB                      ; ||
  
  00401183  |. |8D7C24 10     |LEA EDI,[LOCAL.2]                       ; ||
  
  00401187  |. |83C9 FF       |OR ECX,FFFFFFFF                         ; ||
  
  0040118A  |. |33C0          |XOR EAX,EAX                             ; ||
  
  0040118C  |. |43            |INC EBX                                 ; ||
  
  0040118D  |. |F2:AE         |REPNE SCAS BYTE PTR ES:[EDI]            ; ||
  
  0040118F  |. |F7D1          |NOT ECX                                 ; ||
  
  00401191  |. |49            |DEC ECX                                 ; ||
  
  00401192  |. |3BD9          |CMP EBX,ECX                             ; ||
  
  00401194  |.^\7C CB         \JL SHORT 00401161                       ; ||
  复制代码
  
  
  
  这个代码就是关键的算法处,里面有个call我们跟进去如下面:
  
  
  00401360  /[        DISCUZ_CODE_33        ]nbsp; 8B4424 04     MOV EAX,DWORD PTR SS:[ARG.1]

            ; CrackMe02.00401360(guessed Arg1)
  
  00401364  |.  85C0          TEST EAX,EAX                             ; Switch (cases 0..1A, 2 exits)
  
  00401366  |.  7C 08         JL SHORT 00401370
  
  00401368  |.  83F8 1A       CMP EAX,1A
  
  0040136B  |.  7F 03         JG SHORT 00401370
  
  0040136D  |.  83C0 41       ADD EAX,41                               ; Cases 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

A, B, C, D, E, F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A of switch CrackMe02.401364
  
  00401370  \>  C3            RETN                                     ; Default case of switch

CrackMe02.401364
  复制代码
  
  
  
  这个call就是对每次计算出来的值进行加‘A’也就是0x41。
  
  
  我们再来看看上面的算法吧,就是一个循环与str=”ADGNWKQU”比较,只要有一个计算出来不等于就跳

向错误。算法是:(输入  - 0x2f)% 0x1a + 0x41 = str;
  
  于是我们用c语言实现下算法:
  
  
  #include <stdio.h>
  
  
  
  int main (void)
  
  
  
  {
  
         char str1[8] = "ADGNWKQU";
  
         char str2[8];
  
         int i = 0;
  
         printf ("\n其中一个字符串:\n")
  
         for (i = 0; i < 8; i++)
  
         {
  
                str2[i] = str1[i] - 0x41 + 0x1a + 0x2f;
  
                printf ("%c",str2[i]);   
  
         }
  
         printf ("\n");
  
         return 0;
  
  }
  复制代码
  
  
  
  因为上面有取余数的操作,所以导致注册码不唯一,我就给出一组吧ILOV_SY]
  
  我们发现有个问题呀,它的答案是right?说明有问题呀。我们再看看这个程序的提示有个VERYEASY还有

在以下汇编我们看看:
  
  
  0040101E  |.  8B8424 0C1000 MOV EAX,DWORD PTR SS:[ARG.1]
  
  00401025  |.  83C4 08       ADD ESP,8
  
  00401028  |.  83F8 01       CMP EAX,1
  
  0040102B  |.  75 20         JNE SHORT 0040104D
  
  0040102D  |.  8D4C24 00     LEA ECX,[LOCAL.1023]
  
  00401031  |.  51            PUSH ECX                                 ; /Arg1 => OFFSET LOCAL.1023
  
  00401032  |.  E8 D9000000   CALL 00401110                            ; \CrackMe02.00401110
  
  00401037  |.  83C4 04       ADD ESP,4
  
  0040103A  |.  68 30A04000   PUSH OFFSET 0040A030                     ; ASCII "pause"
  
  0040103F  |.  E8 3C030000   CALL 00401380
  
  00401044  |.  33C0          XOR EAX,EAX
  
  00401046  |.  81C4 04100000 ADD ESP,1004
  
  0040104C  |.  C3            RETN
  
  0040104D  |>  83F8 02       CMP EAX,2
  
  00401050  |.  75 18         JNE SHORT 0040106A
  复制代码
  
  
  如果这个程序不带参数运行,直接就不会跑到下面去,而下面才是真正的注册算法地方,于是我们用到

OD的带参数调试,进入程序,发现40101e跳向了下面,参数是VERYEASY哦。关键算法4011c0处。
  
  
  004011C0  /[        DISCUZ_CODE_36        ]nbsp; 83EC 3C       sub     esp, 3C
  
  004011C3  |.  8B0D F4A14000 mov     ecx, dword ptr [40A1F4]
  
  004011C9  |.  53            push    ebx
  
  004011CA  |.  55            push    ebp
  
  004011CB  |.  56            push    esi
  
  004011CC  |.  57            push    edi
  
  004011CD  |.  894C24 1C     mov     dword ptr [esp+1C], ecx
  
  004011D1  |.  B9 09000000   mov     ecx, 9
  
  004011D6  |.  BE C8A14000   mov     esi, 0040A1C8                    ;  ASCII

"X#duh#vr#fohyhu$#Wklv#lv#wkh#Uhdo#Nh|[        DISCUZ_CODE_6        ]quot;
  
  004011DB  |.  8D7C24 24     lea     edi, dword ptr [esp+24]
  
  004011DF  |.  A1 F0A14000   mov     eax, dword ptr [40A1F0]
  
  004011E4  |.  F3:A5         rep     movs dword ptr es:[edi], dword p>
  
  004011E6  |.  66:8B0D C4A14>mov     cx, word ptr [40A1C4]
  
  004011ED  |.  8B6C24 50     mov     ebp, dword ptr [esp+50]
  
  004011F1  |.  66:A5         movs    word ptr es:[edi], word ptr [esi>
  
  004011F3  |.  894424 18     mov     dword ptr [esp+18], eax
  
  004011F7  |.  A1 C0A14000   mov     eax, dword ptr [40A1C0]
  
  004011FC  |.  A4            movs    byte ptr es:[edi], byte ptr [esi>
  
  004011FD  |.  894424 10     mov     dword ptr [esp+10], eax
  
  00401201  |.  66:894C24 14  mov     word ptr [esp+14], cx
  
  00401206  |.  8BFD          mov     edi, ebp
  
  00401208  |.  83C9 FF       or      ecx, FFFFFFFF
  
  0040120B  |.  33C0          xor     eax, eax
  
  0040120D  |.  8A15 F8A14000 mov     dl, byte ptr [40A1F8]
  
  00401213  |.  F2:AE         repne   scas byte ptr es:[edi]
  
  00401215  |.  F7D1          not     ecx
  
  00401217  |.  885424 20     mov     byte ptr [esp+20], dl
  
  0040121B  |.  8A15 C6A14000 mov     dl, byte ptr [40A1C6]
  
  00401221  |.  49            dec     ecx
  
  00401222  |.  885424 16     mov     byte ptr [esp+16], dl
  
  00401226  |.  83F9 08       cmp     ecx, 8
  
  00401229  |.  0F85 D5000000 jnz     00401304
  复制代码
  
  
  
  
  如同上面一样,也是先进行了判断输入的字符长度,上面401229就是个关键跳,如果长度不等于8就会

跳向输入错误。
  
  
  00401289  |> /8B4C24 54     /mov     ecx, dword ptr [esp+54]
  
  0040128D  |. |8D741C 18     |lea     esi, dword ptr [esp+ebx+18]
  
  00401291  |. |0FBE042E      |movsx   eax, byte ptr [esi+ebp]
  
  00401295  |. |0FBE11        |movsx   edx, byte ptr [ecx]
  
  00401298  |. |2BC2          |sub     eax, edx
  
  0040129A  |. |B9 1A000000   |mov     ecx, 1A
  
  0040129F  |. |83C0 1A       |add     eax, 1A
  
  004012A2  |. |99            |cdq
  
  004012A3  |. |F7F9          |idiv    ecx
  
  004012A5  |. |52            |push    edx
  
  004012A6  |. |E8 B5000000   |call    00401360
  
  004012AB  |. |8A0E          |mov     cl, byte ptr [esi]
  
  004012AD  |. |83C4 04       |add     esp, 4
  
  004012B0  |. |3AC1          |cmp     al, cl
  
  004012B2  |. |75 50         |jnz     short 00401304
  
  004012B4  |. |8D7C24 18     |lea     edi, dword ptr [esp+18]
  
  004012B8  |. |83C9 FF       |or      ecx, FFFFFFFF
  
  004012BB  |. |33C0          |xor     eax, eax
  
  004012BD  |. |43            |inc     ebx
  
  004012BE  |. |F2:AE         |repne   scas byte ptr es:[edi]
  
  004012C0  |. |F7D1          |not     ecx
  
  004012C2  |. |49            |dec     ecx
  
  004012C3  |. |3BD9          |cmp     ebx, ecx
  
  004012C5  |.^\7C C2         \jl      short 00401289
  复制代码
  
  
  
  
  关键算法的地方,里面有一个call也很重要,我们跟进去,如下图:
  
  
  00401360  /[        DISCUZ_CODE_38        ]nbsp; 8B4424 04     mov     eax, dword ptr [esp+4]
  
  00401364  |.  85C0          test    eax, eax
  
  00401366  |.  7C 08         jl      short 00401370
  
  00401368  |.  83F8 1A       cmp     eax, 1A
  
  0040136B  |.  7F 03         jg      short 00401370
  
  0040136D  |.  83C0 41       add     eax, 41
  
  00401370  \>  C3            retn
  复制代码
  
  
  
  
  也就是对结果进行加1。
  
  
  我们继续来看看上面的算法,其实和第一个也差不多,先定义了一个常量字符串str[]= ”ANLJSJWJ”,然

后进行对输入的字符串str2进行操作:(str2 – 0x2f) % 0x1a + ‘A’ =str。
  
  如果有一个不等于就跳向错误。
  
  
  下面我简单的使用c写一个算注册码的吧,因为这里是用到了取余,同样结果不唯一
  
  
  #include <stdio.h>
  
  
  
  int main (void)
  
  
  
  {
  
         char str1[8] = "ANLJSJWJ";
  
         char str2[8];
  
         int i = 0;
  
         printf ("\n其中一个字符串:\n");
  
         for (i = 0; i < 8; i++)
  
         {
  
                str2[i] = str1[i] - 0x41 + 0x56;
  
                printf ("%c",str2[i]);   
  
         }
  
         printf ("\n");
  
         return 0;
  
  }
  复制代码
  
  
  
  结果是Vca_h_1_(倒数第二个是小写的L哦)。

                                                       2012年01月11日 15:18:07

[课程]Linux pwn 探索篇!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 146
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
沙发?!呵呵,学习一下。
2012-1-12 08:15
0
雪    币: 335
活跃值: (91)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
既有吾爱破解...又申明原创于看雪....不解...求解释
2012-1-12 11:38
0
雪    币: 967
活跃值: (1138)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
说实在话 只要找到算法后 f5 就直接一锅端了(这里指作者的思路)
能不能得到注册key又是另外一种失去了
2012-1-12 11:56
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
嗯  不管是在吾爱发过的   还现在在看雪论坛发 只要是自己的原创都可以支持下
2012-1-13 00:21
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
6
请大家做到真正的原创哈,文章原作者提出异议了,现在将文章部分信息删除。
2012-1-13 09:24
0
雪    币: 435
活跃值: (1207)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
7
[QUOTE=loongzyd;1037878]请大家做到真正的原创哈,文章原作者提出异议了,现在将文章部分信息删除。[/QUOTE]

这不西电比赛的那个么
http://bbs.pediy.com/showthread.php?t=141100
比赛题怎么还冒出来个原作者
2012-1-13 09:41
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
8
这道题目不是西电比赛的题目,而是成都信息工程学院的比赛题目;文章最先发表在别的论坛上,本文是直接拷贝过来的。
2012-1-13 10:08
0
雪    币: 435
活跃值: (1207)
能力值: ( LV13,RANK:388 )
在线值:
发帖
回帖
粉丝
9
原来如此,ctrl c ctrl v就不好了,我还以为是分析的同一个,那没所谓的,cm就这么多难度适中的不好找
2012-1-13 10:21
0
游客
登录 | 注册 方可回帖
返回
//