测试文件:https://adworld.xctf.org.cn/media/task/attachments/3f35642056324371b913687e770e97e6.exe
1.准备
打开测试文件,flag内容为乱码。
检测文件信息
获得信息
- 32位文件
- OllyDbg打开
2.IDA打开
将main函数反编译为C语言文件后,得到
1 int __cdecl __noreturn main(int argc, const char **argv, const char **envp) 2 { 3 int v3; // ecx 4 CHAR *lpMem; // [esp+8h] [ebp-Ch] 5 HANDLE hHeap; // [esp+10h] [ebp-4h] 6 7 hHeap = HeapCreate(0x40000u, 0, 0); 8 lpMem = (CHAR *)HeapAlloc(hHeap, 8u, MaxCount + 1); 9 memcpy_s(lpMem, MaxCount, &unk_409B10, MaxCount); 10 if ( sub_40102A() || IsDebuggerPresent() ) 11 { 12 __debugbreak(); 13 sub_401000(v3 + 4, lpMem); 14 ExitProcess(0xFFFFFFFF); 15 } 16 MessageBoxA(0, lpMem + 1, "Flag", 2u); 17 HeapFree(hHeap, 0, lpMem); 18 HeapDestroy(hHeap); 19 ExitProcess(0); 20 }
2.1 代码分析
1.看到第16行代码,输出flag,lpMem中保存着flag值。
2.第8行代码,为lpMen申请内存空间。
3.第9行代码,为lpMem赋值。其中&unk_409B10的值为
.data:00409B10 unk_409B10 db 0BBh ; DATA XREF: _main+33↑o .data:00409B11 db 0CCh .data:00409B12 db 0A0h .data:00409B13 db 0BCh .data:00409B14 db 0DCh .data:00409B15 db 0D1h .data:00409B16 db 0BEh .data:00409B17 db 0B8h .data:00409B18 db 0CDh .data:00409B19 db 0CFh .data:00409B1A db 0BEh .data:00409B1B db 0AEh .data:00409B1C db 0D2h .data:00409B1D db 0C4h .data:00409B1E db 0ABh .data:00409B1F db 82h .data:00409B20 db 0D2h .data:00409B21 db 0D9h .data:00409B22 db 93h .data:00409B23 db 0B3h .data:00409B24 db 0D4h .data:00409B25 db 0DEh .data:00409B26 db 93h .data:00409B27 db 0A9h .data:00409B28 db 0D3h .data:00409B29 db 0CBh .data:00409B2A db 0B8h .data:00409B2B db 82h .data:00409B2C db 0D3h .data:00409B2D db 0CBh .data:00409B2E db 0BEh .data:00409B2F db 0B9h .data:00409B30 db 9Ah .data:00409B31 db 0D7h .data:00409B32 db 0CCh .data:00409B33 db 0DDh
4. 从第13行代码我们知道,第10~15行代码在对lpMem操作,又因为 ExitProcess(0xFFFFFFFF);所以猜测,这段if结构没有执行(执行的话,就会直接退出,不会有跳出MessageBox对话框)
3.OllyDbg打开
00111307 > $ E8 531A0000 call 00112D5F 0011130C .^ E9 95FEFFFF jmp 001111A6 00111311 > 8BFF mov edi,edi 00111313 /. 55 push ebp 00111314 |. 8BEC mov ebp,esp 00111316 |. 81EC 28030000 sub esp,0x328 0011131C |. A3 589C1100 mov dword ptr ds:[0x119C58],eax 00111321 |. 890D 549C1100 mov dword ptr ds:[0x119C54],ecx 00111327 |. 8915 509C1100 mov dword ptr ds:[0x119C50],edx 0011132D |. 891D 4C9C1100 mov dword ptr ds:[0x119C4C],ebx 00111333 |. 8935 489C1100 mov dword ptr ds:[0x119C48],esi 00111339 |. 893D 449C1100 mov dword ptr ds:[0x119C44],edi 0011133F |. 66:8C15 709C1>mov word ptr ds:[0x119C70],ss 00111346 |. 66:8C0D 649C1>mov word ptr ds:[0x119C64],cs 0011134D |. 66:8C1D 409C1>mov word ptr ds:[0x119C40],ds 00111354 |. 66:8C05 3C9C1>mov word ptr ds:[0x119C3C],es 0011135B |. 66:8C25 389C1>mov word ptr ds:[0x119C38],fs 00111362 |. 66:8C2D 349C1>mov word ptr ds:[0x119C34],gs 00111369 |. 9C pushfd 0011136A |. 8F05 689C1100 pop dword ptr ds:[0x119C68] 00111370 |. 8B45 00 mov eax,dword ptr ss:[ebp] 00111373 |. A3 5C9C1100 mov dword ptr ds:[0x119C5C],eax 00111378 |. 8B45 04 mov eax,dword ptr ss:[ebp+0x4] 0011137B |. A3 609C1100 mov dword ptr ds:[0x119C60],eax 00111380 |. 8D45 08 lea eax,[arg.1] 00111383 |. A3 6C9C1100 mov dword ptr ds:[0x119C6C],eax 00111388 |. 8B85 E0FCFFFF mov eax,[local.200] 0011138E |. C705 A89B1100>mov dword ptr ds:[0x119BA8],0x10001 00111398 |. A1 609C1100 mov eax,dword ptr ds:[0x119C60] 0011139D |. A3 5C9B1100 mov dword ptr ds:[0x119B5C],eax 001113A2 |. C705 509B1100>mov dword ptr ds:[0x119B50],0xC0000409 001113AC |. C705 549B1100>mov dword ptr ds:[0x119B54],0x1 001113B6 |. A1 04901100 mov eax,dword ptr ds:[0x119004] 001113BB |. 8985 D8FCFFFF mov [local.202],eax 001113C1 |. A1 08901100 mov eax,dword ptr ds:[0x119008] 001113C6 |. 8985 DCFCFFFF mov [local.201],eax 001113CC |. FF15 14601100 call dword ptr ds:[<&KERNEL32.IsDebugger>; [IsDebuggerPresent 001113D2 |. A3 A09B1100 mov dword ptr ds:[0x119BA0],eax 001113D7 |. 6A 01 push 0x1 001113D9 |. E8 1C1A0000 call 00112DFA 001113DE |. 59 pop ecx 001113DF |. 6A 00 push 0x0 ; /pTopLevelFilter = NULL 001113E1 |. FF15 34601100 call dword ptr ds:[<&KERNEL32.SetUnhandl>; SetUnhandledExceptionFilter 001113E7 |. 68 3C611100 push 0011613C ; /pExceptionInfo = pro3.0011613C 001113EC |. FF15 30601100 call dword ptr ds:[<&KERNEL32.UnhandledE>; UnhandledExceptionFilter 001113F2 |. 833D A09B1100>cmp dword ptr ds:[0x119BA0],0x0 001113F9 |. 75 08 jnz X00111403 001113FB |. 6A 01 push 0x1 001113FD |. E8 F8190000 call 00112DFA 00111402 |. 59 pop ecx 00111403 |> 68 090400C0 push 0xC0000409 ; /ExitCode = C0000409 (-1073740791.) 00111408 |. FF15 2C601100 call dword ptr ds:[<&KERNEL32.GetCurrent>; |[GetCurrentProcess 0011140E |. 50 push eax ; |hProcess 0011140F |. FF15 28601100 call dword ptr ds:[<&KERNEL32.TerminateP>; TerminateProcess 00111415 |. C9 leave 00111416 . C3 retn
右键查找全部字符串,找到“Flag”的位置
001110A5 . 6A 02 push 0x2 ; /Style = MB_ABORTRETRYIGNORE|MB_APPLMODAL 001110A7 . 68 20781100 push 00117820 ; |Title = "Flag" 001110AC . FF75 F4 push dword ptr ss:[ebp-0xC] ; |Text 001110AF . 6A 00 push 0x0 ; |hOwner = NULL 001110B1 . FF15 E4601100 call dword ptr ds:[<&USER32.MessageBoxA>>; MessageBoxA 001110B7 . EB 14 jmp X001110CD 001110B9 > 6A 02 push 0x2 ; /Style = MB_ABORTRETRYIGNORE|MB_APPLMODAL 001110BB . 68 20781100 push 00117820 ; |Title = "Flag" 001110C0 . 8B45 F4 mov eax,dword ptr ss:[ebp-0xC] ; | 001110C3 . 40 inc eax ; | 001110C4 . 50 push eax ; |Text 001110C5 . 6A 00 push 0x0 ; |hOwner = NULL 001110C7 . FF15 E4601100 call dword ptr ds:[<&USER32.MessageBoxA>>; MessageBoxA
通过设置断点调试,我们可以了解到,if结构和第1个“Flag”处没有执行。
if结构对应汇编代码:
00111083 . E8 A2FFFFFF call 0011102A 00111088 . 85C0 test eax,eax 0011108A . 75 0A jnz X00111096 0011108C . FF15 14601100 call dword ptr ds:[<&KERNEL32.IsDebugger>; [IsDebuggerPresent 00111092 . 85C0 test eax,eax 00111094 74 23 je X001110B9 00111096 > 41 inc ecx 00111097 . 41 inc ecx 00111098 . 41 inc ecx 00111099 . 41 inc ecx 0011109A . CC int3 0011109B . 8B55 F4 mov edx,dword ptr ss:[ebp-0xC] 0011109E . E8 5DFFFFFF call 00111000 001110A3 . EB 4A jmp X001110EF
3.1 代码分析
既然这个if结构中有对flag值的操作,而且还跳过了,秉承“偷鸡摸狗,必定有内幕”的侦探心理,在OD修改代码,使得程序执行if结构,再跳转到第二个MessageBox处。
3.2 代码修改
00111083 . E8 A2FFFFFF call 0011102A 00111088 . 85C0 test eax,eax 0011108A . 75 0A jnz X00111096 0011108C . FF15 14601100 call dword ptr ds:[<&KERNEL32.IsDebugger>; [IsDebuggerPresent 00111092 . 85C0 test eax,eax 00111094 90 nop 00111095 90 nop 00111096 > 41 inc ecx 00111097 . 41 inc ecx 00111098 . 41 inc ecx 00111099 . 41 inc ecx 0011109A 90 nop 0011109B . 8B55 F4 mov edx,dword ptr ss:[ebp-0xC] 0011109E . E8 5DFFFFFF call 00111000 001110A3 EB 14 jmp X001110B9
3.3 运行获取flag
设置断点,之后调试。
4. get flag!
flag{reversing_is_not_that_hard!}