解题:
放入查壳软件中查壳,发现是32位无壳的软件,运行一下程序,看看有什么样的输出,得到的是乱码。
所以可能是里面的运算有问题,进入ida中进行查看,进入main函数,看汇编代码可能存在问题,进入反编译。
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int v3; // ecx
CHAR *lpMem; // [esp+8h] [ebp-Ch]
HANDLE hHeap; // [esp+10h] [ebp-4h]
hHeap = HeapCreate(0x40000u, 0, 0);
lpMem = (CHAR *)HeapAlloc(hHeap, 8u, MaxCount + 1);
memcpy_s(lpMem, MaxCount, &unk_409B10, MaxCount);
if ( sub_40102A() || IsDebuggerPresent() )
{
__debugbreak();
sub_401000(v3 + 4, lpMem);
ExitProcess(0xFFFFFFFF);
}
MessageBoxA(0, lpMem + 1, "Flag", 2u);
HeapFree(hHeap, 0, lpMem);
HeapDestroy(hHeap);
ExitProcess(0);
}
看到了,flag应该是在lpMen里面,但是返回去看汇编
_main proc near ; CODE XREF: ___tmainCRTStartup+106↓p
.text:0040103A
.text:0040103A lpMem = dword ptr -0Ch
.text:0040103A var_8 = dword ptr -8
.text:0040103A hHeap = dword ptr -4
.text:0040103A argc = dword ptr 8
.text:0040103A argv = dword ptr 0Ch
.text:0040103A envp = dword ptr 10h
.text:0040103A
.text:0040103A push ebp
.text:0040103B mov ebp, esp
.text:0040103D sub esp, 14h
.text:00401040 push 0 ; dwMaximumSize
.text:00401042 push 0 ; dwInitialSize
.text:00401044 push 40000h ; flOptions
.text:00401049 call ds:HeapCreate
.text:0040104F mov [ebp+hHeap], eax
.text:00401052 mov eax, MaxCount
.text:00401057 inc eax
.text:00401058 push eax ; dwBytes
.text:00401059 push 8 ; dwFlags
.text:0040105B push [ebp+hHeap] ; hHeap
.text:0040105E call ds:HeapAlloc
.text:00401064 mov [ebp+lpMem], eax
.text:00401067 push MaxCount ; MaxCount
.text:0040106D push offset unk_409B10 ; Src
.text:00401072 push MaxCount ; DstSize
.text:00401078 push [ebp+lpMem] ; Dst
.text:0040107B call _memcpy_s
.text:00401080 add esp, 10h
.text:00401083 call sub_40102A
.text:00401088 test eax, eax
.text:0040108A jnz short loc_401096
.text:0040108C call ds:IsDebuggerPresent
.text:00401092 test eax, eax
.text:00401094 jz short loc_4010B9
.text:00401096
.text:00401096 loc_401096: ; CODE XREF: _main+50↑j
.text:00401096 inc ecx
.text:00401097 inc ecx
.text:00401098 inc ecx
.text:00401099 inc ecx
.text:0040109A int 3 ; Trap to Debugger
.text:0040109B mov edx, [ebp+lpMem]
.text:0040109E call sub_401000
.text:004010A3 jmp short loc_4010EF
.text:004010A5 ; ---------------------------------------------------------------------------
.text:004010A5 push 2 ; uType
.text:004010A7 push offset Caption ; "Flag"
.text:004010AC push [ebp+lpMem] ; lpText
.text:004010AF push 0 ; hWnd
.text:004010B1 call ds:MessageBoxA
.text:004010B7 jmp short loc_4010CD
.text:004010B9 ; ---------------------------------------------------------------------------
.text:004010B9
.text:004010B9 loc_4010B9: ; CODE XREF: _main+5A↑j
.text:004010B9 push 2 ; uType
.text:004010BB push offset Caption ; "Flag"
.text:004010C0 mov eax, [ebp+lpMem]
.text:004010C3 inc eax
.text:004010C4 push eax ; lpText
.text:004010C5 push 0 ; hWnd
.text:004010C7 call ds:MessageBoxA
.text:004010CD
.text:004010CD loc_4010CD: ; CODE XREF: _main+7D↑j
.text:004010CD push [ebp+lpMem] ; lpMem
.text:004010D0 push 0 ; dwFlags
.text:004010D2 push [ebp+hHeap] ; hHeap
.text:004010D5 call ds:HeapFree
.text:004010DB mov [ebp+var_8], eax
.text:004010DE push [ebp+hHeap] ; hHeap
.text:004010E1 call ds:HeapDestroy
.text:004010E7 push 0 ; uExitCode
.text:004010E9 call ds:ExitProcess
.text:004010EF ; ---------------------------------------------------------------------------
.text:004010EF
.text:004010EF loc_4010EF: ; CODE XREF: _main+69↑j
.text:004010EF push 0FFFFFFFFh ; uExitCode
.text:004010F1 call ds:ExitProcess
.text:004010F1 _main endp
.text:004010F1
.text:004010F7 ; ---------------------------------------------------------------------------
.text:004010F7 leave
.text:004010F8 retn
按照逻辑图来看。
没有走flag的那里的逻辑,所以我们静态调试可能就会很费劲,所以用OD进行调试,在OD中查找flag,直接跳转过去。
00A61092 . 85C0 test eax,eax
00A61094 74 23 je short 0453d212.00A610B9
00A61096 > 41 inc ecx ; 0453d212.<ModuleEntryPoint>
00A61097 . 41 inc ecx ; 0453d212.<ModuleEntryPoint>
00A61098 . 41 inc ecx ; 0453d212.<ModuleEntryPoint>
00A61099 . 41 inc ecx ; 0453d212.<ModuleEntryPoint>
00A6109A CC int3
00A6109B . 8B55 F4 mov edx,dword ptr ss:[ebp-0xC] ; kernel32.75D16739
00A6109E . E8 5DFFFFFF call 0453d212.00A61000
00A610A3 EB 4A jmp short 0453d212.00A610EF
00A610A5 . 6A 02 push 0x2 ; /Style = MB_ABORTRETRYIGNORE|MB_APPLMODAL
00A610A7 . 68 2078A600 push 0453d212.00A67820 ; |Flag
00A610AC . FF75 F4 push dword ptr ss:[ebp-0xC] ; |Text = "P(豼<豼^?t ?"
00A610AF . 6A 00 push 0x0 ; |hOwner = NULL
00A610B1 . FF15 E460A600 call dword ptr ds:[<&USER32.MessageBoxA>>; \MessageBoxA
00A610B7 EB 14 jmp short 0453d212.00A610CD
00A610B9 > 6A 02 push 0x2 ; /Style = MB_ABORTRETRYIGNORE|MB_APPLMODAL
00A610BB . 68 2078A600 push 0453d212.00A67820 ; |Flag
00A610C0 . 8B45 F4 mov eax,dword ptr ss:[ebp-0xC] ; |kernel32.75D16739
00A610C3 . 40 inc eax ; |
00A610C4 . 50 push eax ; |Text = "匉?
00A610C5 . 6A 00 push 0x0 ; |hOwner = NULL
00A610C7 . FF15 E460A600 call dword ptr ds:[<&USER32.MessageBoxA>>; \MessageBoxA
这里是有需要修改的地方,看逻辑位置,在图片中标记出来。
按照正常的逻辑,这里flag的运算会被跳过,那么把跳转和int3填充,让他跳回来,形成正常的一个逻辑。
逻辑从最开始的。
00A6108C . FF15 1460A600 call dword ptr ds:[<&KERNEL32.IsDebugger>; [IsDebuggerPresent
00A61092 . 85C0 test eax,eax
00A61094 74 23 je short 0453d212.00A610B9
00A61096 > 41 inc ecx ; 0453d212.<ModuleEntryPoint>
00A61097 . 41 inc ecx ; 0453d212.<ModuleEntryPoint>
00A61098 . 41 inc ecx ; 0453d212.<ModuleEntryPoint>
00A61099 . 41 inc ecx ; 0453d212.<ModuleEntryPoint>
00A6109A CC int3
00A6109B . 8B55 F4 mov edx,dword ptr ss:[ebp-0xC] ; kernel32.75D16739
00A6109E . E8 5DFFFFFF call 0453d212.00A61000
00A610A3 EB 4A jmp short 0453d212.00A610EF
00A610A5 . 6A 02 push 0x2 ; /Style = MB_ABORTRETRYIGNORE|MB_APPLMODAL
00A610A7 . 68 2078A600 push 0453d212.00A67820 ; |Flag
00A610AC . FF75 F4 push dword ptr ss:[ebp-0xC] ; |Text = "P(豼<豼^?t ?"
00A610AF . 6A 00 push 0x0 ; |hOwner = NULL
00A610B1 . FF15 E460A600 call dword ptr ds:[<&USER32.MessageBoxA>>; \MessageBoxA
00A610B7 EB 14 jmp short 0453d212.00A610CD
00A610B9 > 6A 02 push 0x2 ; /Style = MB_ABORTRETRYIGNORE|MB_APPLMODAL
00A610BB . 68 2078A600 push 0453d212.00A67820 ; |Flag
00A610C0 . 8B45 F4 mov eax,dword ptr ss:[ebp-0xC] ; |kernel32.75D16739
00A610C3 . 40 inc eax ; |
00A610C4 . 50 push eax ; |Text = "匉?
00A610C5 . 6A 00 push 0x0 ; |hOwner = NULL
00A610C7 . FF15 E460A600 call dword ptr ds:[<&USER32.MessageBoxA>>; \MessageBoxA
00A610CD > FF75 F4 push dword ptr ss:[ebp-0xC] ; /pMemory = kernel32.75D16739
00A610D0 . 6A 00 push 0x0 ; |Flags = 0
00A610D2 . FF75 FC push dword ptr ss:[ebp-0x4] ; |hHeap = 75D16720
00A610D5 . FF15 0860A600 call dword ptr ds:[<&KERNEL32.HeapFree>] ; \HeapFree
变成更改之后的。
00A6108C . FF15 1460A600 call dword ptr ds:[<&KERNEL32.IsDebugger>; [IsDebuggerPresent
00A61092 . 85C0 test eax,eax
00A61094 90 nop
00A61095 90 nop
00A61096 > 41 inc ecx
00A61097 . 41 inc ecx
00A61098 . 41 inc ecx
00A61099 . 41 inc ecx
00A6109A 90 nop
00A6109B . 8B55 F4 mov edx,dword ptr ss:[ebp-0xC]
00A6109E . E8 5DFFFFFF call 0453d212.00A61000
00A610A3 EB 14 jmp short 0453d212.00A610B9
00A610A5 . 6A 02 push 0x2 ; /Style = MB_ABORTRETRYIGNORE|MB_APPLMODAL
00A610A7 . 68 2078A600 push 0453d212.00A67820 ; |Flag
00A610AC . FF75 F4 push dword ptr ss:[ebp-0xC] ; |Text = ""
00A610AF . 6A 00 push 0x0 ; |hOwner = NULL
00A610B1 . FF15 E460A600 call dword ptr ds:[<&USER32.MessageBoxA>>; \MessageBoxA
00A610B7 EB 14 jmp short 0453d212.00A610CD
00A610B9 > 6A 02 push 0x2 ; /Style = MB_ABORTRETRYIGNORE|MB_APPLMODAL
00A610BB . 68 2078A600 push 0453d212.00A67820 ; |Flag
00A610C0 . 8B45 F4 mov eax,dword ptr ss:[ebp-0xC] ; |
00A610C3 . 40 inc eax ; |
00A610C4 . 50 push eax ; |Text = NULL
00A610C5 . 6A 00 push 0x0 ; |hOwner = NULL
00A610C7 . FF15 E460A600 call dword ptr ds:[<&USER32.MessageBoxA>>; \MessageBoxA
00A610CD > FF75 F4 push dword ptr ss:[ebp-0xC] ; /pMemory = 006701A2
00A610D0 . 6A 00 push 0x0 ; |Flags = 0
00A610D2 . FF75 FC push dword ptr ss:[ebp-0x4] ; |hHeap = NULL
00A610D5 . FF15 0860A600 call dword ptr ds:[<&KERNEL32.HeapFree>] ; \HeapFree
就可以获得flag值flag{reversing_is_not_that_hard!}