反編譯系列教程(中)
0x00 反編譯的侷限、先決條件和評價指標
反編譯技術具有一些侷限性,各類反編譯工具或者系統,都面臨著一些共同的困難,多數困難是由於需要恢復出一些輸入的二進位制檔案中並非顯式提供的資訊,畢竟程式語言在設計時考慮的不是逆向工程,而是正向編譯。這部分是有志反編譯技術人士面臨的主要技術困難。同時,也是惡意程式碼編寫者常用於對抗反編譯的技術手段。
1.反編譯技術面臨的宏觀問題
1)問題
同一機器上,同一語言的不同編譯版本存在目的碼結構上的差異,即多編譯版本問題;同一機器上,不同語言編譯存在目的碼結構上的差異,即多語言問題;不同機器上,同一語言編譯存在目的碼上的差異,即多機種(CPU,也就是多體系結構)問題。
2)相應的解決方案
上述這些問題都影響到以程式分析為目的反編譯系統的實用性和通用性。對這些問題,某些可能的解決途徑是:
最笨但一定可行的方法:針對每一種情況,分別開發各自的反編譯系統,這種窮舉方法勢必使反編譯投資龐大,且研製的反編譯器時效性差,顯然不適合實際需要。
基於同一機型,設計良好的中間語言(針對於特定的體系結構,比如X86固定暫存器表示等,與機器相關!!),開發標準的反編譯系統,對各編譯版本的影響或者不同語言的差別(目的碼結構上)採用預處理方法分別轉換為標準的中間語言形式,這種思路可行(不同前端-相同的中端,相同或者不同的後端),從中間語言轉換到高階語言的技術是成熟的,但要覆蓋各種情況,因而開發量也很大(僅比第一種方法看上去美些……)。
對於不同的機型和同一種語言,可以設計抽象的中間程式碼,也就是與體系結構不相關的,暫存器數量不限,採用目的碼預處理方法分別轉換到抽象的中間程式碼,接下來根據不同的後端,進行中間程式碼的提升,這種方法效果類似2)中所述(是目前常用的方法!)。
2.反編譯技術面臨的技術性問題
反向編譯需要解決如下一些傳統的難點問題,在此我們僅僅列出了最難解決的若干問題,而在一款反編譯器開發的過程中,開發者往往會遇到更多具體而又瑣碎的問題。
1)區分程式碼和資料
受馮•諾伊曼結構的制約,絕大多數計算機使用的資料和程式碼是儲存在同一段記憶體空間中的,因此,區分資料和程式碼的一般解決辦法已經被證明等價於停機問題。雖然,多種格式的可執行檔案都定義了程式碼段.text和資料段.data,但這樣並不能阻止編譯器或程式設計師把常量資料(如:字串、switch跳轉表)放入程式碼段中,也無法阻止將可執行程式碼放入資料段中。因此,程式碼和資料的區分仍然是一個亟需解決的重要問題。
針對程式碼和資料的區分問題,對靜態反編譯而言效果最好的一個方法是資料流制導的遞迴遍歷。此技術根據機器程式碼從程式的入口點搜尋所有可能的程式路徑,它依賴於程式的所有路徑都是有效的,且入口點是可發現的。最終,它同樣依賴於分析間接轉移指令以獲得其目標地址的能力,間接轉移指令包括間接跳轉和間接呼叫指令。
2)處理間接跳轉和間接呼叫指令
對於指令中的每個立即數運算元,都需要選擇將這個數值作為常量的值來表示還是作為指向記憶體中地址的指標來表示。對間接跳轉和間接呼叫的分析面臨著一個共同的問題——目標地址的確定。程式切片、表示式複製傳播和值域分析等是最有希望解決這一問題的技術,但是這些技術嚴重依賴於資料流分析,而資料流分析又依賴於完整的控制流圖。間接跳轉和間接呼叫問題未得到解決之前,是不可能擁有一個完整的控制流圖的。因此,初看起來它就如“雞跟蛋”問題一樣是無法解決的。
當反彙編器或者反編譯器面對一個指標尺寸(如:8位元組)的立即數時,它們需要判斷此立即數到底是常數(屬於整形、字元型或者其它資料型別)還是指向某型別資料的指標。
3)自修改程式碼
自修改程式碼指的是指令或者預先設定的資料在程式的執行中被修改。用於儲存指令的記憶體空間可能會在程式執行過程中被修改成為了另外的指令或者資料。在上個世紀六七十年代,計算機的記憶體空間很小,難以執行大的程式。計算機的最大記憶體為32Kb或64Kb,由於空間的制約,必須以最好的方式對空間進行利用,其中一種方法就是在可執行程式中節省位元組,同一記憶體單元在程式執行中能儲存指令,也能在另一時刻儲存資料或其他指令。
自修改程式碼是程式執行時改變自身執行指令的程式程式碼。自修改程式碼的編寫是非常困難的,因為它要考慮可能對指令快取造成的不良影響,它的主要用途是:反靜態分析、反盜版、病毒利用此方法逃避防毒軟體的查殺等。
4)編譯器和連結器包含的子過程
二進位制翻譯的另外一個問題就是編譯器引入的大量子過程以及連結器連結進來的很多過程造成翻譯難度和工作量大的問題。編譯器總是需要透過start-up子過程來設定環境,而且在需要的時候引入一些執行時的支援過程,這些過程通常是用匯編語言編寫的,無法翻譯到高階表示。同時,由於多數作業系統不提供共享庫機制,因此二進位制程式是自包含的,庫函式繫結到二進位制映像中,而且很多庫函式是用匯編語言編寫的。這就意味著二進位制程式包含的不僅僅是程式設計師編寫的過程,而且還有很多是連結器連結進來的其他過程。二進位制翻譯本身只對使用者編寫的過程感興趣,因此需要能夠區分使用者自定義過程和庫函式。
5) 對難點問題的總結
傳統的反編譯想要具備一定的實用性,下列問題是不能夠迴避的:
- 如何區分程式碼和資料
- 如何處理間接跳轉和間接呼叫指令,以獲得間接轉移指令的目標地址而完成對程式碼的完整挖掘
- 如何處理自修改程式碼
- 如何進行資料型別恢復。如果可以完全恢復源程式的資料和資料型別,那麼反編譯生成程式就可像源程式一樣執行於不同體系結構的機器,從反向編譯更加通用
3.反編譯的先決條件
反編譯的難度要遠遠大於編譯,因為編譯後得到的機器程式碼己將源程式中所有顯式的高階語言資訊完全丟失了。針對某種語言進行反編譯,不但需要較深的關於編譯和作業系統以及硬體等方面理論知識的支援,還需要透過大量的實踐和摸索獲得源——目標對之間的某些對應模式,在此基礎上進行研究和實踐。
反編譯的實踐,要以如下的背景知識作為先決條件:
- 反編譯所要達到的高階語言的語法描述;反編譯過程是由它所翻譯到的目標高階語言的語法來制導的。
- 反編譯原始檔所包含的目的碼集,即編譯所對應的機器指令集;只有掌握作為反編譯器的輸入的機器指令集的規格說明,才能有效地恢復低階程式碼程式的控制結構和資料流。
- 編譯所得到的可執行程式碼的記憶體映象:有效地區分資料區和程式碼區,能減小反編譯的工作量。
4.反編譯器的評價指標
反編譯器的效能評價方面並沒有確定的標準,通常人們採用如下幾點作為評價依據:
- 反編譯自動化程度:反編譯器執行過程中人工干預的次數是評定反編譯自動化程度的量度;
- 反編譯時間:即針對某個應用,反編譯器獲得結果所需要的執行時間;
- 反編譯器開發效率:重新編制程式和透過研製反編譯目標程式得到高階語言程式所需工作量的比值;
- 反編譯壓縮比:反編譯生成的高階語言程式與輸入的低階語言程式的長度比,比值越小,則壓縮比越大,反編譯器越優秀。
0x01 常見反編譯框架
比起如何使用一款反編譯工具,我們這裡更關心如何設計和實現一款實用的反編譯器以及需要用到哪些技術。在這裡,我們還是站在較為宏觀的角度列舉和認識一下幾種常見的反編譯器框架。在討論框架的同時,分析它們各自的優點,進行必要的對比。從整體上學習傳統反編譯器是如何設計的?能夠解決實際問題的新型反編譯又是如何設計的?以反編譯為核心技術實現的具有二進位制翻譯功能、同時又具備反編譯能力的“翻譯器”是怎樣設計的?
透過閱讀,讀者朋友們能夠從整體上了解實現不同用途的反編譯器的整體設計思路,以及一些具備現代反編譯特徵的(即多源反編譯、多源二進位制翻譯)新型反編譯器的框架設計理念。
1.“I型”反編譯器的框架
反編譯器在實際使用中,需要一些輔助程式來配合其建立目標高階語言的工作。無論這個反編譯器多麼簡單,至少也要包括能夠實現檔案裝載和可以處理有關庫函式在反編譯(或者具備二進位制翻譯特性的反編譯工作)過程中的庫函式處理程式。接下來我們將介紹經典反編譯器在囊括必要輔助程式以後的程式框架和基本功能組成。
1)上下文環境的銜接
一般來說,源二進位制程式都有一個重定位的地址表,當程式被裝入記憶體的時候,將在某些地址上進行重定位,通常反編譯器會透過裝載程式實現這個操作。接著,已經被重定位的(或絕對的)機器碼就會被反編譯器中的反彙編引擎進行機器碼到彙編碼的轉換,產生該程式的彙編表示。
反彙編引擎在工作中並非將可執行程式中所有01程式碼翻譯成彙編程式碼,而是需要藉助上文提到的“輔助程式”——即藉助“編譯器簽名”和“庫簽名”兩類輔助程式去掉編譯器在編譯時加入的啟動程式碼(start-up code)和庫例程程式碼,然後再對剩餘的由使用者編寫的程式碼進行反彙編。
接著,組合語言程式作為反編譯器的輸入,輸出併產生一個高階語言的目標程式。該目標程式並不是最終反編譯的結果,還需要進行進一步的處理,例如:對while()迴圈做轉換以便後期處理器處理等。
當然,“輔助程式”等自動工具不能保證在任何情況下都能進行正確的處理,反編譯過程有時需要人為的干預,即使用者也可能作為一個資訊提供者,尤其是在確定庫例程以及區分資料和指令的時候。經驗豐富的反編譯程式設計師比使用自動工具更可靠。
2)dcc反編譯器的框架
dcc是用C語言編寫的一個適用於DOS作業系統的原型反編譯器(昆士蘭大學Cristina Cifuentes博士期間進行的反編譯研究成果)。dcc最初在一臺執行Ultrix的DecStation 3000上開發,後來被移植到執行DOS的PC機體系結構上。dcc把Intel i80286體系結構的.exe檔案和.com檔案作為輸入,並且產生目標C語言和組合語言程式。這個反編譯器嚴格按照上一節介紹的反編譯上下文環境設計實現,它的框架由圖所示的幾個部分組成。
圖1 dcc反編譯器框架
(1)裝載器
裝載器是一段程式,它負責將待反編譯的目標程式載入記憶體,並完成目標程式機器碼的重定位(如果是可重定位的)。程式裝載是反編譯的準備階段的第一步。
(2)簽名生成器
簽名生成器是編譯器的重要“輔助程式”,它存在的目的是簡化反編譯的目標程式,簡化方法就是確定待反編譯程式的所使用的編譯器版本以及庫函式版本(dcc的編制者稱其為編譯器和庫的簽名,可以理解為編譯器和庫的特徵資訊)。簽名生成器可以自動、且唯一地標識每個編譯器和庫子程式的二進位制標本。這些簽名的使用試圖反向進行連結器的工作——連結器把庫和編譯器啟動程式碼連結到程式。透過上述處理,被分析的程式就剝離掉非使用者程式部分的所有編碼,只包含使用者當初用高階語言編寫的那部分程式。
從Cristina所給出的示例可以看出:顯示“hello world”的C程式編譯以後,在二進位制程式中有26個不同子程式,其中16個子程式是被編譯器增加來設定它的環境,9個例程是被連結器加入來實現printf(),1個子程式來自最初的C程式。簽名生成器的使用不僅減少了需要分析的子程式個數,也由於使用庫函式名稱代替任意的子程式名稱從而增加了目標程式的可讀性。
(3)原型生成器
原型生成器是一個自動確定庫子程式引數型別以及函式返回值型別的程式。這些原型來自於函式庫的標頭檔案,被反編譯器用來確定庫子程式的引數以及引數個數。原型生成器所做的工作是所有反編譯器必須著重處理的重要目標之一:函式恢復,包括庫函式的名稱、引數個數、引數型別、返回值型別等等。
(4)反彙編器
反彙編器是一個把機器語言轉換成組合語言的程式。有些反編譯器把組合語言程式轉換成一個更高階的表示法(一般是為統一多源目標反編譯的高階中間表示)。
(5)庫繫結
這一步是用來處理源可執行程式的編制語言與反編譯輸出的高階語言不一致的問題,例如:用Pascal編寫的程式所生成的可執行程式碼被反編譯成C程式。假如產生的目的碼中使用庫函式名稱 (也就是說能夠檢測到庫簽名),由於兩種語言使用不同的庫例程,所以即使這個程式是正確的也不能再用目標語言編譯它了,需要將原來用到的庫函式替換成反編譯目標語言的庫函式。dcc解決這個問題的辦法是使用庫繫結——在兩種語言的庫例程之間建立關聯。
當然這種類似的方法在反編譯或者二進位制翻譯中被普遍的使用,例如二進位制翻譯會涉及到誇作業系統使用庫函式,這樣即便是同一種高階語言也可能因為版本不同而存在庫函式的差異,因此這種“庫繫結”的處理方式適用面很廣。
(6)後期處理器
dcc後期處理器也是一個程式,它把一個高階語言程式轉換成同種語言的一個語義等價的高階程式,例如while迴圈轉換成for迴圈,此處假設目標語言是C語言,以下while迴圈的程式碼:
#!c
a = 1;
while (a < 50)
{
/* 其它 C程式碼 */
a =a + 1;
}
可能被後期處理器轉換成等價的for迴圈程式碼:
#!c
for (a = 1; a < 50; a++) { /*其它 C程式碼 */}
這是一個語義等價的程式,我們知道C語言中使用for作為迴圈結構具有更好的效能,因此此處後期處理器處理的結果是更適合於C語言的for迴圈,而不是反編譯器直接生成的反編譯結果的一般化結構while迴圈。
2.經典多源反編譯框架簡介
目前支援多源的反編譯框架主要有三種,分別是:基於語義描述和過程抽象描述的可變源、可變目標框架;以商用反彙編軟體IDA Pro為前端的、支援可擴充套件的反編譯框架;以及基於第三方程式碼轉換庫的多源反編譯框架。下面分別以三種框架的典型系統為例,簡單介紹和分析一下各種框架的特點。
1)UQBT
在實驗型反編譯器dcc的研發基礎上,畢業後Cristina Cifuentes和Mike van Emmerik等人於1997年提出了UQBT可重定向的二進位制翻譯系統,該二進位制翻譯系統是以反編譯為主要技術手段實現的。2001年研發者又對其後端作了擴充套件,在1999年版本的基礎上增加了對JVML的支援等功能。
(1)框架結構
UQBT的1999版框架如圖所示。
圖2 UQBT原始框架
2001年擴充套件後的框架結構如所示。
圖3 UQBT的擴充套件框架
UQBT框架可以大致被分為三部分:前端、分析和翻譯部分、後端。Ms表示給定的源機器,Md表示目標機器,前端負責對源機器Ms上的二進位制檔案解碼,並將其轉換為與機器無關的中間語言形式,即RTLs的形式;分析部分負責將源機器上的地址對映為目標機上的地址並完成相關的最佳化;後端負責將最佳化過的中間語言形式轉換為對應目標機上的可執行檔案。由此可見UQBT框架中的前端和分析部分相當於反編譯的部分,後端則是程式碼生成部分,即將反編譯後的程式碼再編譯或轉換為目標機上的可執行程式碼。
UQBT是可變源、可變目標的,對於反編譯來說只是為了實現從低階程式碼到高階程式碼的轉換,不需要再轉變為目標機器上的可執行程式碼,因此可以不考慮多目標的問題。UQBT的可變源和目標的特性透過描述語言、API和可插入模組支援。其中幾個形式化的描述語言成為UQBT的亮點和精髓,分別是:編解碼描述語言SLED、語義描述語言SSL、過程描述語言PAL等。
SLED語言
SLED語言是專門用來描述彙編指令與二進位制編碼之間對映關係的語言,支援RISC和CISC指令架構,已實現對MIPS、SPARC和Pentium的編解碼描述。基於SLED描述的指令解析,由NJMC(New JerseyMachine Code)工具集透過匹配語句來驅動,但對於一個特定的SLED描述檔案,要為其生成專門的匹配語句,而這個過程要實現自動化非常困難。
SSL語言
SSL語言包括兩類語義的描述,一類是描述每條彙編指令的語義,另一類則是描述硬體體系架構相關的特徵。透過定義constants、registers、flag_fnc、operands、tables、instr等關鍵詞來進行描述。其中constants用來描述常量、registers用來描述暫存器、flag_fnc用來描述標誌副作用、operands用來描述複雜運算元、tables用來描述一組指令名稱、instr則用來描述一條SSL語句。而一條SSL語句由左部LHS和右部RHS兩部分組成,左部對應的是彙編指令的名稱,或一組彙編指令對應的表的名稱,右部則是表示暫存器轉換的語句序列。對SSL語言的解析是由語義描述解碼器SRD來完成。由於SSL語言的語法比較複雜,要實現對各種SSL描述的正確解析也是很困難的。
PAL語言
PAL語言分別利用FRAME ABSTRACTION、LOCALS、PARAMETERS、RETURNS四種關鍵字對記憶體棧的抽象、本地變數的抽象、引數的抽象、返回值的抽象進行描述。其中記憶體棧的抽象主要描述用於存放記憶體棧指標的暫存器名稱;本地變數抽象主要描述棧幀分配的大小;引數的抽象主要從呼叫者和被呼叫者兩個角度描述實參和形參所在的可能位置;返回值的抽象則主要描述返回值與存放返回值的暫存器或記憶體單元之間的對應關係。
APIs
UQBT提供了二進位制檔案格式和控制轉移APIs。二進位制檔案格式有多種(如:Elf,PE等),但是這些表示都有方法可以從可執行程式中提取程式碼和資料——這種型別的資訊可以透過API獲得。
對於控制轉移API,需要開發者從無條件跳轉中識別條件轉移,也就是呼叫和返回。因為這些指令看起來都類似於跳轉,但是在語義上具有很小的差別。
(2)中間表示
UQBT應用兩種中間表示,低階RTL(Register TransferLists)直接與機器指令對映,高階HRTL(High LevelRegister Transfer Lists)形式與編譯器中間程式碼類似,它應用了控制流的高一級抽象。
RTL是一種基於暫存器的中間語言,它針對機器的彙編指令進行描述,代表了指令間的資訊傳遞。該語言提供了無限個暫存器和記憶體單元可供使用,不會受限於某種特殊的機器結構。近年來,RTL已經被廣泛的應用到各種系統中作為中間表示,例如GNU編譯器、編譯連線最佳化器OM、編輯庫EEL等等。由於其操作簡單並且具有良好的平臺無關性,因此我們選用RTL作為IA64到Alpha二進位制翻譯器的中間表示語言。
在UQBT中,源機器體系結構每一條指令對應一個暫存器傳送列表或RTL語句。這種語言能夠透過對某一位置的一系列執行效果來捕獲機器指令的語義資訊。
HRTL是從過程呼叫、過程內控制流等與機器特性相關的細節中抽象出來的一種高階中間表示語言,由指令和運算子組成。它提供了所有基本控制流指令,例如無條件跳轉(JUMP)和條件跳轉(JCOND)、應用CALL和RETURN指令的過程呼叫、N—way分支指令等,為了給記憶體單元賦值,HRTL定義了ASGN指令。
所有的記憶體單元和值都由語義串描述,分支指令將它們的跳轉目標作為語義串引數。複雜的語義串應用算術、邏輯或位元組運算函式遞迴定義。在ITA翻譯器的實現過程中,我們應用該語言表示IA-64指令語義時,需要對它的函式進行擴充套件,目前HRTL定義了一百多個不同的運算子和函式。
(3)前端模組
前端模組的工作由一系列階段完成,每一個階段將源輸入文字流變換成高一級的表示形式。
- 二進位制檔案的解碼器:將源二進位制檔案解碼到一種中間表示,該中間表示支援二進位制檔案格式API。所有的文字段和程式碼段被複製,並將得到的二進位制檔案資訊存放在中間表示中。
- 指令的解碼:將檔案解碼器得到的指令流進行反彙編。在UQBT中主要應用NJMCT提供的匹配檔案,結合指令的SLED描述檔案完成指令的解碼。
- 語義對映模組:將彙編指令對映成與源機器檔案程式碼段相對應的RTL表示,RTL由機器的SSL描述語言提供。這一步在彙編指令匹配之後執行,指令被轉換成暫存器傳送列表。
- Ms-RTL 到HRTL翻譯器,這是二進位制翻譯中的一個關鍵階段,以機器無關性來表示程式程式碼。該模組將RTL指令轉換成HRTL指令,處理控制轉移指令,基於PAL描述分析過程資訊,新增額外的程式碼處理源機器指令集的特性,其中機器特定的分析用於將機器相關性進行消除。在UQBT中這部分工作包括SPARC中控制的延遲轉移消除,Pentium中將基於棧的浮點程式碼變換成基於暫存器的程式碼;在我們的ITA翻譯器中這部分工作主要是IA-64體系結構的謂詞執行和投機機制等特性最佳化程式碼的處理。
(4)後端模組
UQBT框架應用多種後端產生程式碼,其中比較成功的方法是依賴C編譯器作為目標機的最佳化器和程式碼產生器。在這種方法中,HRTL程式碼被翻譯到低階C,應用C編譯器作為宏彙編器。後來的UQBT版本應用公共域或特性最佳化器後端,並整合在RTL級。
(5)開發耗時——一個有趣的事實
這裡我們討論一個有趣的事實,但卻能夠充分說明進行一款實用的反編譯器開發需要龐大的工作量,以及使用描述語言對開發效率的提升。在表中我們列出了基於UQBT翻譯框架開發其他的二進位制翻譯器所用的時間和人力,可以看出描述語言的應用使得在UQBT框架上容易實現其他機器的二進位制翻譯器。寫描述檔案與寫和機器相關的部分原始碼相比,無論是時間還是程式碼數量都少了很多,而且開發者還可以重用本系統提供的機器無關的分析。開發人員需要完成源機器指令的SLED和SSL描述檔案,以及應用PAL語言對源作業系統環境進行描述,再針對源機器的機器特性進行處理,結合目標機的特性完成相應的後端,這樣就可以有效地縮短二進位制翻譯系統的開發週期。
UQBT開發時間和人力情況:
里程碑 | 人力耗費 | 人力耗費細節 |
---|---|---|
(SPARC,Solaris)和(x86,Solaris) 前端;C後端 | 5.7(人-年) | 18(研究員-月),24(工程師-月)3.6(研究員-月),4.8(學生-月)6(學生-月),12(學生-月) |
(68328,PalmOs) 前端 | 6(人-月) | 3(工程師-月),3(工程師-月) |
JVML後端(C ver.) | 3(人-月) | 3(學生-月) |
JVML後端(Java ver.) | 5(人-月) | 3(學生-月),2(工程師-月) |
目的碼後端 | 3(人-月) | 3(學生-月) |
RTL後端 | 7(人-月) | 3(研究員-月)(SPARC)4(工程師-月)(ARM) |
(PA-RISC,HP-UX)前端 | 10(人-月) | 6(學生-月,)3(工程師-月)1(研究員-月) |
儘管UQBT提供的框架和二次開發方法大大提高了反編譯器的編寫效率,縮短了開發週期和時間,但是以筆者常年參與以反編譯為基礎的逆向分析方法的研究經歷和研發經驗來看——一款可用的反編譯器開發仍然會耗費一個10人團隊數年的開發時間。
2)Hex-Rays
Hex-Rays是一款商用反編譯工具,前端是IDA Pro。Hex-Rays實際上是IDA Pro中的反編譯外掛,因為IDA Pro支援擴充套件,且已經支援對大量不同指令集架構下可執行程式的反彙編,因此,Hex-Rays理論上可以實現對所有IDA Pro支援的指令集架構下的所有可執行程式進行反編譯,但目前為止,Hex-Rays僅實現了對x86和ARM平臺下可執行程式的反編譯,擴充套件緩慢。
與同類工具相比,Hex-Rays能很好的識別複合條件表示式及迴圈結構,對庫函式名及引數的識別率較高。另外Hex-Rays提供有Decompiler SDK,允許開發者以IDA Pro為前端,實現自己的分析方法。目前很多逆向分析人員都是利用IDA提供的介面來編寫外掛,從而完成漏洞挖掘、軟體確認、覆蓋分析等。
3)BAP
BAP是由David Brumley在BitBlaze靜態分析組建Vine的基礎上改進得到的,與BitBlaze相比,BAP對中間語言做了一些擴充套件,清除了Vine中存在的幾個漏洞。其框架如圖所示。
圖4 BAP框架
由圖中可以看到,BAP分為前端、中間語言、後端三部分。其中前端主要完成二進位制檔案格式的解析及語義的提升,後端主要完成相關的最佳化、程式驗證、其他的程式分析工作、生成相關的圖、程式碼生成等工作,中間語言程式碼則是基於libVEX第三方庫生成的VEX IR中間語言程式碼轉換得到的。BAP基於第三方的工具集,主要包括:反彙編器、程式碼轉換庫、GNU中的二進位制檔案解析工具libbfd,決策過程等。其中反彙編器BAP主要支援IDA Pro和GNU objdump,程式碼轉換庫是libVEX。值得一提的是,BAP支援動態分析,TEMU就是基於QEMU專門針對x86平臺的動態分析引擎,TEMU為使用者提供了各種語義提取介面以及動態汙點分析介面,為使用者進行動靜態結合的漏洞挖掘及惡意程式碼分析等工作提供了很好的平臺。
由於BAP前端主要依賴於第三方庫,只要第三方庫支援的平臺,BAP就會支援,第三方庫不支援的平臺BAP也無法進行分析,要實現對新平臺的支援,只能依賴第三方庫的擴充套件,因此存在被動擴充套件的問題。
相關文章
- 反編譯系列教程(上)2020-08-19編譯
- Android Apk反編譯系列教程(一)如何反編譯APK2019-04-14AndroidAPK編譯
- Android Apk反編譯系列教程(二)APK重打包2019-04-14AndroidAPK編譯
- 小程式反編譯教程2020-11-15編譯
- Android Apk反編譯系列教程(三)Android Studio除錯smali程式碼2019-04-14AndroidAPK編譯除錯
- Java編譯與反編譯2021-03-20Java編譯
- android 反編譯2024-10-04Android編譯
- Java 反彙編、反編譯、volitale解讀2018-08-14Java編譯
- java反編譯工具2021-08-13Java編譯
- Eclipse配置反編譯2020-12-07Eclipse編譯
- Android 反編譯指南2019-02-06Android編譯
- c#程式反編譯2024-09-04C#編譯
- Mac中編譯FFmpeg教程(Android版)2019-03-04Mac編譯Android
- webpack4 系列教程(二): 編譯 ES62018-07-31Web編譯
- Openwrt編譯教程2024-03-10編譯
- Java程式碼的編譯與反編譯那些事兒2019-05-09Java編譯
- 反編譯之安裝Apktool2018-10-25編譯APK
- android 反編譯APK取原始碼。2024-04-30Android編譯APK原始碼
- jad反編譯常用命令2020-04-04編譯
- python反編譯之位元組碼2019-05-19Python編譯
- Android反編譯工具Apktool淺析2018-12-25Android編譯APK
- 使用AndroidKiller進行APK反編譯2022-06-23AndroidAPK編譯
- 如何反編譯微信小程式?2021-11-02編譯微信小程式
- Go 高效能系列教程之三:編譯器優化2021-06-01Go編譯優化
- 使用ilasm 和 ildasm編譯和反編譯工具對DLL檔案修改2024-03-07ASMLDA編譯
- android反編譯相關命令總結2019-01-22Android編譯
- 安卓逆向之Luac解密反編譯2018-08-03安卓解密編譯
- .NET應用如何防止被反編譯2023-09-29編譯
- .NET反編譯神器ILSpy怎麼用?2023-09-23編譯
- Cython加密python程式碼防止反編譯2023-10-12加密Python編譯
- 微信小程式反編譯~2020年2020-07-19微信小程式編譯
- 有償找一懂dylib反編譯2020-10-23編譯
- Android的反編譯(佈局植入篇)2020-04-06Android編譯
- ecplise配置jad反編譯.class檔案2019-05-11編譯
- Android APK反編譯技巧全講解2019-05-14AndroidAPK編譯
- Angular入門到精通系列教程(14)- Angular 編譯打包 & Docker釋出2021-01-29Angular編譯Docker
- 使用Reflector和Filedisassembler逆向編譯反編譯.cs.dll檔案程式碼2019-05-10編譯
- AndroidKiller反編譯失敗的處理方法2018-11-29Android編譯