反彙編patch學習
編寫一個測試程式
這個程式沒有什麼意義,在IDA中把puts函式patch成nop用於新增我們自己的指令
肯定有更好的方法,但是這裡只是為了練習
visual studio 2019 preview x64 release編譯
#include<stdio.h> #include<stdlib.h> #include<string.h> int main(int argc, char** argv) { char a; system("pause"); a = getchar(); puts("nop me"); puts("nop me"); puts("nop me"); puts("nop me"); puts("nop me"); puts("nop me"); puts("nop me"); putchar(a); system("pause"); return 0; }
patch過程
新增nop
IDA開啟,根據字串找到我們自己的邏輯

把一部分puts("nop me") patch成nop,類似這樣,在這些nop中開始表演

新增特別的彙編指令
這裡現在一堆nop中新增如下的兩條指令,來分析一下

- call $+5也就是跳轉到pop rax,看起來和直接跳到下一條指令沒什麼區別
- 但實際上,call會把下一條要執行的指令地址壓棧,這裡也就是把0x140001035壓棧
- 再pop rax,這時rax就是0x140001035了
- 調整rax的位置,加上8以後jmp rax,準備跳到原本的指令中
- 這裡rax==0x140001035+8==0x14000103C
- patch到這裡,儲存一下,即附件中的patched1
- 在IDA中重新開啟,除錯發現,jmp rax即將跳轉到jmp指令的之後的某條指令上
新增垃圾指令
為了讓反彙編引擎"出錯",我們可以在中間即將跳過的nop中,新增特殊的垃圾指令
比如剛剛動態除錯發現會跳轉到...03D的位置上,那我們就讓03D的指令是jmp到接下來的原程式流程
這裡也就是跳轉到puts("nop me")

儲存一下,作為patched2
可以看到還是可以正常執行的
雖然IDA的反彙編引擎識別的不錯,但是F5的結果就有點差了


我們改成0xEB,儲存為patched3,重新開啟,可以看到IDA的反彙編已經把很多指令識別為資料了

F5後也看不到原本的幾個puts("nop me")了
讓IDA正確分析
本程式中,可以通過動態除錯發現jmp rax的目的地,然後從call $+5開始,把這些指令都nop掉,直接jmp 到該去的地址,幫助IDA正確分析
幫助IDA瞭解哪些是資料、哪些是程式碼指令,可以用U D C這三個快捷鍵,應該是undefine,data,code的意思