这次在破解TraceMe的时候,我有看过别人的视频。但是我并没有按照别人思路走,而是完全安全自己的思路试了一次。结果破解成功。新手学破解,如果有不对的地方,还请指出来。
004013A0 crackmes.<ModuleEntryPoint> /$ 55 push ebp ; EP入口 004013A1 |. 8BEC mov ebp, esp ;保护数据,入栈。方便程序结束后返回 004013A3 |. 6A FF push -1 004013A5 |. 68 D0404000 push 004040D0 004013AA |. 68 D41E4000 push 00401ED4 ; SE handler installation 004013AF |. 64:A1 00000000 mov eax, dword ptr fs:[0] 004013B5 |. 50 push eax 004013B6 |. 64:8925 00000000 mov dword ptr fs:[0], esp 004013BD |. 83EC 58 sub esp, 58 004013C0 |. 53 push ebx ;将参数压入桟 004013C1 |. 56 push esi ;将参数压入桟 004013C2 |. 57 push edi ;将参数压入桟 004013C3 |. 8965 E8 mov dword ptr ss:[ebp-18], esp ;将当前桟数据取出保存地址 004013C6 |. FF15 44404000 call near dword ptr ds:[<&KERNEL32.Ge>; kernel32.GetVersion ;调用 004013CC |. 33D2 xor edx, edx ;Edx清0 004013CE |. 8AD4 mov dl, ah 004013D0 |. 8915 28554000 mov dword ptr ds:[405528], edx 004013D6 |. 8BC8 mov ecx, eax 004013D8 |. 81E1 FF000000 and ecx, 0FF 004013DE |. 890D 24554000 mov dword ptr ds:[405524], ecx 004013E4 |. C1E1 08 shl ecx, 8 004013E7 |. 03CA add ecx, edx 004013E9 |. 890D 20554000 mov dword ptr ds:[405520], ecx 004013EF |. C1E8 10 shr eax, 10 004013F2 |. A3 1C554000 mov dword ptr ds:[40551C], eax 004013F7 |. 33F6 xor esi, esi ;清0 004013F9 |. 56 push esi ;将输入压桟 004013FA |. E8 A1090000 call 00401DA0 ;跟进去以后发现是heapcreate函数。创建辅助堆栈 004013FF |. 59 pop ecx ;将ECX值取出 00401400 |. 85C0 test eax, eax ;比较EAX值,这个时候值永远是成立的。 垃圾指令,跳过 00401402 |. 75 08 jnz short 0040140C ;EIP指向: 0040140C 00401404 |. 6A 1C push 1C 00401406 |. E8 B0000000 call 004014BB 0040140B |. 59 pop ecx 0040140C |> 8975 FC mov dword ptr ss:[ebp-4], esi 0040140F |. E8 E1070000 call 00401BF5 00401414 |. FF15 40404000 call near dword ptr ds:[<&KERNEL32.Ge>; [GetCommandLineA ;调用API 0040141A |. A3 185A4000 mov dword ptr ds:[405A18], eax 0040141F |. E8 9F060000 call 00401AC3 00401424 |. A3 04554000 mov dword ptr ds:[405504], eax 00401429 |. E8 48040000 call 00401876 ;CALL没一个一个跟了,直接单步补过 0040142E |. E8 8A030000 call 004017BD 00401433 |. E8 A7000000 call 004014DF ;CALL没一个一个跟了,直接单步补过 00401438 |. 8975 D0 mov dword ptr ss:[ebp-30], esi 0040143B |. 8D45 A4 lea eax, dword ptr ss:[ebp-5C] ;数据入栈,然后调用API 0040143E |. 50 push eax ; /pStartupinfo 0040143F |. FF15 3C404000 call near dword ptr ds:[<&KERNEL32.Ge>; GetStartupInfoA 00401445 |. E8 1B030000 call 00401765 0040144A |. 8945 9C mov dword ptr ss:[ebp-64], eax 0040144D |. F645 D0 01 test byte ptr ss:[ebp-30], 1 00401451 |. 74 06 je short 00401459 00401453 |. 0FB745 D4 movzx eax, word ptr ss:[ebp-2C] 00401457 |. EB 03 jmp short 0040145C 00401459 |> 6A 0A push 0A 数据入栈,然后调用API 0040145B |. 58 pop eax 0040145C |> 50 push eax 0040145D |. FF75 9C push dword ptr ss:[ebp-64] 00401460 |. 56 push esi 00401461 |. 56 push esi ; /pModule 00401462 |. FF15 38404000 call near dword ptr ds:[<&KERNEL32.Ge>; GetModuleHandleA 数据入栈,然后调用API 00401468 |. 50 push eax 00401469 |. E8 92FBFFFF call 00401000 ;当运行到 00401000 程序弹出。
7E46B05E USER32.GetDlgItemTextA 8BFF mov edi, edi ; USER32.GetDlgItemTextA API地址 7E46B060 /. 55 push ebp ;保存地址 7E46B061 |. 8BEC mov ebp, esp 7E46B063 |. FF75 0C push dword ptr ss:[ebp+C] ; /ControlID 参数入栈, ControlID 7E46B066 |. FF75 08 push dword ptr ss:[ebp+8] ; |hWnd 参数入栈,hWnd 7E46B069 |. E8 0093FBFF call GetDlgItem ; GetDlgItem 调用API,GetDlgItem。返回窗口中指定参数ID的子元素的句柄 7E46B06E |. 85C0 test eax, eax ;通过比较,判断以上是否正常, 7E46B070 |. 74 0E je short 7E46B080 ;标志位没改变。跳转没实现 继续走 7E46B072 |. FF75 14 push dword ptr ss:[ebp+14] ; /Count 参数入栈 7E46B075 |. FF75 10 push dword ptr ss:[ebp+10] ; |Buffer 参数入栈 7E46B078 |. 50 push eax ; |hWnd 参数入栈 7E46B079 |. E8 ED70FCFF call GetWindowTextA ; GetWindowTextA ;函数原形为:GetDlgItem(控件ID)->GetWindowText(eax); 7E46B07E |. EB 0E jmp short 7E46B08E ;段间短跳转。无条件跳到7E46B08E 7E46B080 |> 837D 14 00 cmp dword ptr ss:[ebp+14], 0 7E46B084 |. 74 06 je short 7E46B08C 7E46B086 |. 8B45 10 mov eax, dword ptr ss:[ebp+10] 7E46B089 |. C600 00 mov byte ptr ds:[eax], 0 7E46B08C |> 33C0 xor eax, eax 7E46B08E |> 5D pop ebp 将bp基址指针取出。 7E46B08F . C2 1000 retn 10 RETURN to crackmes.004011B6
004011B6 . 8D8C24 9C000000 lea ecx, dword ptr ss:[esp+9C] 004011BD . 6A 65 push 65 ; /Count = 65 (101.) 将参数入栈 004011BF . 51 push ecx ; |Buffer 004011C0 . 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.) 004011C5 . 56 push esi ; |hWnd 004011C6 . 8BD8 mov ebx, eax ; | 004011C8 . FFD7 call near edi ; GetDlgItemTextA 返回到 GetDlgItemTextA 地址
//又进入了7E46B05E这个地址了。 7E46B05E USER32.GetDlgItemTextA 8BFF mov edi, edi 7E46B060 /. 55 push ebp 7E46B061 |. 8BEC mov ebp, esp 7E46B063 |. FF75 0C push dword ptr ss:[ebp+C] ; /ControlID 7E46B066 |. FF75 08 push dword ptr ss:[ebp+8] ; |hWnd
7E46B069 |. E8 0093FBFF call GetDlgItem ; GetDlgItem 7E46B06E |. 85C0 test eax, eax 7E46B070 |. 74 0E je short 7E46B080 7E46B072 |. FF75 14 push dword ptr ss:[ebp+14] ; /Count 7E46B075 |. FF75 10 push dword ptr ss:[ebp+10] ; |Buffer 7E46B078 |. 50 push eax ; |hWnd 7E46B079 |. E8 ED70FCFF call GetWindowTextA ; GetWindowTextA 7E46B07E |. EB 0E jmp short 7E46B08E 7E46B080 |> 837D 1400 cmp dword ptr ss:[ebp+14], 0
7E46B084 |. 74 06 je short 7E46B08C 7E46B086 |. 8B45 10 mov eax, dword ptr ss:[ebp+10] 7E46B089 |. C600 00 mov byte ptr ds:[eax], 0 7E46B08C |> 33C0 xor eax, eax 7E46B08E |> 5D pop ebp 改变基址指针 7E46B08F . C2 1000 retn 10 ; 返回到 004011CA
004011CA . 8A4424 4C mov al, byte ptr ss:[esp+4C] 004011CE . 84C0 test al, al ;比较AL值 004011D0 . 74 76 je short 00401248 004011D2 . 83FB 05 cmp ebx, 5 ;比较偏移地址值。应该就是我们输入的admin长度的值? 004011D5 . 7C 71 jl short 00401248 ; 我们来让他进行跳转,更改标志位 004011D7 . 8D5424 4C lea edx, dword ptr ss:[esp+4C] ;桟中取数据。 004011DB . 53 push ebx ;将数据依次取出在压入桟。 004011DC . 8D8424 A0000000 lea eax, dword ptr ss:[esp+A0] 004011E3 . 52 push edx; 这儿其实就相当于: fucntion: xxxoo Cstring username = GetDlgItemTextA(idc1); Cstring password = GetDlgItemTextA(idc2); if(lstrlen(username) > 0 || lstrlen(password) > 0) { xxoo(username,password) }
004011E4 . 50 push eax 将数据依次取出在压入桟。 004011E5 . E8 56010000 call 00401340 ;这儿是个WSprintfW调用。将用户写入到了另外一个变量里 004011EA . 8B3D BC404000 mov edi, dword ptr ds:[<&USER32.GetD>; USER32.GetDlgItem ;调用API 004011F0 . 83C4 0C add esp, 0C ;将桟大小抬高。 004011F3 . 85C0 test eax, eax ;比较返回值,跳转成立,标志位改变、。 004011F5 . 74 37 je short 0040122E ;条件跳转。 该标志位,继续往下走。 004011F7 . 8D4C24 0C lea ecx, dword ptr ss:[esp+C] 004011FB . 51 push ecx ; /String2 004011FC . 68 E4544000 push 004054E4 ; |String1 = crackmes.004054E4;开辟空间 00401201 . FF15 60404000 call near dword ptr ds:[<&KERNEL32.ls>; lstrcpyA ;拷贝字符串。 00401207 . 6A 00 push 0 ; /Enable = FALSE 00401209 . 6A 6E push 6E ; |/ControlID = 6E (110.) 0040120B . 56 push esi ; ||hWnd 0040120C . FFD7 call near edi ; |GetDlgItem API参数,这儿做的应该就是将我们控件获取的字符串复制给了其他的变量了。 0040120E . 8B1D A4404000 mov ebx, dword ptr ds:[<&USER32.Enab>; |USER32.EnableWindow 00401214 . 50 push eax ; |hWnd 00401215 . FFD3 call near ebx ; EnableWindow 00401217 . 6A 00 push 0 ; /Enable = FALSE 00401219 . 68 E8030000 push 3E8 ; |/ControlID = 3E8 (1000.) 0040121E . 56 push esi ; ||hWnd 0040121F . FFD7 call near edi ; |GetDlgItem 00401221 . 50 push eax ; |hWnd 00401222 . FFD3 call near ebx ; EnableWindow 00401224 . 68 E8030000 push 3E8 ; /ControlID = 3E8 (1000.) 00401229 . 56 push esi ; |hWnd 0040122A . FFD7 call near edi ; GetDlgItem 0040122C . EB 33 jmp short 00401261 ;字符串拷贝完毕,准备跳转。
00401261 > 50 push eax ; /hWnd 00401262 . FF15 A8404000 call near dword ptr ds:[<&USER32.SetF>; SetFocus 00401268 . 6A 00 push 0 ; /BeepType = MB_OK 0040126A . FF15 AC404000 call near dword ptr ds:[<&USER32.Mess>; MessageBeep 00401270 . 8B0D E0544000 mov ecx, dword ptr ds:[4054E0] ; crackmes.00400000 00401276 . 6A 00 push 0 ; /lParam = NULL 00401278 . 68 60104000 push 00401060 ; |DlgProc = crackmes.00401060 0040127D . 56 push esi ; |hOwner 0040127E . 6A 79 push 79 ; |pTemplate = 79 00401280 . 51 push ecx ; |hInst => 00400000 00401281 . FF15 C8404000 call near dword ptr ds:[<&USER32.Dial>; DialogBoxParamA 继续调用API,成功破解完毕。