反編譯技術探究

鴨脖發表於2012-04-21

摘要:編譯原理簡介,反編譯原理簡介,反編譯的主要步驟,反編譯的意義。

 

關鍵字:反編譯,編譯,中間程式碼,逆過程。

 

內容:

反編譯,又稱為逆向編譯技術,是指將可執行檔案變成高階語言源程式的過程。反編譯技術依賴於編譯技術,是編譯過程的逆過程。欲理解反編譯技術的原理所在,我們需要先系統的瞭解一下編譯技術。

編譯技術就是把高階語言變成可執行檔案的過程。它的主要過程如下所示:

 

圖片

 


編譯程式把一個源程式翻譯成目標程式的工作過程分為五個階段:詞法分析;語法分析;語義檢查和中間程式碼生成;程式碼優化;目的碼生成。詞法分析的任務是對由字元組成的單詞進行處理,從左至右逐個字元地對源程式進行掃描,產生一個個的單詞符號,把作為字串的源程式改造成為單詞符號串的中間程式。語法分析以單詞符號作為輸入,分析單詞符號串是否形成符合語法規則的語法單位,如表示式、賦值、迴圈等,最後看是否構成一個符合要求的程式。語義分析是審查源程式有無語義錯誤,為程式碼生成階段收集型別資訊。中間程式碼是源程式的一種內部表示,或稱中間語言。中間程式碼的作用是可使編譯程式的結構在邏輯上更為簡單明確,特別是可使目的碼的優化比較容易實現程式碼優化是指對程式進行多種等價變換,使得從變換後的程式出發,能生成更有效的目的碼。目的碼生成是編譯的最後一個階段。目的碼生成器把語法分析後或優化後的中間程式碼變換成目的碼。表格管理和出錯處理不在本篇文章的研究範圍,故不再贅述。

對於反編譯技術,我們上文提到,它是編譯的逆過程。那是不是把上述的六個步驟倒置,就變成了反編譯的過程了呢?顯然是不對的。對於反編譯過程,我們可以這麼去理解:我們的源程式現在是二進位制可執行檔案或者彙編指令,我們的目標程式是某種特定的高階語言。那麼現在這個過程該如何轉化呢?這其中的中間程式碼的生成是否和編譯過程中的一樣呢?

基於上述原理及其疑問,我們很容易便採用這種思想:將特定的機器程式碼,即我們的“源程式”,先翻譯為低階的中間程式碼,然後再根據特定的高階語言將中間程式碼翻譯為高階程式。沒錯,反編譯的主要思想確實就是那樣:反編譯器也有前端和後端。前端是一個機器依賴的模組,句法分析二進位制程式、分析其指令的語義、並且生成該程式的低階中間表示法和每一子程式的控制流向圖。通用的反編譯機器是一個與語言和機器無關的模組,分析低階中間程式碼,將它轉換成對任何高階語言都可接受的高階表示法,並且分析控制流向圖的結構、把它們轉換成用高階控制結構表現的圖。最後,後端是一個目標語言依賴的模組,生成目標語言程式碼。反編譯的過程中要使用一些工具:把二進位制程式裝入記憶體,對這一程式做句法分析或反彙編,以及反編譯或者分析該程式來生成高階語言程式。這個過程藉助編譯器和庫的簽名來識別特定的編譯器和庫子程式。只要在二進位制程式中識別出編譯器簽名,就不去反編譯這些編譯器啟動程式碼(start-up)和庫子程式:對於前者,從最後的目標程式去掉啟動程式碼的那些例程,反編譯器從主(main)程式入口點開始分析;對於後者,那些子程式用其庫函式名代替。所以我們可以採用下圖來表示反編譯的過程:

 

圖片

 


上圖是我們對於反編譯過程的初級構想(按照我們的理解),而實際的更為詳細的過程則如下所示:


 圖片

 

我們再對上述各個過程做一下更為詳細的介紹:

1語法分析:語法分析程式或語法分析器把源程式的位元組組織成源機器語言的語法短語(或語句)。這些短語用一個語法分析樹表示。語法分析器的主要問題是確定哪些是資料和哪些是指令。

2語義分析:語義分析階段檢查源程式一組指令的語義含義,收集型別資訊並且向整個子程式傳遞這個型別。對於任何一個編譯器生成的二進位制程式,只要程式能執行,其機器語言的語義一定是正確的。沒見過哪一個二進位制程式是因為編譯器生成程式碼的錯誤而不能執行。因此,除非語法分析器對某一條指令做了不正確的分析或者把指令當作資料分析,否則,在源程式中是不會有語義錯誤的。

3中間程式碼生成:反編譯器分析程式需要一箇中間表示法來明晰地表現源程式。它必須容易從源程式中生成,而且還必須適合用來表示目標語言。

4控制流圖生成:源程式中每一個子程式的控制流圖也是為反編譯器分析程式所必需的。這個表示法適合用來確定在程式中的高階控制結構。它也被用來清除掉由於機器語言的條件跳轉有偏移量限制因而被編譯器產生的中間跳轉。

5資料流分析:資料流分析階段試圖改善中間程式碼,以便能夠得到高階語言表示式。在這個分析期間,臨時暫存器的使用和條件標誌被清除掉,因為在高階語言裡面沒有這些概念。

6控制流分析器階段試圖將程式每一個子程式的控制流圖組織成一個高階語言構造的類集(通有的)。這個類集必須包含大多數語言都有的控制指令

7程式碼生成:反編譯器的最後階段是在控制流圖和每一個子程式中間程式碼的基礎上生成目標高階語言程式碼。為所有的區域性棧、引數和暫存器變數識別符號選擇變數名稱。也為在程式中出現的各個例程指定各自的子程式名稱。

 

把二進位制程式從各種各樣的機器語言反編譯為多種多樣的高階語言,都要用到基本的反編譯器技術。反編譯器的結構是以編譯器的結構為基礎,採用與之相似的原理和技術來進行程式分析。第一代反編譯器誕生於20世紀60年代早期,比它們的姐姐——編譯器小十歲。對於第一代編譯器,反編譯大量地被用來翻譯科學程式在編寫一個反編譯器的時候,反編譯器作者必須面對一些理論上和實際的問題。有些問題能夠通過使用試探方法(啟發式)解決,而另一些則不能被完全確定。由於這些限制,反編譯器對某些源程式能夠進行全自動的程式翻譯,而對其它一些源程式則需要進行半自動的程式翻譯。這與編譯器對所有源程式都進行全自動程式翻譯是不同的。正如李莉老師課堂中提到的關於常量的反編譯,這些都體現了反編譯的種種限制。

 

反編譯是計算機專業人士的一個工具。反編譯主要使用在兩個領域:軟體維護與安全性。在前一個領域,反編譯被用來恢復丟失的或者不能見到的源程式程式碼,將一個使用過時的語言編寫的程式碼翻譯成一個較新的語言,將一個以非結構化方式編寫的舊程式(亦即,多層式程式碼)構成一個結構化程式,將應用程式移植到一個新的硬體平臺,以及除錯已知有缺陷但是原始碼不可得的二進位制程式。在後一領域,反編譯在軟體關鍵系統中被用來驗證一個編譯器產生的目的碼,因為在這些系統中編譯器不足以信賴,另外,反編譯也被用來檢查是否存在惡意程式碼比如病毒。

 

關於反編譯的合法性問題去年已經被提出來了。反編譯支持者和反對者之間的爭論目前正在進行,支援方主張反編譯工具的使用有利於公平競爭,反對方主張反編譯侵犯了版權。各個不同國家正在修改法律以確定在哪些情況下反編譯是法律許可的。目前,商業軟體的銷售隨同軟體協議書禁止使用者反彙編或反編譯其產品。例如,Lotus軟體協議部分這樣寫道:
You may not alter, merge, modify or adapt this Sofware in any way including disassembling or decompiling.對於其他方面的法律問題,本文不做討論。

 

以上便是對反編譯技術的探究及簡單的總結,迫求指正。

 

引用:

百度百科:http://baike.baidu.com/view/481013.htm

逆向編譯技術:http://www.hackbase.com/tech/2009-08-18/55060_1.html

百科:http://baike.baidu.com/view/69568.htm

反編譯:http://bbs.bbfish.net/thread-10023-1-1.html

相關文章