反匯編器(disassembler)是一種將機器語言轉換為匯編語言計算機程序——這與匯編器的目的相反。反匯編器與反編譯器不同,反編譯器的目標是高級語言而非匯編語言。反匯編器的反匯編輸出通常格式化為適合人類閱讀,而非用作匯編器的輸入源,因此它主要是一個逆向工程工具。

匯編語言源代碼通常允許使用常量和程序員注釋,而這些通常會在匯編器匯編的機器語言中被移除。因此,以機器代碼為基礎完成的反匯編結果將沒有這些常量和注釋,閱讀輸出結果將比閱讀源代碼更有難度。一些反匯編器提供了內置的代碼注釋功能,其生成的輸出增補了有關被調用API函數或被調用函數參數的注釋。一些反匯編器會利用對象文件(例如ELF)中存在的符號調試英語Symbolic debugging信息。例如,IDA允許人類用戶在交互式會話中為代碼的值或區域標記助記符號。

反匯編不是一門精準科學:在有可變寬度指令的複雜指令集(CISC)平台上,使用操作碼英語Opcode級編程或存在程序自修改代碼時,單個程序可能有兩個或多個合理的反匯編結果。程序在運行期間決定實際執行哪個指令被歸約停機問題,這是已知無法解決的問題。

反匯編的問題

編寫一個反匯編器,使其產生的代碼在匯編時與原始二進制文件完全一樣是可能的;但是,往往這兩者之間會有差異。這就對匯編器的表達能力提出了要求。例如,一個x86匯編器對哪怕像MOV AX,BX這樣簡單的事情,都要在兩個二進制代碼中任意選擇一個。如果原始代碼使用的是另一種選擇,那麼原始代碼在任何的時間點上都不能被反匯編器生成。然而,即使產生了一份完全正確的反匯編代碼,如果需要修改程序,那麼問題仍然存在。例如,同樣的機器語言跳轉指令可以由跳轉到一個指定的位置(例如,執行特定的代碼),或者跳轉指定的字節數(例如,跳過一個不需要的分支)的匯編代碼生成。反匯編器不知道目的是什麼,它可以使用任何一種語法來生成一個重現原始二進制的反匯編。然而,如果程序員想在跳轉指令和它的目標之間增加指令,就必須了解原程序的操作,以確定跳轉應該是絕對的還是相對的:也就是說,它的目的地應該被保持在一個固定的位置,還是被移動以便跳過原來的和增加的指令。

反匯編的例子

反匯編器可能獨立運行,也可能交互操作。獨立的反匯編器被執行時將生成可以查閱的匯編語言文件;交互式反匯編器則立即顯示用戶所做更改的結果。例如,反匯編器起初可能不知道程序的某一部分是代碼,而將其視為數據;如果用戶將其指定為代碼,則可立即顯示據其所生成的反匯編代碼,從而使用戶儘快查閱和採取進一步行動。

任何交互式調試工具都包含一些查看被調試程序的反匯編結果的方法。通常,相同的反匯編工具會被打包成單獨的反匯編器,與調試器分開發布。例如,objdumpGNU Binutils的一部分,而它與交互式調試器gdb相關。[1]

反匯編器和仿真器

動態反匯編器可以併入到一個仿真器管理程序的輸出中,從而步進、逐行執行要實時執行的機器指令。在此情況下,其包含反匯編後的機器代碼行,以及可顯示每條指令所引發的寄存器和/或數據改變(或者其他任何狀態英語State (computer science)的改變,例如有條件代碼),各個指令的變化都可以在反編譯後的指令旁邊或下方顯示。這從而提供了極為強大的調試信息,有助於最終解決問題,儘管這些信息有時可能非常大,尤其是如果程序很活躍。

參見

參考資料

拓展閱讀

外部連結

Wikiwand in your browser!

Seamless Wikipedia browsing. On steroids.

Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.

Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.