运行程序 flag显示乱码
IDA打开查看程序逻辑
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, unk_409B34 + 1); 9 memcpy_s(lpMem, unk_409B34, dword_409B10, unk_409B34); 10 if ( sub_40102A() || IsDebuggerPresent() ) 11 { 12 __debugbreak(); 13 sub_401000(v3 + 4, lpMem); 14
1 unsigned int __fastcall sub_401000(int a1, char *a2) 2 { 3 int v2; // esi 4 char *v3; // eax 5 unsigned int v4; // ecx 6 unsigned int result; // eax 7 8 v2 = dword_409B38; 9 v3 = &a2[strlen(a2 + 1) + 2]; 10 v4 = 0; 11 result = ((unsigned int)(v3 - (a2 + 2)) >> 2) + 1; 12 if ( result ) 13 { 14 do 15 *(_DWORD *)&a2[4 * v4++] ^= v2; 16 while ( v4 < result ); 17 } 18 return result; 19 }
15 ExitProcess(0xFFFFFFFF); 16 } 17 MessageBoxA(0, lpMem + 1, "Flag", 2u); 18 HeapFree(hHeap, 0, lpMem); 19 HeapDestroy(hHeap); 20 ExitProcess(0); 21 }
可发现:
1.存在反调试IsDebuggerPresent()
2.lpMem还出现在sub_401000(v3 + 4, lpMem)函数中,但该函数未被调用
动态调试:
跳过反调试,跳转到sub_401000 函数 (调试用基地址会变,但偏移不变 0x1000)
解码后调用原弹窗(程序中有两个MessageBoxA函数,陷阱,第一个输出lpMem,第二个输出(lpMem+1)),这里需要跳转到第二个弹窗处,即原弹窗处
运行
flag{reversing_is_not_that_hard!}
解码脚本:
1 x=[0xbb,0xaa,0xcc,0xdd] 2 y=bytes.fromhex('BBCCA0BCDCD1BEB8CDCFBEAED2C4AB82D2D993B3D4DE93A9D3CBB882D3CBBEB99AD7CCDD') 3 z=[] 4 i=0 5 while i<len(y): 6 t=chr(y[i]^x[i%4]) 7 z.append(t) 8 i+=1 9 print(z) 10 print(''.join(z))
['x00', 'f', 'l', 'a', 'g', '{', 'r', 'e', 'v', 'e', 'r', 's', 'i', 'n', 'g', '_', 'i', 's', '_', 'n', 'o', 't', '_', 't', 'h', 'a', 't', '_', 'h', 'a', 'r', 'd', '!', '}', 'x00', 'x00']
flag{reversing_is_not_that_hard!}
这里就可以知道为什么调用第一个弹窗会失败了,因为第一个字符解码后为' ',直接截断,所以会输出空白