攻防世界 csaw2013reversing2 CSAW CTF 2014

运行程序 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 }
View Code
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!}

这里就可以知道为什么调用第一个弹窗会失败了,因为第一个字符解码后为'\0',直接截断,所以会输出空白

猜你喜欢

转载自www.cnblogs.com/DirWang/p/11420740.html