XCTF_RE_csaw2013reversing2_WP

先運行一下程序,發現flag是一串亂碼,還好知道這個re題,不然又是一頓亂操作(爬。

yePFhQ.png

很快找到主函數,F5反編譯。

 
 
 
xxxxxxxxxx
 
 
 
 
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);//win32函數創建堆
  lpMem = (CHAR *)HeapAlloc(hHeap, 8u, MaxCount + 1);//win32爲堆申請空間
  memcpy_s(lpMem, MaxCount, &unk_409B10, MaxCount);//猜測將unk_409b10賦值給堆lpMem
  if ( sub_40102A() || IsDebuggerPresent() )//第二個函數是判斷是否被調試如果被調試就返回非零。
  {
    __debugbreak();//暫停程序執行,打開調試器,進入調試模式。(不知道做什麼用的)
    sub_401000(v3 + 4, lpMem);
    ExitProcess(0xFFFFFFFF);
  }
  MessageBoxA(0, lpMem + 1, "Flag", 2u);//win32釋放一個標題爲“Flag”,內容爲lpMem+1的文本框
  HeapFree(hHeap, 0, lpMem);//釋放空間
  HeapDestroy(hHeap);//銷燬對象
  ExitProcess(0);
}
 
 

不妨看一下其他的函數。

 
 
 
xxxxxxxxxx
 
 
 
 
int sub_40102A()
{
  char v0; // t1
  v0 = *(_BYTE *)(*(_DWORD *)(__readfsdword(0x18u) + 48) + 2);
  return 0;
}//一定返回0
 
 

那麼正常打開的情況下條件語句中的代碼沒有被執行。那麼我們不妨直接看一下lpMem(即unk_409b10)的內容:

yePitg.png

顯然是符合亂碼的。

接下來看一下分支語句中的函數:

 
 
 
xxxxxxxxxx
 
 
 
 
unsigned int __fastcall sub_401000(int a1, char *a2)
{
  int v2; // esi
  char *v3; // eax
  unsigned int v4; // ecx
  unsigned int result; // eax
  v2 = dword_409B38;
  v3 = &a2[strlen(a2 + 1) + 2];
  v4 = 0;
  result = ((unsigned int)(v3 - (a2 + 2)) >> 2) + 1;
  if ( result )
  {
    do
      *(_DWORD *)&a2[4 * v4++] ^= v2;//劃重點!!!
    while ( v4 < result );
  }
  return result;
}
 
 

這裏對lpMem的內容進行了修改,應該就是解密函數。所以我們需要做的就是讓這一步運行。

這裏我們啓用OD(ollydebug)。

先用中文搜索引擎+智能搜索選擇"Flag“來快速定位到我們的函數(直接到達的位置應爲00C810A7,向上翻即可)

yePApj.png

接下來我們應該做什麼?修改程序運行流程,做如下圖所示的三處修改:

1.抹除判斷語句的跳轉

2.抹除int3的異常

3.跳入第二個MassageBox()(第一個完全沒有入口是由於編譯器產生的一個無效的函數,鑑定方法:查看流程圖,感謝hsq學長的解答,hsqyyds)

yePE1s.png

Finally,you get it!

yeiPDx.png

另外附上使用IDA調試的方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章