新CrackMe160之161 - password - crackme

与新版的124相同

汇编写的,代码直接看:

00401000 >/$  6A 00         push 0x0                                    ; /pModule = NULL
00401002  |.  E8 E3000000   call <jmp.&kernel32.GetModuleHandleA>       ; \GetModuleHandleA
00401007  |.  6A 00         push 0x0                                    ; /lParam = NULL
00401009  |.  68 22104000   push crackme.00401022                       ; |DlgProc = crackme.00401022
0040100E  |.  6A 00         push 0x0                                    ; |hOwner = NULL
00401010  |.  68 E9030000   push 0x3E9                                  ; |pTemplate = 0x3E9
00401015  |.  50            push eax                                    ; |hInst = 0019FFCC
00401016  |.  E8 B7000000   call <jmp.&user32.DialogBoxParamA>          ; \DialogBoxParamA
0040101B  |.  6A 00         push 0x0                                    ; /ExitCode = 0x0
0040101D  \.  E8 C2000000   call <jmp.&kernel32.ExitProcess>            ; \ExitProcess
00401022  /.  55            push ebp
00401023  |.  8BEC          mov ebp,esp
00401025  |.  53            push ebx
00401026  |.  56            push esi                                    ;  crackme.<ModuleEntryPoint>
00401027  |.  57            push edi                                    ;  crackme.<ModuleEntryPoint>
00401028  |.  817D 0C 11010>cmp [arg.2],0x111
0040102F  |.  75 56         jnz short crackme.00401087
00401031  |.  817D 10 EB030>cmp [arg.3],0x3EB
00401038  |.  75 4B         jnz short crackme.00401085
0040103A  |.  6A 00         push 0x0                                    ; /IsSigned = FALSE
0040103C  |.  6A 00         push 0x0                                    ; |pSuccess = NULL
0040103E  |.  68 EA030000   push 0x3EA                                  ; |ControlID = 3EA (1002.)
00401043  |.  FF75 08       push [arg.1]                                ; |hWnd = 003CC000
00401046  |.  E8 8D000000   call <jmp.&user32.GetDlgItemInt>            ; \GetDlgItemInt
0040104B  |.  50            push eax
0040104C  |.  68 BF104000   push crackme.004010BF
00401051  |.  E8 48000000   call crackme.0040109E                       ;  关键算法Call
00401056  |.  83F8 01       cmp eax,0x1
00401059  |.  74 16         je short crackme.00401071
0040105B  |.  6A 10         push 0x10                                   ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
0040105D  |.  68 00304000   push crackme.00403000                       ; |Title = "Fishing with DiLA v0.5"
00401062  |.  68 17304000   push crackme.00403017                       ; |Text = "Sorry, wrong code!"
00401067  |.  FF75 08       push [arg.1]                                ; |hOwner = 003CC000
0040106A  |.  E8 6F000000   call <jmp.&user32.MessageBoxA>              ; \MessageBoxA
0040106F  |.  EB 14         jmp short crackme.00401085
00401071  |>  6A 40         push 0x40                                   ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401073  |.  68 00304000   push crackme.00403000                       ; |Title = "Fishing with DiLA v0.5"
00401078  |.  68 2A304000   push crackme.0040302A                       ; |Text = "Success! Thank you for playing ;)"
0040107D  |.  FF75 08       push [arg.1]                                ; |hOwner = 003CC000
00401080  |.  E8 59000000   call <jmp.&user32.MessageBoxA>              ; \MessageBoxA
00401085  |>  EB 0E         jmp short crackme.00401095
00401087  |>  837D 0C 10    cmp [arg.2],0x10
0040108B  |.  75 08         jnz short crackme.00401095
0040108D  |.  FF75 08       push [arg.1]                                ; /hWnd = 003CC000
00401090  |.  E8 37000000   call <jmp.&user32.DestroyWindow>            ; \DestroyWindow
00401095  |>  33C0          xor eax,eax
00401097  |.  5F            pop edi                                     ;  kernel32.7608FCC9
00401098  |.  5E            pop esi                                     ;  kernel32.7608FCC9
00401099  |.  5B            pop ebx                                     ;  kernel32.7608FCC9
0040109A  |.  C9            leave
0040109B  \.  C2 1000       retn 0x10
0040109E  /$  83C4 10       add esp,0x10                                ;  这里是关键算法入口
004010A1  |.  83EC 0C       sub esp,0xC
004010A4  |.  66:35 AFDE    xor ax,0xDEAF                               ;  看这里
004010A8  |.  C1C0 10       rol eax,0x10                                ;  看这里
004010AB  |.  BB CFFFDA3A   mov ebx,0x3ADAFFCF                          ;  看这里
004010B0  |.  3BC3          cmp eax,ebx
004010B2  |.  75 08         jnz short crackme.004010BC
004010B4  |.  B8 01000000   mov eax,0x1
004010B9  |.  33DB          xor ebx,ebx
004010BB  |.  C3            retn
004010BC  |>  33DB          xor ebx,ebx
004010BE  \.  C3            retn
004010BF   .  58            pop eax                                     ;  kernel32.7608FCC9
004010C0   .  80C4 20       add ah,0x20
004010C3   .  F7D8          neg eax
004010C5   .  68 A1104000   push crackme.004010A1
004010CA   .  C3            retn
004010CB      CC            int3
004010CC   $- FF25 18204000 jmp dword ptr ds:[<&user32.DestroyWindow>]  ;  user32.DestroyWindow
004010D2   $- FF25 14204000 jmp dword ptr ds:[<&user32.DialogBoxParamA>>;  user32.DialogBoxParamA
004010D8   $- FF25 10204000 jmp dword ptr ds:[<&user32.GetDlgItemInt>]  ;  user32.GetDlgItemInt
004010DE   $- FF25 0C204000 jmp dword ptr ds:[<&user32.MessageBoxA>]    ;  user32.MessageBoxA
004010E4   .- FF25 04204000 jmp dword ptr ds:[<&kernel32.ExitProcess>]  ;  kernel32.ExitProcess
004010EA   $- FF25 00204000 jmp dword ptr ds:[<&kernel32.GetModuleHandl>;  kernel32.GetModuleHandleA
004010F0      00            db 00

算法就这三行:

004010A4  |.  66:35 AFDE    xor ax,0xDEAF
004010A8  |.  C1C0 10       rol eax,0x10
004010AB  |.  BB CFFFDA3A   mov ebx,0x3ADAFFCF

反过来就是:
code = ror(0x3ADAFFCF, 0x10) ^ 0xDEAF = 0xFFCF3ADA ^ 0xDEAF = 0xFFCFE475 = 4291814517
输入验证, 唉? 失败的~ 重新单步跟踪, 没错啊,走到004010B4 |. B8 01000000 mov eax,0x1 这行了,返回1不就成功了吗?
继续运行发现retn不是返回上一级, 而是又调用了一次本身,然后就失败了, 第二次调用的地址是004010BF, 就是关键Call的第一个入参(倒过来算的)

0040104B  |.  50            push eax
0040104C  |.  68 BF104000   push crackme.004010BF         ;  看这里
00401051  |.  E8 48000000   call crackme.0040109E
00401056  |.  83F8 01       cmp eax,0x1

只需要把这个值改为 00401056 这个, 让第一次调用算法方法后就返回到这里, 那就OK了,修改后,测试一下,果然是正常的
这只是尝试,并不是真正的破解作者的原程序思路,所以继续分析第二次调用
第二次调用前还执行了这个方法:

004010BF   .  58            pop eax                                     ;  kernel32.7608FCC9
004010C0   .  80C4 20       add ah,0x20
004010C3   .  F7D8          neg eax
004010C5   .  68 A1104000   push crackme.004010A1

所以第一次分析的结果还需要继续再反过来执行这个方法中的操作,即:
code = 0xFFCFE475 * -1 = 0x301B8B
code(ah) = 0x1B - 0x20 = 0xFB
code = 0x30FB8B = 3210123
输入验证完全正确, 搞定~

 
 
本节高手录制的视频,点击前往查看

 
 
 
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载

下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~
OD界面布局

posted @ 2024-12-30 14:36  hankerstudio  阅读(17)  评论(0)    收藏  举报