当前位置: 首页 > 逆向 > 正文

一个比较有迷惑性的CrackME的算法分析

CrackMe下载:点我下载

首先声明,这个CrackMe的具体的算法我也没有看出来,询问了下CrackME的作者,被告知程序不是完全用C++写的,程序反汇编后有很多的switch和case,并且程序的逻辑比较混乱,由于我实在不知道程序使用的算法,于是将将程序算法的反汇编代码直接翻译为c语言了,

所以对于c语言,可能也会比较的混乱

因为程序为控制台程序,所以只有通过搜索字符串的方法来来到程序开始读取用户名和密码的地方,将会来到如下的代码处:

004011B0   $  81EC 000C0000 sub     esp, 0C00
004011B6   .  53            push    ebx
004011B7   .  56            push    esi
004011B8   .  57            push    edi
004011B9   .  BB 06000000   mov     ebx, 6
004011BE   >  B9 00010000   mov     ecx, 100
004011C3   .  33C0          xor     eax, eax
004011C5   .  8DBC24 0C0800>lea     edi, dword ptr [esp+80C]
004011CC   .  68 14314100   push    00413114                         ;  input name:
004011D1   .  F3:AB         rep     stos dword ptr es:[edi]
004011D3   .  68 E86C4100   push    00416CE8
004011D8   .  E8 D3040000   call    004016B0
004011DD   .  8D8424 140400>lea     eax, dword ptr [esp+414]
004011E4   .  50            push    eax
004011E5   .  68 786D4100   push    00416D78
004011EA   .  E8 51070000   call    00401940
004011EF   .  8DBC24 1C0400>lea     edi, dword ptr [esp+41C]
004011F6   .  83C9 FF       or      ecx, FFFFFFFF
004011F9   .  33C0          xor     eax, eax
004011FB   .  83C4 10       add     esp, 10
004011FE   .  F2:AE         repne   scas byte ptr es:[edi]
00401200   .  F7D1          not     ecx
00401202   .  49            dec     ecx
00401203   .  3BCB          cmp     ecx, ebx
00401205   .  73 71         jnb     short 00401278
00401207   .  68 00314100   push    00413100                         ;  size(name) >= 6!!!
0040120C   .  68 E86C4100   push    00416CE8
00401211   .  E8 9A040000   call    004016B0
00401216   .  83C4 08       add     esp, 8
00401219   .  8BF0          mov     esi, eax
0040121B   .  8BCE          mov     ecx, esi
0040121D   .  6A 0A         push    0A
0040121F   .  E8 2C020000   call    00401450
00401224   .  8B0E          mov     ecx, dword ptr [esi]
00401226   .  33FF          xor     edi, edi
00401228   .  8B51 04       mov     edx, dword ptr [ecx+4]
0040122B   .  8A4C32 04     mov     cl, byte ptr [edx+esi+4]
0040122F   .  84CB          test    bl, cl
00401231   .  8D0432        lea     eax, dword ptr [edx+esi]
00401234   .  75 14         jnz     short 0040124A
00401236   .  8B40 28       mov     eax, dword ptr [eax+28]
00401239   .  8BC8          mov     ecx, eax
0040123B   .  8B10          mov     edx, dword ptr [eax]
0040123D   .  FF52 2C       call    dword ptr [edx+2C]
00401240   .  83F8 FF       cmp     eax, -1
00401243   .  75 05         jnz     short 0040124A
00401245   .  BF 04000000   mov     edi, 4
0040124A   >  8B06          mov     eax, dword ptr [esi]
0040124C   .  8B48 04       mov     ecx, dword ptr [eax+4]
0040124F   .  03CE          add     ecx, esi
00401251   .  85FF          test    edi, edi
00401253   .^ 0F84 65FFFFFF je      004011BE
00401259   .  8B41 04       mov     eax, dword ptr [ecx+4]
0040125C   .  8B51 28       mov     edx, dword ptr [ecx+28]
0040125F   .  0BC7          or      eax, edi
00401261   .  85D2          test    edx, edx
00401263   .  0F85 9E000000 jnz     00401307
00401269   .  0C 04         or      al, 4
0040126B   .  6A 00         push    0
0040126D   .  50            push    eax
0040126E   .  E8 AD100000   call    00402320
00401273   .^ E9 46FFFFFF   jmp     004011BE
00401278   >  68 F0304100   push    004130F0                         ;  input serial:
0040127D   .  68 E86C4100   push    00416CE8
00401282   .  E8 29040000   call    004016B0
00401287   .  8D4C24 14     lea     ecx, dword ptr [esp+14]
0040128B   .  51            push    ecx
0040128C   .  68 786D4100   push    00416D78
00401291   .  E8 AA060000   call    00401940
00401296   .  8D7C24 1C     lea     edi, dword ptr [esp+1C]
0040129A   .  83C9 FF       or      ecx, FFFFFFFF
0040129D   .  33C0          xor     eax, eax
0040129F   .  83C4 10       add     esp, 10
004012A2   .  F2:AE         repne   scas byte ptr es:[edi]
004012A4   .  F7D1          not     ecx
004012A6   .  49            dec     ecx
004012A7   .  3BCB          cmp     ecx, ebx
004012A9   .  73 69         jnb     short 00401314
004012AB   .  68 D8304100   push    004130D8                         ;  size(serial) >= 6!!!
004012B0   .  68 E86C4100   push    00416CE8
004012B5   .  E8 F6030000   call    004016B0
004012BA   .  83C4 08       add     esp, 8
004012BD   .  8BF0          mov     esi, eax
004012BF   .  8BCE          mov     ecx, esi
004012C1   .  6A 0A         push    0A
004012C3   .  E8 88010000   call    00401450
004012C8   .  8B16          mov     edx, dword ptr [esi]
004012CA   .  33FF          xor     edi, edi
004012CC   .  8B42 04       mov     eax, dword ptr [edx+4]
004012CF   .  03C6          add     eax, esi
004012D1   .  8458 04       test    byte ptr [eax+4], bl
004012D4   .  75 14         jnz     short 004012EA
004012D6   .  8B40 28       mov     eax, dword ptr [eax+28]
004012D9   .  8BC8          mov     ecx, eax
004012DB   .  8B10          mov     edx, dword ptr [eax]
004012DD   .  FF52 2C       call    dword ptr [edx+2C]
004012E0   .  83F8 FF       cmp     eax, -1
004012E3   .  75 05         jnz     short 004012EA
004012E5   .  BF 04000000   mov     edi, 4
004012EA   >  8B06          mov     eax, dword ptr [esi]
004012EC   .  8B48 04       mov     ecx, dword ptr [eax+4]
004012EF   .  03CE          add     ecx, esi
004012F1   .  85FF          test    edi, edi
004012F3   .^ 0F84 C5FEFFFF je      004011BE
004012F9   .  8B41 04       mov     eax, dword ptr [ecx+4]
004012FC   .  8B51 28       mov     edx, dword ptr [ecx+28]
004012FF   .  0BC7          or      eax, edi
00401301   .  85D2          test    edx, edx
00401303   .  75 02         jnz     short 00401307
00401305   .  0C 04         or      al, 4
00401307   >  6A 00         push    0
00401309   .  50            push    eax
0040130A   .  E8 11100000   call    00402320
0040130F   .^ E9 AAFEFFFF   jmp     004011BE
00401314   >  8D8C24 0C0800>lea     ecx, dword ptr [esp+80C]
0040131B   .  8D9424 0C0400>lea     edx, dword ptr [esp+40C]
00401322   .  51            push    ecx
00401323   .  52            push    edx
00401324   .  E8 37FEFFFF   call    00401160
00401329   .  83C4 08       add     esp, 8
0040132C   .  8D7424 0C     lea     esi, dword ptr [esp+C]
00401330   .  8D8424 0C0800>lea     eax, dword ptr [esp+80C]
00401337   >  8A10          mov     dl, byte ptr [eax]
00401339   .  8ACA          mov     cl, dl
0040133B   .  3A16          cmp     dl, byte ptr [esi]
0040133D   .  75 1C         jnz     short 0040135B
0040133F   .  84C9          test    cl, cl
00401341   .  74 14         je      short 00401357
00401343   .  8A50 01       mov     dl, byte ptr [eax+1]
00401346   .  8ACA          mov     cl, dl
00401348   .  3A56 01       cmp     dl, byte ptr [esi+1]
0040134B   .  75 0E         jnz     short 0040135B
0040134D   .  83C0 02       add     eax, 2
00401350   .  83C6 02       add     esi, 2
00401353   .  84C9          test    cl, cl
00401355   .^ 75 E0         jnz     short 00401337
00401357   >  33C0          xor     eax, eax
00401359   .  EB 05         jmp     short 00401360
0040135B   >  1BC0          sbb     eax, eax
0040135D   .  83D8 FF       sbb     eax, -1
00401360   >  85C0          test    eax, eax
00401362   .  75 71         jnz     short 004013D5
00401364   .  68 D0304100   push    004130D0                         ;  great
00401369   .  68 E86C4100   push    00416CE8
0040136E   .  E8 3D030000   call    004016B0
00401373   .  83C4 08       add     esp, 8
00401376   .  8BF0          mov     esi, eax
00401378   .  8BCE          mov     ecx, esi
0040137A   .  6A 0A         push    0A
0040137C   .  E8 CF000000   call    00401450
00401381   .  8B06          mov     eax, dword ptr [esi]
00401383   .  33FF          xor     edi, edi
00401385   .  8B48 04       mov     ecx, dword ptr [eax+4]
00401388   .  8D0431        lea     eax, dword ptr [ecx+esi]
0040138B   .  8A4C31 04     mov     cl, byte ptr [ecx+esi+4]
0040138F   .  84CB          test    bl, cl
00401391   .  75 14         jnz     short 004013A7
00401393   .  8B40 28       mov     eax, dword ptr [eax+28]
00401396   .  8BC8          mov     ecx, eax
00401398   .  8B10          mov     edx, dword ptr [eax]
0040139A   .  FF52 2C       call    dword ptr [edx+2C]
0040139D   .  83F8 FF       cmp     eax, -1
004013A0   .  75 05         jnz     short 004013A7
004013A2   .  BF 04000000   mov     edi, 4
004013A7   >  8B06          mov     eax, dword ptr [esi]
004013A9   .  8B48 04       mov     ecx, dword ptr [eax+4]
004013AC   .  03CE          add     ecx, esi
004013AE   .  85FF          test    edi, edi
004013B0   .^ 0F84 08FEFFFF je      004011BE
004013B6   .  8B41 04       mov     eax, dword ptr [ecx+4]
004013B9   .  8B51 28       mov     edx, dword ptr [ecx+28]
004013BC   .  0BC7          or      eax, edi
004013BE   .  85D2          test    edx, edx
004013C0   .^ 0F85 41FFFFFF jnz     00401307
004013C6   .  0C 04         or      al, 4
004013C8   .  6A 00         push    0
004013CA   .  50            push    eax
004013CB   .  E8 500F0000   call    00402320
004013D0   .^ E9 E9FDFFFF   jmp     004011BE
004013D5   >  68 C8304100   push    004130C8                         ;  wrong
004013DA   .  68 E86C4100   push    00416CE8
004013DF   .  E8 CC020000   call    004016B0
004013E4   .  83C4 08       add     esp, 8
004013E7   .  8BF0          mov     esi, eax
004013E9   .  8BCE          mov     ecx, esi
004013EB   .  6A 0A         push    0A
004013ED   .  E8 5E000000   call    00401450
004013F2   .  8B0E          mov     ecx, dword ptr [esi]
004013F4   .  33FF          xor     edi, edi
004013F6   .  8B51 04       mov     edx, dword ptr [ecx+4]
004013F9   .  8A4C32 04     mov     cl, byte ptr [edx+esi+4]
004013FD   .  84CB          test    bl, cl
004013FF   .  8D0432        lea     eax, dword ptr [edx+esi]
00401402   .  75 14         jnz     short 00401418
00401404   .  8B40 28       mov     eax, dword ptr [eax+28]
00401407   .  8BC8          mov     ecx, eax
00401409   .  8B10          mov     edx, dword ptr [eax]
0040140B   .  FF52 2C       call    dword ptr [edx+2C]
0040140E   .  83F8 FF       cmp     eax, -1
00401411   .  75 05         jnz     short 00401418
00401413   .  BF 04000000   mov     edi, 4
00401418   >  8B06          mov     eax, dword ptr [esi]
0040141A   .  8B48 04       mov     ecx, dword ptr [eax+4]
0040141D   .  03CE          add     ecx, esi
0040141F   .  85FF          test    edi, edi
00401421   .^ 0F84 97FDFFFF je      004011BE
00401427   .  8B41 04       mov     eax, dword ptr [ecx+4]
0040142A   .  8B51 28       mov     edx, dword ptr [ecx+28]
0040142D   .  0BC7          or      eax, edi
0040142F   .  85D2          test    edx, edx
00401431   .^ 0F85 D0FEFFFF jnz     00401307
00401437   .  0C 04         or      al, 4
00401439   .  6A 00         push    0
0040143B   .  50            push    eax
0040143C   .  E8 DF0E0000   call    00402320
00401441   .^ E9 78FDFFFF   jmp     004011BE

上面基本上已经包含了程序的输入,运算和判断的代码了,所以只要对这段程序仔细分析,可以得到下面的算法分析结果:

004011CC   .  68 14314100   push Crackme3.00413114                                         ;  input name:
004011D1   .  F3:AB         rep stos dword ptr es:[edi]
004011D3   .  68 E86C4100   push Crackme3.00416CE8
004011D8   .  E8 D3040000   call Crackme3.004016B0
004011DD   .  8D8424 140400>lea eax,dword ptr ss:[esp+414]
004011E4   .  50            push eax
004011E5   .  68 786D4100   push Crackme3.00416D78
004011EA   .  E8 51070000   call Crackme3.00401940                                         ;  获取用户名
004011EF   .  8DBC24 1C0400>lea edi,dword ptr ss:[esp+41C]                                 ;  取字符串在堆栈中的地址12f784,保存到EDI中
004011F6   .  83C9 FF       or ecx,FFFFFFFF
004011F9   .  33C0          xor eax,eax
004011FB   .  83C4 10       add esp,10
004011FE   .  F2:AE         repne scas byte ptr es:[edi]
00401200   .  F7D1          not ecx
00401202   .  49            dec ecx
00401203   .  3BCB          cmp ecx,ebx                                                    ;  用户名必须大于等于6位
00401205   .  73 71         jnb short Crackme3.00401278
00401207   .  68 00314100   push Crackme3.00413100                                         ;  size(name) >= 6!!!
0040120C   .  68 E86C4100   push Crackme3.00416CE8
00401211   .  E8 9A040000   call Crackme3.004016B0
00401216   .  83C4 08       add esp,8
00401219   .  8BF0          mov esi,eax
0040121B   .  8BCE          mov ecx,esi
0040121D   .  6A 0A         push 0A
0040121F   .  E8 2C020000   call Crackme3.00401450
00401224   .  8B0E          mov ecx,dword ptr ds:[esi]
00401226   .  33FF          xor edi,edi
00401228   .  8B51 04       mov edx,dword ptr ds:[ecx+4]
0040122B   .  8A4C32 04     mov cl,byte ptr ds:[edx+esi+4]
0040122F   .  84CB          test bl,cl
00401231   .  8D0432        lea eax,dword ptr ds:[edx+esi]
00401234   .  75 14         jnz short Crackme3.0040124A
00401236   .  8B40 28       mov eax,dword ptr ds:[eax+28]
00401239   .  8BC8          mov ecx,eax
0040123B   .  8B10          mov edx,dword ptr ds:[eax]
0040123D   .  FF52 2C       call dword ptr ds:[edx+2C]
00401240   .  83F8 FF       cmp eax,-1
00401243   .  75 05         jnz short Crackme3.0040124A
00401245   .  BF 04000000   mov edi,4
0040124A   >  8B06          mov eax,dword ptr ds:[esi]
0040124C   .  8B48 04       mov ecx,dword ptr ds:[eax+4]
0040124F   .  03CE          add ecx,esi
00401251   .  85FF          test edi,edi
00401253   .^ 0F84 65FFFFFF je Crackme3.004011BE
00401259   .  8B41 04       mov eax,dword ptr ds:[ecx+4]
0040125C   .  8B51 28       mov edx,dword ptr ds:[ecx+28]
0040125F   .  0BC7          or eax,edi
00401261   .  85D2          test edx,edx
00401263   .  0F85 9E000000 jnz Crackme3.00401307
00401269   .  0C 04         or al,4
0040126B   .  6A 00         push 0
0040126D   .  50            push eax
0040126E   .  E8 AD100000   call Crackme3.00402320
00401273   .^ E9 46FFFFFF   jmp Crackme3.004011BE
00401278   >  68 F0304100   push Crackme3.004130F0                                         ;  input serial:
0040127D   .  68 E86C4100   push Crackme3.00416CE8
00401282   .  E8 29040000   call Crackme3.004016B0
00401287   .  8D4C24 14     lea ecx,dword ptr ss:[esp+14]
0040128B   .  51            push ecx
0040128C   .  68 786D4100   push Crackme3.00416D78
00401291   .  E8 AA060000   call Crackme3.00401940                                         ;  输入序列号
00401296   .  8D7C24 1C     lea edi,dword ptr ss:[esp+1C]
0040129A   .  83C9 FF       or ecx,FFFFFFFF
0040129D   .  33C0          xor eax,eax
0040129F   .  83C4 10       add esp,10
004012A2   .  F2:AE         repne scas byte ptr es:[edi]
004012A4   .  F7D1          not ecx
004012A6   .  49            dec ecx
004012A7   .  3BCB          cmp ecx,ebx                                                    ;  ECX为序列号的值
004012A9   .  73 69         jnb short Crackme3.00401314                                    ;  序列号必须大于6位
004012AB   .  68 D8304100   push Crackme3.004130D8                                         ;  size(serial) >= 6!!!

00401190  |.  5F            pop edi
00401191  |.  85C9          test ecx,ecx                                                   ;  判断用户名位数
00401193  |.  7E 15         jle short Crackme3.004011AA
00401195  |.  56            push esi
00401196  |.  8BF1          mov esi,ecx
00401198  |>  A1 146C4100   /mov eax,dword ptr ds:[416C14]                                 ;  for(int i=length;i>=0;)
0040119D  |.  50            |push eax
0040119E  |.  E8 ADFEFFFF   |call Crackme3.00401050                                        ;  关键函数
004011A3  |.  83C4 04       |add esp,4
004011A6  |.  4E            |dec esi                                                       ;  i--
004011A7  |.^ 75 EF         \jnz short Crackme3.00401198
004011A9  |.  5E            pop esi
004011AA  |>  83C4 0C       add esp,0C
004011AD  \.  C3            retn

00401050  /$  53            push ebx
00401051  |.  55            push ebp
00401052  |.  56            push esi
00401053  |.  57            push edi
00401054  |.  BD B0304100   mov ebp,Crackme3.004130B0                                      ;  ebp == 004130b0[ebp]==03
00401059  |.  BF B3304100   mov edi,Crackme3.004130B3                                      ;  EDI== 004130B3[edi]==08
0040105E  |.  BE B1304100   mov esi,Crackme3.004130B1                                      ;  ESI== 004130B1[eSi]==07
00401063  |>  0FBE45 00     /movsx eax,byte ptr ss:[ebp]                                   ;  先取第一个 从一个已经定义的整形数组中每隔6位取值 数值为 03 07 00 08 00 01 02 07 01 09 01 02 05 07 02 02 01 00 01 02 01 02 06 00
00401067  |.  48            |dec eax                                                       ;  Switch (cases 1..6)
00401068  |.  83F8 05       |cmp eax,5                                                     ;  eax-5
0040106B  |.  0F87 CC000000 |ja Crackme3.0040113D                                          ;  大于5就将eax清零
00401071  |.  FF2485 441140>|jmp dword ptr ds:[eax*4+401144]
00401078  |>  0FBE06        |movsx eax,byte ptr ds:[esi]                                   ;  case eax=0; Case 1 of switch 00401067
0040107B  |.  8B4C24 14     |mov ecx,dword ptr ss:[esp+14]                                 ;  取存放当前用户名指针的堆栈,恒定为0x12f360
0040107F  |.  83C5 02       |add ebp,2                                                     ;  ebp+2
00401082  |.  83C6 02       |add esi,2                                                     ;  esi+2
00401085  |.  8B1C81        |mov ebx,dword ptr ds:[ecx+eax*4]
00401088  |.  8D0481        |lea eax,dword ptr ds:[ecx+eax*4]
0040108B  |.  43            |inc ebx
0040108C  |.  83C7 02       |add edi,2                                                     ;  edi+2
0040108F  |.  8918          |mov dword ptr ds:[eax],ebx                                    ;  0012F360指向下一个
00401091  |.^ EB D0         |jmp short Crackme3.00401063
00401093  |>  56            |push esi                                                      ;  eax==1; Case 2 of switch 00401067
00401094  |.  E8 67FFFFFF   |call Crackme3.00401000
00401099  |.  57            |push edi
0040109A  |.  8AD8          |mov bl,al
0040109C  |.  E8 5FFFFFFF   |call Crackme3.00401000
004010A1  |.  83C4 08       |add esp,8
004010A4  |.  02D8          |add bl,al                                                     ;  两次返回的结果相加
004010A6  |>  0FBE55 05     |movsx edx,byte ptr ss:[ebp+5]                                 ;  取[ebp+5]
004010AA  |.  8B4424 14     |mov eax,dword ptr ss:[esp+14]
004010AE  |.  83C5 06       |add ebp,6                                                     ;  ebp+6
004010B1  |.  83C6 06       |add esi,6                                                     ;  esi+6
004010B4  |.  83C7 06       |add edi,6                                                     ;  edi+6
004010B7  |.  8B0C90        |mov ecx,dword ptr ds:[eax+edx*4]
004010BA  |.  8819          |mov byte ptr ds:[ecx],bl                                      ;  前面相加的结果单独保存到0012fb84
004010BC  |.^ EB A5         |jmp short Crackme3.00401063
004010BE  |>  56            |push esi                                                      ;  eax =2,再将第二个压栈004130b1; Case 3 of switch 00401067
004010BF  |.  E8 3CFFFFFF   |call Crackme3.00401000
004010C4  |.  57            |push edi                                                      ;  最后压栈第4个
004010C5  |.  8AD8          |mov bl,al
004010C7  |.  E8 34FFFFFF   |call Crackme3.00401000                                        ;  取下一位的ascii值
004010CC  |.  83C4 08       |add esp,8
004010CF  |.  32D8          |xor bl,al                                                     ;  bl = al xor bl
004010D1  |.^ EB D3         |jmp short Crackme3.004010A6
004010D3  |>  0FBE16        |movsx edx,byte ptr ds:[esi]                                   ;  Case 4 of switch 00401067
004010D6  |.  8B4424 14     |mov eax,dword ptr ss:[esp+14]
004010DA  |.  83C5 03       |add ebp,3
004010DD  |.  83C6 03       |add esi,3
004010E0  |.  83C7 03       |add edi,3
004010E3  |.  8B0C90        |mov ecx,dword ptr ds:[eax+edx*4]                              ;  ??????
004010E6  |.  8A55 FF       |mov dl,byte ptr ss:[ebp-1]
004010E9  |.  8811          |mov byte ptr ds:[ecx],dl
004010EB  |.^ E9 73FFFFFF   |jmp Crackme3.00401063
004010F0  |>  56            |push esi                                                      ;  eax = 4; Case 5 of switch 00401067
004010F1  |.  E8 0AFFFFFF   |call Crackme3.00401000
004010F6  |.  8AD8          |mov bl,al
004010F8  |.  C0F8 04       |sar al,4                                                      ;  al = al >> 4
004010FB  |.  24 0F         |and al,0F                                                     ;  al= al & 15
004010FD  |.  50            |push eax
004010FE  |.  E8 3DFFFFFF   |call Crackme3.00401040                                        ;  有是另外的一个函数
00401103  |.  0FBE0F        |movsx ecx,byte ptr ds:[edi]
00401106  |.  8B5424 1C     |mov edx,dword ptr ss:[esp+1C]
0040110A  |.  80E3 0F       |and bl,0F                                                     ;  前面运算的结果bl & 15
0040110D  |.  53            |push ebx
0040110E  |.  8B0C8A        |mov ecx,dword ptr ds:[edx+ecx*4]
00401111  |.  8801          |mov byte ptr ds:[ecx],al                                      ;  保存到一个数组中
00401113  |.  E8 28FFFFFF   |call Crackme3.00401040
00401118  |.  0FBE17        |movsx edx,byte ptr ds:[edi]
0040111B  |.  8B4C24 20     |mov ecx,dword ptr ss:[esp+20]
0040111F  |.  83C4 0C       |add esp,0C
00401122  |.  83C5 04       |add ebp,4                                                     ;  ebp+4
00401125  |.  83C6 04       |add esi,4                                                     ;  esi+4
00401128  |.  8B1491        |mov edx,dword ptr ds:[ecx+edx*4]
0040112B  |.  83C7 04       |add edi,4                                                     ;  EDI+4
0040112E  |.  8842 01       |mov byte ptr ds:[edx+1],al                                    ;  al保存到0012FB85
00401131  |.^ E9 2DFFFFFF   \jmp Crackme3.00401063
00401136  |>  5F            pop edi                                                        ;  Case 6 of switch 00401067
00401137  |.  5E            pop esi
00401138  |.  5D            pop ebp
00401139  |.  B0 01         mov al,1
0040113B  |.  5B            pop ebx
0040113C  |.  C3            retn
0040113D  |>  5F            pop edi                                                        ;  Default case of switch 00401067
0040113E  |.  5E            pop esi
0040113F  |.  5D            pop ebp
00401140  |.  32C0          xor al,al
00401142  |.  5B            pop ebx
00401143  \.  C3            retn

00401040  /$  8A4424 04     mov al,byte ptr ss:[esp+4]                                     ;  取的是参数eax的值
00401044  |.  3C 0A         cmp al,0A
00401046  |.  7D 04         jge short Crackme3.0040104C                                    ;  al>=10?
00401048  |.  83C0 30       add eax,30                                                     ;  al<10  al = al+48
0040104B  |.  C3            retn
0040104C  |>  83C0 37       add eax,37                                                     ;  al>=10 al = al+55

00401000  /$  8B4C24 04     mov ecx,dword ptr ss:[esp+4]
00401004  |.  0FBE01        movsx eax,byte ptr ds:[ecx]                                    ;  难道是依次取固定数组的指定位数
00401007  |.  83E8 07       sub eax,7                                                      ;  取出来的值减去7; Switch (cases 7..9)
0040100A  |.  74 1E         je short Crackme3.0040102A
0040100C  |.  48            dec eax
0040100D  |.  74 0A         je short Crackme3.00401019
0040100F  |.  48            dec eax
00401010  |.  74 03         je short Crackme3.00401015
00401012  |.  32C0          xor al,al                                                      ;  Default case of switch 00401007
00401014  |.  C3            retn
00401015  |>  8A41 01       mov al,byte ptr ds:[ecx+1]                                     ;  等于9,直接取下一位然后付给al; Case 9 of switch 00401007
00401018  |.  C3            retn
00401019  |>  0FBE41 01     movsx eax,byte ptr ds:[ecx+1]                                  ;  取出来的值等于8,同样取下一位; Case 8 of switch 00401007
0040101D  |.  8B0D 146C4100 mov ecx,dword ptr ds:[416C14]
00401023  |.  8B1481        mov edx,dword ptr ds:[ecx+eax*4]
00401026  |.  8A42 01       mov al,byte ptr ds:[edx+1]                                     ;  取第eax+1个放到al中
00401029  |.  C3            retn
0040102A  |>  0FBE41 01     movsx eax,byte ptr ds:[ecx+1]                                  ;  等于7就取下一位赋值给eax; Case 7 of switch 00401007
0040102E  |.  8B0D 146C4100 mov ecx,dword ptr ds:[416C14]
00401034  |.  8B1481        mov edx,dword ptr ds:[ecx+eax*4]                               ;  数组寻址?
00401037  |.  8A02          mov al,byte ptr ds:[edx]                                       ;  取前面的运算结果?
00401039  \.  C3            retn

因为程序本身从代码级别来分析相当的麻烦。我也是分析了一下午才分析出来的,一次这里只是给出我分析的注释和keygen的代码。可以结合注释和keygen的代码来综合理解.
KeyGen代码:

#include <iostream>
#include <string.h>
using namespace std;
char * c[6],*d;
char b[255];
char result[255];
int a[] = {3,7,0,8,0,1,2,7,1,9,1,2,5,7,2,2,1,0,1,2,1,2,6,0};
int fun1(int x,int y)
{
	switch(x-7){
		case 0 :{
			return *(*(c+a[y+1]));
		}
		case 1:{
			return *(*(c+a[y+1])+1);
		}
		case 2 :{
			return a[y+1];
		}
		default :{
			return 0;
		}
	}
}
int fun2(int x)
{
	if(x>=10){
		x = x+55;
	}
	else{
		x = x+48;
	}
	return x;
}
int fun(char * username){


int i=0;
int j=1;
int k=3;
	while(1){
		int tmp = a[i];
		tmp--;
		switch(tmp){
			case 0:{//
				*(c+a[j]) = *(c+a[j])+1;
				i = i+2;
				j = j+2;
				k = k+2;
				continue;
			}
			case 1 :{//
				int tmp1 = fun1(a[j],j);
				int tmp2 = fun1(a[k],k);
				tmp1 =tmp1+tmp2;
				*(*(a[i+5]+c)) =tmp1;
				i=i+6;
				j=j+6;
				k=k+6;
				continue;
			}
			case 2:{//
				int tmp1 = fun1(a[j],j);
				int tmp2 =fun1(a[k],k);
				tmp2 = tmp1 ^ tmp2;
				*(*(a[i+5]+c)) = tmp2;
				i =i+6;
				j=j+6;
				k=k+6;

				continue;
			}
			case 3:{
				*(*(c+a[k])) = a[k-1];
				i = i+3;
				j=j+3;
				k = k+3;
			}
			case 4:{//
				int tmp1 = fun1(a[j],j) ;
				int tmp2 = tmp1;
				tmp1 = tmp1 >> 4;
				tmp1 = tmp1 & 15;

				tmp2 = tmp2 & 15;
				*(*(c+a[k])) = fun2(tmp1);
				*(*(c+a[k])+1) =fun2(tmp2);
				i=i+4;
				j=j+4;
				k=k+4;
				;
				continue;
			}
			case 5 :{//
				return 1;
				break;
			}
			default : return 0;
		}
	}
}
 
int main()
{
	char username[255];
	cin>>username;
	int length = strlen(username);
	c[0]=username;
	c[5] =result;
	c[2] =c[4]=c[5];
	c[1] = b;
	
	for(int i = 0; i<length;i++){ 
		fun(username);
	}
	for(int j=0;result[j]!='\0';j++){
		cout<<result[j];
	}
	cout<<endl;
	return 0;
}

因为是将汇编语言直接翻译为c语言,所以反汇编代码看不懂的话。可以参考c语言



本文固定链接: http://kuaile.in/archives/868 | 蒲公英的博客

该日志由 蒲公英 于2012年04月21日发表在 逆向 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 一个比较有迷惑性的CrackME的算法分析 | 蒲公英的博客

一个比较有迷惑性的CrackME的算法分析:等您坐沙发呢!

发表评论


You must enable javascript to see captcha here!

快捷键:Ctrl+Enter