题目描述:听说运行就能拿到Flag,不过菜鸡运行的结果不知道为什么是乱码
运行一下,出现弹窗,标题是flag,内容是好乱的码。查了一下,无壳,32位exe
拿去IDA分析
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);
//unk_409B10存的是乱码,复制到lpMem里
if ( sub_40102A() || IsDebuggerPresent() )
{
__debugbreak();//跳出if语句,执行MessageBoxA语句
sub_401000(v3 + 4, lpMem);//解码函数
ExitProcess(0xFFFFFFFF);//退出程序
}
MessageBoxA(0, lpMem + 1, "Flag", 2u);//lpMem存的是flag
HeapFree(hHeap, 0, lpMem);
HeapDestroy(hHeap);
ExitProcess(0);
}
所以在if语句中,我们要绕过__debugbreak();
和ExitProcess(0xFFFFFFFF);
。回去看main的汇编代码
.text:00401083 call sub_40102A
.text:00401088 test eax, eax
.text:0040108A jnz short loc_401096 ;if的条件语句,要让它跳到96去
.text:0040108C call ds:IsDebuggerPresent
.text:00401092 test eax, eax
.text:00401094 jz short loc_401089 ;if的条件语句
.text:00401096
.text:00401096 loc_401096:
.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
;jmp EF直接退出,所以不能jmp到EF去,要jmp到B9调用MessageBox
.text:004010EF
.text:004010EF loc_4010EF: ; uExitCode
.text:004010EF push 0FFFFFFFFh
.text:004010F1 call ds:ExitProcess
.text:004010F1 _main endp
.text:004010F1
.text:004010B9 ;弹窗
.text:004010B9 loc_4010B9: ; uType
.text:004010B9 push 2
.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
绿色线连着的表示条件为true时执行的逻辑,而红色线表示条件为false时执行的逻辑。
加载进OD,遇到问题下断点,直到在注释窗口遇到MessageBox函数,在函数上下附近找找,跟IDA以上相似的汇编代码,修改对应指令,就可得到flag。
jnz short 00ED1096 => jz short 00ED1096
int3 => nop
jmp short 00ED10EF => jmp short 00ED10B9
flag{reversing_is_not_that_hard!}