首页
社区
课程
招聘
[原创][文章标题]: 一个过关类型的FaNt0m's CrackMe #5的分析(总共有4个关卡)
发表于: 2007-12-29 14:44 5581

[原创][文章标题]: 一个过关类型的FaNt0m's CrackMe #5的分析(总共有4个关卡)

2007-12-29 14:44
5581

【文章标题】: 一个过关类型的FaNt0m's CrackMe #5的分析(总共有4个关卡)
【文章作者】: CuteSnail
【作者QQ号】: 121567771
【作者声明】: 只是感兴趣的自娱自乐,没有其他目的。失误之处还要敬请诸位大侠赐教!
-------------------------------------------------------------------------------
【详细过程】
  
  (A).先看第一关,PassWord的检查:


0040133E  |> \68 00010000       push    100                             ; /第一关 PassWord 检查
00401343  |.  68 B8334000       push    CRACKME5.004033B8               ; |EXN9-CK4-5QV345
00401348  |.  68 E8030000       push    3E8                             ; |
0040134D  |.  FF35 B8344000     push    dword ptr [4034B8]              ; |句柄
00401353  |.  E8 F4030000       call    <jmp.&USER32.GetDlgItemTextA>   ; \得到输入的PassWord
00401358  |.  68 B8334000       push    CRACKME5.004033B8               ; /EXN9-CK4-5QV345
0040135D  |.  68 A2304000       push    CRACKME5.004030A2               ; |JD39-CK4-5QV345
00401362  |.  E8 51040000       call    <jmp.&KERNEL32.lstrcmpA>        ; \两者比较,相等,eax返回0
00401367  |.  50                push    eax                             ;  压入比较结果
00401368  |.  6A 00             push    0
0040136A  |.  83F0 40           xor     eax, 40
0040136D  |.  66:83E0 10        and     ax, 10
00401371  |.  C1E8 0D           shr     eax, 0D
00401374  |.  C1E0 03           shl     eax, 3
00401377  |.  58                pop     eax
00401378  |.  83F8 00           cmp     eax, 0
0040137B  |.  75 28             jnz     short CRACKME5.004013A5
0040137D  |.  83F0 40           xor     eax, 40
00401380  |.  C1E8 0D           shr     eax, 0D
00401383  |.  66:83E0 10        and     ax, 10
00401387  |.  C1E0 03           shl     eax, 3
0040138A  |.  58                pop     eax                             ;  弹出比较结果
0040138B  |.  83F8 00           cmp     eax, 0                          ;  与0比较
0040138E  |.  74 15             je      short CRACKME5.004013A5         ;  相等,跳走,成功
00401390  |.  6A 30             push    30                              ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401392  |.  68 B2304000       push    CRACKME5.004030B2               ; |Password Check
00401397  |.  68 E9304000       push    CRACKME5.004030E9               ; |Nope, try again!
0040139C  |.  6A 00             push    0                               ; |hOwner = NULL
0040139E  |.  E8 C7030000       call    <jmp.&USER32.MessageBoxA>       ; \MessageBoxA
004013A3  |.  EB 15             jmp     short CRACKME5.004013BA
004013A5  |>  6A 40             push    40                              ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004013A7  |.  68 B2304000       push    CRACKME5.004030B2               ; |Password Check
004013AC  |.  68 C1304000       push    CRACKME5.004030C1               ; |Good job, you got the correct password!
004013B1  |.  6A 00             push    0                               ; |hOwner = NULL
004013B3  |.  E8 B2030000       call    <jmp.&USER32.MessageBoxA>       ; \MessageBoxA
004013B8  |.  EB 00             jmp     short CRACKME5.004013BA
004013BA  |>  B8 01000000       mov     eax, 1
004013BF  |.  C9                leave
004013C0  \.  C2 1000           retn    10  

  从上面可以一面了然的知道password就是: JD39-CK4-5QV345 ,输入这个password后,程序便显示正确的信息了;

  (B).再来到第二关,将程序拖入OD中,下 MessageBoxA 断点后运行,被断下后Alt+F9键返回程序领空,来到这里:
  
  
004011C8      E8 57020000       call    CRACKME5.00401424               ;  第二关 这里弹出NAG对话框,nop掉
004011CD  |.  8D05 C3134000     lea     eax, dword ptr [4013C3]
004011D3  |.  6A 00             push    0                               ; /(最初的 CPU 选择)
004011D5  |.  50                push    eax                             ; |DlgProc => CRACKME5.004013C3
004011D6  |.  FF75 08           push    dword ptr [ebp+8]               ; |hOwner
004011D9  |.  68 3C304000       push    CRACKME5.0040303C               ; |NAGDIALOG
004011DE  |.  FF35 B0314000     push    dword ptr [4031B0]              ; |hInst = 00400000
004011E4      E8 4B050000       call    <jmp.&USER32.DialogBoxParamA>   ;  第二关 这里弹出NAG窗口,nop掉
004011E9  |.  EB 2A             jmp     short CRACKME5.00401215

  将004011C8处的call    CRACKME5.00401424 和 004011E4处的call    <jmp.&USER32.DialogBoxParamA>都修改 Nop 掉,便可以了,这样就过了第二关了;
  
  (C).然后开始第三关 CD Check 检查的分析:
  
  
00401438  /$  53                push    ebx                             ;  第三关 CD Check 检查
00401439  |.  50                push    eax
0040143A  |.  6A 00             push    0                               ; /RootPathName = NULL
0040143C  |.  E8 6B030000       call    <jmp.&KERNEL32.GetDriveTypeA>   ; \GetDriveTypeA
00401441  |.  33DB              xor     ebx, ebx
00401443  |.  43                inc     ebx
00401444  |.  43                inc     ebx
00401445  |.  F6F3              div     bl
00401447  |.  3C 02             cmp     al, 2                           ;  al 与 2 比较
00401449      75 1C             jnz     short CRACKME5.00401467         ;  不相等,跳走,失败,改为je
0040144B  |.  80FC 01           cmp     ah, 1                           ;  al 与 1 比较
0040144E  |.  74 02             je      short CRACKME5.00401452         ;  相等,跳走,成功
00401450  |.  EB 15             jmp     short CRACKME5.00401467
00401452  |>  6A 40             push    40                              ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401454  |.  68 88314000       push    CRACKME5.00403188               ; |CD Check
00401459  |.  68 91314000       push    CRACKME5.00403191               ; |CDROM found!
0040145E  |.  6A 00             push    0                               ; |hOwner = NULL
00401460  |.  E8 05030000       call    <jmp.&USER32.MessageBoxA>       ; \MessageBoxA
00401465  |.  EB 15             jmp     short CRACKME5.0040147C
00401467  |>  6A 30             push    30                              ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
00401469  |.  68 88314000       push    CRACKME5.00403188               ; |CD Check
0040146E  |.  68 9E314000       push    CRACKME5.0040319E               ; |CDROM Not found!
00401473  |.  6A 00             push    0                               ; |hOwner = NULL
00401475  |.  E8 F0020000       call    <jmp.&USER32.MessageBoxA>       ; \MessageBoxA
0040147A  |.  EB 00             jmp     short CRACKME5.0040147C
0040147C  |>  58                pop     eax
0040147D  |.  5B                pop     ebx
0040147E  \.  C3                retn

  将00401449处的jnz     short CRACKME5.00401467修改为je     short CRACKME5.00401467,便可以了,这样就又把第三关也过了;
  
  (D).接着,开始第四关 Name/Serial 检查的分析了:


0040153F  |> \68 00010000       push    100                         ; /第四关 Name/Serial 检查
00401544  |.  68 B8314000       push    CRACKME5.004031B8           ; |注册名
00401549  |.  68 E8030000       push    3E8                         ; |ControlID = 3E8 (1000.)
0040154E  |.  FF35 BC344000     push    dword ptr [4034BC]          ; |hWnd = 00860236 ('Name/Serial Protection',class='#32770',parent=01260102)
00401554  |.  E8 F3010000       call    <jmp.&USER32.GetDlgItemText>; \得到注册名
00401559  |.  68 00010000       push    100                         ; /Count = 100 (256.)
0040155E  |.  68 B8324000       push    CRACKME5.004032B8           ; |注册码
00401563  |.  68 EC030000       push    3EC                         ; |ControlID = 3EC (1004.)
00401568  |.  FF35 BC344000     push    dword ptr [4034BC]          ; |hWnd = 00860236 ('Name/Serial Protection',class='#32770',parent=01260102)
0040156E  |.  E8 D9010000       call    <jmp.&USER32.GetDlgItemText>; \得到注册码
00401573  |.  68 B8314000       push    CRACKME5.004031B8           ; /注册名
00401578  |.  E8 41020000       call    <jmp.&KERNEL32.lstrlenA>    ; \得到注册名的长度
0040157D  |.  83F8 02           cmp     eax, 2                      ;  与 2 比较
00401580  |.  0F8E A1000000     jle     CRACKME5.00401627           ;  小于等于,跳走,失败
00401586  |.  68 B8324000       push    CRACKME5.004032B8           ; /注册码
0040158B  |.  E8 2E020000       call    <jmp.&KERNEL32.lstrlenA>    ; \得到注册码的长度
00401590  |.  83F8 02           cmp     eax, 2                      ;  与 2 比较
00401593  |.  0F8E 8E000000     jle     CRACKME5.00401627           ;  小于等于,跳走,失败
00401599  |.  68 B8334000       push    CRACKME5.004033B8           ; /运算结果字符串
0040159E  |.  68 B8324000       push    CRACKME5.004032B8           ; |压入注册码
004015A3  |.  E8 10020000       call    <jmp.&KERNEL32.lstrcmpA>    ; \两字符串比较
004015A8  |.  50                push    eax                         ;  结果 入栈
004015A9  |.  6A 00             push    0
004015AB  |.  83F0 40           xor     eax, 40
004015AE  |.  66:83E0 10        and     ax, 10
004015B2  |.  C1E8 0D           shr     eax, 0D
004015B5  |.  C1E0 03           shl     eax, 3
004015B8  |.  58                pop     eax
004015B9  |.  83F8 00           cmp     eax, 0
004015BC  |.  75 2A             jnz     short CRACKME5.004015E8
004015BE  |.  83F0 40           xor     eax, 40
004015C1  |.  C1E8 0D           shr     eax, 0D
004015C4  |.  66:83E0 10        and     ax, 10
004015C8  |.  C1E0 03           shl     eax, 3
004015CB  |.  58                pop     eax                         ;  结果 出栈
004015CC  |.  83F8 00           cmp     eax, 0                      ;  与 0 比较
004015CF      74 17             je      short CRACKME5.004015E8     ;  相等,成功(注册码和运算结果比较)
004015D1      75 2A             jnz     short CRACKME5.004015FD     ;  不相等,继续
004015D3  |>  6A 30             push    30                          ; /Style = MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004015D5  |.  68 FA304000       push    CRACKME5.004030FA           ; |Check Serial
004015DA  |.  68 07314000       push    CRACKME5.00403107           ; |Wrong Serial! Keep trying, you'll get it!
004015DF  |.  6A 00             push    0                           ; |hOwner = NULL
004015E1  |.  E8 84010000       call    <jmp.&USER32.MessageBoxA>   ; \MessageBoxA
004015E6  |.  EB 54             jmp     short CRACKME5.0040163C
004015E8  |>  6A 40             push    40                          ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004015EA  |.  68 FA304000       push    CRACKME5.004030FA           ; |Check Serial
004015EF  |.  68 31314000       push    CRACKME5.00403131           ; |You got it! Congrats! :)
004015F4  |.  6A 00             push    0                           ; |hOwner = NULL
004015F6  |.  E8 6F010000       call    <jmp.&USER32.MessageBoxA>   ; \MessageBoxA
004015FB  |.  EB 3F             jmp     short CRACKME5.0040163C
004015FD  |>  68 B8314000       push    CRACKME5.004031B8           ;  压入注册名
00401602  |.  68 B8324000       push    CRACKME5.004032B8           ;  压入注册码
00401607  |.  E8 39000000       call    CRACKME5.00401645           ;  ×关键算法1,返回下面运算需要的KEY1
0040160C  |.  83F0 40           xor     eax, 40                     ;  异或 64
0040160F  |.  66:83E0 10        and     ax, 10                      ;  与 16
00401613  |.  C1E8 0D           shr     eax, 0D                     ;  右移 12
00401616  |.  C1E0 03           shl     eax, 3                      ;  左移3
00401619  |.  6A 00             push    0
0040161B  |.  E8 7C000000       call    CRACKME5.0040169C           ;  ×关键算法2,返回eax结果,跟进分析
00401620  |.  83F8 00           cmp     eax, 0                      ;  与0比较
00401623  |.^ 74 C3             je      short CRACKME5.004015E8     ;  相等,跳向成功
00401625  |.^ EB AC             jmp     short CRACKME5.004015D3     ;  否则,跳向失败
00401627  |>  6A 10             push    10                          ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00401629  |.  68 56304000       push    CRACKME5.00403056           ; |Input Error
0040162E  |.  68 62304000       push    CRACKME5.00403062           ; |You must input minimum 3 characters\r\nand maximum 255 characters
00401633  |.  6A 00             push    0                           ; |hOwner = NULL
00401635  |.  E8 30010000       call    <jmp.&USER32.MessageBoxA>   ; \MessageBoxA
0040163A  |.  EB 00             jmp     short CRACKME5.0040163C
0040163C  |>  B8 01000000       mov     eax, 1
00401641  |.  C9                leave
00401642  \.  C2 1000           retn    10

  从上面可以看到,0040161B处的call    CRACKME5.0040169C便是关键算法call了,而它前面的00401607处的call    CRACKME5.00401645则负责为其产生一个运算需要的数据,因此先进入00401607处的call分析:

00401645  /$  55                push    ebp                         ;  产生KEY1数据
00401646  |.  8BEC              mov     ebp, esp
00401648  |.  68 B8334000       push    CRACKME5.004033B8           ;  随即字符串
0040164D  |.  68 B8324000       push    CRACKME5.004032B8           ;  输入注册码
00401652  |.  5E                pop     esi
00401653  |.  5F                pop     edi
00401654  |.  A4                movs    byte ptr es:[edi], byte ptr>;  修改随即字符串
00401655  |.  68 B8334000       push    CRACKME5.004033B8           ;  再压入
0040165A  |.  6A 00             push    0
0040165C  |.  58                pop     eax
0040165D  |.  5A                pop     edx
0040165E  |.  8802              mov     byte ptr [edx], al          ;  第一个字符清零
00401660  |.  B9 00010000       mov     ecx, 100                    ;  初始化ecx
00401665  |.  8D35 B8314000     lea     esi, dword ptr [4031B8]     ;  注册名
0040166B  |.  8D3D B8334000     lea     edi, dword ptr [4033B8]     ;  初始化edi
00401671  |>  33C0              /xor     eax, eax                   ;  初始化eax
00401673  |.  8A06              |mov     al, byte ptr [esi]         ;  依次取注册名的字符
00401675  |.  46                |inc     esi                        ;  指向注册名的下一个字符
00401676  |.  83F8 00           |cmp     eax, 0                     ;  是否取完了注册名
00401679  |.  74 19             |je      short CRACKME5.00401694    ;  如果取完,则跳走
0040167B  |.  C1E8 03           |shr     eax, 3                     ;  右移3
0040167E  |.  83F0 2C           |xor     eax, 2C                    ;  异或 44
00401681  |.  C1E0 04           |shl     eax, 4                     ;  左移4
00401684  |.  C1C8 0A           |ror     eax, 0A                    ;  循环右移10
00401687  |.  83F0 1A           |xor     eax, 1A                    ;  异或 26
0040168A  |.  83C0 40           |add     eax, 40                    ;  加上 64
0040168D  |.  C1E8 04           |shr     eax, 4                     ;  右移4
00401690  |.  8807              |mov     byte ptr [edi], al         ;  结果送变量
00401692  |.^ EB DD             \jmp     short CRACKME5.00401671
00401694  |>  47                inc     edi                         ;  指向下一字符
00401695  |.  C607 00           mov     byte ptr [edi], 0           ;  设置为空,得到其前一位的数据 KEY1
00401698  |.  C9                leave
00401699  \.  C2 0800           retn    8

  再了解了上面的预算后,便来到了主算法的call中了:

0040169C  /$  55                push    ebp                         ; 算法开始:
0040169D  |.  8BEC              mov     ebp, esp
0040169F  |.  56                push    esi
004016A0  |.  57                push    edi
004016A1  |.  52                push    edx
004016A2  |.  53                push    ebx
004016A3  |.  8D35 B8314000     lea     esi, dword ptr [4031B8]     ;  注册名
004016A9  |.  8D3D B8334000     lea     edi, dword ptr [4033B8]     ;  Key1 = 上面的运算结果数
004016AF  |.  8D15 A2304000     lea     edx, dword ptr [4030A2]     ;  Key2 = "JD39-CK4-5QV345"(固定字符串)
004016B5  |.  B9 01000000       mov     ecx, 1                      ;  初始化ecx
004016BA  |.  BB 45000000       mov     ebx, 45                     ;  初始化ebx
004016BF  |.  C1E3 08           shl     ebx, 8                      ;  左移8
004016C2  |>  B3 1A             /mov     bl, 1A                     ;  初始化bl
004016C4  |.  33C0              |xor     eax, eax                   ;  eax清零
004016C6  |.  8A06              |mov     al, byte ptr [esi]         ;  依次取注册名的ASCII码值
004016C8  |.  3C 00             |cmp     al, 0                      ;  与0比较
004016CA  |.  74 40             |je      short CRACKME5.0040170C    ;  为空,跳走
004016CC  |.  46                |inc     esi                        ;  指向注册名的下一字符
004016CD  |.  803A 00           |cmp     byte ptr [edx], 0          ;  Key是否为空
004016D0  |.  75 06             |jnz     short CRACKME5.004016D8    ;  不为空,跳走
004016D2  |.  8D15 A2304000     |lea     edx, dword ptr [4030A2]
004016D8  |>  3202              |xor     al, byte ptr [edx]         ;  异或
004016DA  |.  F6E7              |mul     bh                         ;  乘以 69
004016DC  |.  66:F7D0           |not     ax                         ;  取反
004016DF  |.  25 FF0F0000       |and     eax, 0FFF                  ;  与 4095 与运算
004016E4  |.  F6F3              |div     bl                         ;  除以 26
004016E6  |.  80C4 41           |add     ah, 41                     ;  加上 65
004016E9  |.  C1E0 10           |shl     eax, 10                    ;  左移 16
004016EC  |.  C1E8 18           |shr     eax, 18                    ;  右移 24
004016EF  |.  50                |push    eax                        ;  结果 入栈
004016F0  |.  B3 05             |mov     bl, 5                      ;  bl 等于 5
004016F2  |.  8BC1              |mov     eax, ecx
004016F4  |.  25 FF0F0000       |and     eax, 0FFF
004016F9  |.  F6F3              |div     bl                         ;  除以 05
004016FB  |.  80FC 00           |cmp     ah, 0                      ;  与0比较
004016FE  |.  75 04             |jnz     short CRACKME5.00401704    ;  不等,跳走
00401700  |.  C607 2D           |mov     byte ptr [edi], 2D
00401703  |.  47                |inc     edi
00401704  |>  58                |pop     eax
00401705  |.  8807              |mov     byte ptr [edi], al         ;  结果回写KEY1
00401707  |.  47                |inc     edi                        ;  注册名指向下一字符
00401708  |.  42                |inc     edx                        ;  KEY2 指向下一字符
00401709  |.  41                |inc     ecx                        ;  计数,增加1
0040170A  |.^ EB B6             \jmp     short CRACKME5.004016C2    ;  循环
0040170C  |>  68 B8334000       push    CRACKME5.004033B8           ; /得到真正的注册码
00401711  |.  68 B8324000       push    CRACKME5.004032B8           ; |输入的注册码
00401716  |.  E8 9D000000       call    <jmp.&KERNEL32.lstrcmpA>    ; \两者比较,相等,eax返回0
0040171B  |.  5A                pop     edx
0040171C  |.  5F                pop     edi
0040171D  |.  5E                pop     esi
0040171E  |.  C9                leave
0040171F  \.  C2 0400           retn    4

  从上面的分析知道了:运算是由注册名,注册名的运算结果(KEY1),以及固定的字符串"JD39-CK4-5QV345"(KEY2),三方共同参与运算的,以注册名的长度为循环次数,依次取注册名的ASCII码值,经过异或、乘法、取反、除法、左移、右移等操作后,与KEY2的运算结果再运算,结果送KEy1替换,然后再次往复的循环运算,便得到最终的注册码值了。而只要这个数值与输入的注册码一样,就注册成功了,比如我输入的注册名是:1234,那么经过运算后,我真正的注册码就是: EXNA 了, 哈哈 ^_^
   
  成功的注册信息:
   
  注册名: 1234
  注册码: EXNA
  
-----------------------------------------------------------------------------------
【版权声明】: 本文由 CuteSnail 原创, 转载请注明作者并保持文章的完整性, 谢谢! 再见!!


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

上传的附件:
收藏
免费 7
支持
分享
最新回复 (1)
雪    币: 721
活跃值: (350)
能力值: ( LV9,RANK:1250 )
在线值:
发帖
回帖
粉丝
2
不错,不错。分析的很详细。
2007-12-29 19:21
0
游客
登录 | 注册 方可回帖
返回
//