-找出 Main Function
x64dbg 預設會將 EntryPoint 設置中斷點,因此按下 F9 會在 EntryPoint (程式的進入點,會將參數和環境變數等資訊做處理,然後才會進入 Main Function)。這裡將介紹二種靠近關鍵程式碼區塊的方法,第一種是字串搜尋 、第二種是 API 搜尋,使用這些做法可以省去大多的時間去分析不感興趣的程式碼。
-字串搜尋
在程式碼區塊內按下右鍵 -> Search for,會看到 Current Module 和 All Modules,這裡先說明這二種搜尋字串的差別,如下列:
- Current Module (現在模塊):是指你在程式區塊 (0x401000 .text) 點擊的右鍵,只會看到這個模塊使用過的字串。
- All Modules (所有模塊):主程式和全部載入的動態連結函式庫使用過的字串。
由於 All Modules 會出現太多不相關的字串,因此只需要使用到 Current Module,在點選 String references。
由於範例程式碼是透過 printf 印出 Hellow World!,因此只要在點選 Hellow World! 這行,在按下 Enter 就可以進入 Main Function 的程式碼區塊。
按下 Enter 後的 Main Function 的程式碼區塊。
-API 搜尋
點擊右鍵選取 Search for -> Current Module -> Intermodular calls。
然後會跳出 Calls 的視窗,這邊就是 Current Module 所調用的 API,可以直接按 F2 下中斷點。
-顯示程式碼的佈置圖
在程式碼區塊按 G 就會跳出 Graph,它會將有JMP的語法 ( jmp, je, jne , ja, jb ......) 畫成流程圖,比較容易閱讀程式碼。
-反編譯成 C code
如果沒有那麼熟悉組合語言,可以使用這個功能。將需要轉換的組合語言,用滑鼠拖曳反白 -> Decompile -> Selection。
反編譯後的效果,由於程式比較簡單,所以不會有那麼的強烈反差。
-修改記憶體 、暫存器
在反編譯時,常常透過修改暫存器或記憶體來判斷是否跟我們要的結果是一樣的,例如讓一些原本要 JMP 的程式碼,使它們不 JMP。
-修改記憶體
還沒有改記憶體 (ebp - 4) 之前,在判斷 cmp [ebp-4], 1 是不會相等,因此 jne (不相等就 JMP) 是不會進入 printf。
點選 dword ptr [ebp-4]=[0028FF44]=0之後,它會變成灰色,然後再按右鍵 -> Modify Value -> Address: EBP-4 -> 將 Expression 的欄位改成 1 就可以了,修改完成後繼續單步執行就會進入 printf 了。
-修改暫存器
由於已經判斷完 cmp,因此 ZF 旗標等於 0 (如果 cmp 判斷二者值相等 ZF 就會等於1),所以 jne 就會 JMP 到0x4012D3,也就是不會進入 printf。
左鍵點擊2下 ZF 的旗標,就會從0改成1,然後使jne不會 JMP ,直接執行 printf。
-修改程式碼
修改記憶體或暫存器,只能在這次的執行有效果,如果重新執行程式還是不會進入 printf,那就要修改程式碼,再把結果另存執行檔,這樣每次都會顯示 Hellow World!。
在程式碼 jne test2.4012D3 那欄點擊左鍵2下,會跳出 Assemble at 004012C5 的視窗,然後將 jne 改成 jz 就可以了。
修改完成後點擊右鍵 -> Patches。
會跳出 Patches 的視窗,再點選 Patch File 後,會跳出 Save file 的視窗,最後再點選存檔,下次執行就是修改後的結果了。