反組譯與反組譯器
磁碟上的可執行檔是一道由原始位元組砌成的牆——CPU 懂、你卻不懂的機器碼。反組譯器是把這些位元組翻回人類可讀組合語言的工具,還原出助憶符與運算元。反組譯既是這個過程,也是它產出的可讀組合語言列表。它是組譯器把組合語言文字變成位元組之動作的反向。
在機制上,反組譯器逐一走過程式碼位元組,依 ISA 的指令編碼解碼每一個,並印出對應的助憶符、運算元與定址模式。常見工具有 Linux 上的 objdump -d,以及像 gdb 這類除錯器內的反組譯視窗。反組譯不需要原始的原始碼——機器碼就夠了——這正是為什麼反組譯是逆向工程、惡意程式分析,以及對你手上沒有原始碼之程式進行除錯的核心。當你編譯自己的 C 時,反組譯其結果能讓你精確看到編譯器發出了什麼。
讀懂反組譯是整個本領域的實務報酬,因為它能回答別的方法都答不了的問題:最佳化器到底有沒有把那個呼叫內聯、把那個迴圈向量化,或把那個邊界檢查刪掉(可能因為未定義行為)?它讓你把對效能與行為的論斷紮根於機器字面上做了什麼,而非原始碼看似在說什麼。一個誠實的提醒:在一個去除符號的二進位中完美地分離程式碼與資料,一般而言是不可判定的,所以反組譯器偶爾會錯位,在它把資料誤認為程式碼之處產出垃圾指令。
對一支編譯好的程式執行 objdump -d,會把每個函式印成像 401136: 89 7d fc mov DWORD PTR [rbp-4], edi 這樣的行——位址、原始位元組,以及解碼後的指令。
反組譯器把機器碼位元組轉回可讀的組合語言;不需要原始碼。
反組譯還原的是指令,不是原始的原始碼:變數名稱、註解、型別與巨集都不見了,且最佳化編譯器可能已把程式碼重塑到難以一眼辨認。以 -g 編譯並用原始碼交錯的方式反組譯(objdump -S),可把指令對回原始碼的行。