高洪濤 楊棟翔 李明程 程春
摘要:軟件逆向工程對于國外先進技術(shù)引進、惡意代碼檢測等有重要意義。隨著嵌入式技術(shù)的高速發(fā)展,以ARM架構(gòu)微處理器為核心的嵌入式系統(tǒng)在國防、通信、自動控制等關(guān)鍵領(lǐng)域得到了普遍應(yīng)用。本文以某型航空發(fā)動機數(shù)據(jù)采集單元(DCU)的二進制程序逆向為例,闡述了一種基于ARM7TDMI架構(gòu)的嵌入式軟件逆向分析流程和方法。結(jié)果顯示,本方法可以對DCU軟件的全部子函數(shù)和全局變量功能進行有效逆向分析,可以作為功能分析及維護保障的重要依據(jù)。
關(guān)鍵詞:ARM7TDMI;逆向工程;嵌入式軟件;二進制
Keywords:ARM7TDMI;reverse engineering;embedded software;binary
0 引言
隨著嵌入式系統(tǒng)的飛速發(fā)展,在嵌入式領(lǐng)域占據(jù)主導(dǎo)地位的ARM架構(gòu)微處理器在國防電子、電力系統(tǒng)、工業(yè)自動化、汽車電子、醫(yī)療設(shè)備、無線通信等國家關(guān)鍵領(lǐng)域都有十分廣泛的應(yīng)用。 ARM微處理器采用RISC(精簡指令集)架構(gòu),具有體積小、成本低、能效比高等特點。如圖1所示,2003年以前,ARM架構(gòu)主要包括ARM7TDMI、ARM9E、ARM11等系列。2003年之后,ARM架構(gòu)主要分為A系列、R系列和 M系列,A系列主要用于頂級主控,如手機、平板電腦的應(yīng)用處理器;R系列主要用于實時高性能場景,如車輛控制等;M系列主要用于低端應(yīng)用領(lǐng)域,如消費電子等。
鑒于ARM架構(gòu)在各個領(lǐng)域的廣泛應(yīng)用,針對ARM架構(gòu)進行逆向分析具有重要的價值和意義。在民用領(lǐng)域,逆向分析可以幫助檢測惡意代碼,找出隱藏的后門軟件以避免系統(tǒng)被攻擊;在軍事領(lǐng)域,逆向分析有助于快速學習并引進國外的軍事工業(yè)技術(shù),發(fā)展我國的國產(chǎn)化裝備。軟件逆向工程按照工程實踐,可以分為兩類:一類是從已知的軟件系統(tǒng)的源碼出發(fā),生成對應(yīng)的系統(tǒng)結(jié)構(gòu)及設(shè)計原理、算法思想的文檔;另一類軟件逆向的研究對象是二進制,即沒有源代碼的逆向分析。二進制逆向工程按照程序的結(jié)構(gòu)特點,又可以分為結(jié)構(gòu)化二進制逆向和非結(jié)構(gòu)化二進制逆向。前者的研究對象是具有規(guī)范的文件格式、包含了程序動態(tài)執(zhí)行與靜態(tài)分析相關(guān)的程序信息,如PE、ELF文件等;后者的研究對象是僅包含數(shù)據(jù)和指令的固件代碼,如bin、hex格式的芯片內(nèi)置程序等[1]。二進制逆向工程是目前研究的重點。
公開資料顯示,目前國內(nèi)ARM逆向工程的研究重點主要在工具層面,如趙亞新等基于芯片的JTAG接口分析固件的運行機制[2]。解放軍信息工程大學蔣烈輝團隊在開發(fā)ARM的反匯編自動化工具方面做了大量工作,將ARM指令集轉(zhuǎn)為高級語言[3,5];井靖等提出了嵌入式軟件的動靜態(tài)分析機制,以幫助逆向分析軟件的調(diào)用關(guān)系和完整性等[4]。此外,為了方便脫離硬件環(huán)境對固件代碼進行分析和調(diào)試,鮑慶國引入了QEMU技術(shù)進行仿真模擬[5]。然而,這些工作只能將二進制文件轉(zhuǎn)為代號或地址表達的高級語言,無法真正解析函數(shù)或變量的具體含義。
本文使用目前最流行的逆向分析軟件IDA Pro,將二進制文件轉(zhuǎn)換為ARM指令集的匯編語言,在此基礎(chǔ)上,以某型發(fā)動機數(shù)據(jù)采集單元(DCU)為研究對象,闡述一種ARM架構(gòu)嵌入式軟件的逆向分析方法,從ARM框架代碼入手,結(jié)合DCU的已知功能情況,依次逆向分析各個子函數(shù)和全局變量的實際含義。
1 ARM7TDMI架構(gòu)
ARM7系列包括ARM7TDMI、ARM7TDMI-S、ARM720T和擴充了Jazelle的ARM7EJ-S等內(nèi)核。ARM7TDMI內(nèi)核支持32位尋址范圍,其命名規(guī)則為:
● T:支持高密度16位的Thumb指令集;
● D:支持片上調(diào)試;
● M:支持64位乘法;
● I:支持EmbededICE觀察硬件;
● S:ARM7TDMI的軟核版本,編程模型與ARM7TDMI一致。
ARM處理器使用流水線增加處理器指令流的速度,可以同時進行幾個操作。ARM7TDMI的流水線分3級,分別是取值、譯碼和執(zhí)行。ARM7TDMI處理器使用了馮諾依曼結(jié)構(gòu)進行存儲器訪問,指令和數(shù)據(jù)共用一條32位總線,只有裝載、存儲和交換指令可以對存儲器中的數(shù)據(jù)進行訪問。
ARM7TDMI支持7種處理器模式,分別為用戶模式、FIQ模式、IRQ模式、管理模式、中止模式、未定義模式和系統(tǒng)模式。各模式的定義和關(guān)系如表1所示。
ARM7TDMI具有37個寄存器,包括31個通用的32位寄存器和6個狀態(tài)寄存器。ARM各模式下可以訪問的寄存器如表2所示。
根據(jù)各寄存器的作用范圍和特點,從ARM7TDMI的匯編代碼可以直接進行如下逆向分析工作。
1)??臻g操作分析:寄存器R13通常作為棧指針(SP),當使用R13時,通常是在操作棧空間的內(nèi)容。
2)子函數(shù)調(diào)用分析:寄存器R14稱為鏈接寄存器(LR),當要調(diào)用子函數(shù)時,其用于保存當前函數(shù)的下一條指令地址,子函數(shù)執(zhí)行完畢后,將LR寄存器的內(nèi)容放入R15(PC),返回原函數(shù)。因此,匯編語句中有BX LR的地方,一般情況下可以視作子函數(shù)的結(jié)尾標志。
3)函數(shù)傳入?yún)?shù)分析:R0~R7可以作為子函數(shù)的傳入?yún)?shù),當一個函數(shù)中直接使用R0~R7寄存器的內(nèi)容時,該函數(shù)可以視為有傳入?yún)?shù)的函數(shù)。若R0在函數(shù)中第一次使用時是被賦值,則該函數(shù)的傳入?yún)?shù)肯定是void類型。
4)分支跳轉(zhuǎn)分析:對于BL分支指令,返回指令應(yīng)為MOV PC,R14或?qū)崿F(xiàn)類似功能的語句,通過判斷該語句可以找到分支結(jié)束的標志。
5)中斷響應(yīng)函數(shù)分析:針對中止、FIQ、IRQ等異常模式,當退出異常模式時,應(yīng)有SUBS PC,R14或?qū)崿F(xiàn)類似功能的語句,通過查找這個語句,可以找到整個代碼的中斷響應(yīng)函數(shù)。
2 DCU逆向流程
針對DCU的逆向分析流程如圖2所示。
硬件電路逆向,主要包括DCU正常工作時的各關(guān)鍵測試點的信號、電平、開關(guān)量的測試,以及電路測繪和驗證,最終獲得DCU的電路原理圖及關(guān)鍵測試點的工作狀態(tài)表,如圖3所示。
上位機協(xié)議逆向,通過抓取上位機軟件與DCU進行通信的數(shù)據(jù)包,通過改變數(shù)據(jù)內(nèi)容查看其影響范圍,獲取上位機協(xié)議相關(guān)信息。本階段獲得上位機通信協(xié)議。
二進制文件提取,是通過JTAG(DCU的MCU芯片支持JTAG)接口,使用J-Flash軟件,直接讀取ARM7TDMI芯片的全部Flash內(nèi)容。二進制文件提取后,將該文件再燒錄到空白芯片中,驗證空白芯片是否能正常工作。若能正常工作,則說明所有的程序內(nèi)容都有效的被提取完成。本階段獲得二進制代碼文件。
反匯編階段,使用IDA Pro軟件,將二進制代碼文件轉(zhuǎn)換為ARM指令集的匯編語言。轉(zhuǎn)換完成后,查看匯編代碼的結(jié)束位置是否為二進制文件的結(jié)束位置。若不是,則說明有無法反匯編的二進制數(shù)據(jù)。這些數(shù)據(jù)通常是靜態(tài)存儲的數(shù)組或配置文件,應(yīng)單獨保存。本階段獲得DCU的匯編代碼。
在軟件框架分析階段,根據(jù)上述對ARM7TDMI架構(gòu)的分析,可以直接從匯編語句中分析出每個子函數(shù)的匯編代碼起止位置、調(diào)用關(guān)系、輸入?yún)?shù)、返回值,還可以找到DCU的中斷響應(yīng)函數(shù)、主函數(shù)。本階段獲得DCU的軟件總體框架。
類C代碼轉(zhuǎn)換,是指將匯編代碼逐行轉(zhuǎn)換為類C代碼的操作。由于匯編代碼中的全局變量和外設(shè)寄存器全部用物理地址表示,而局部變量則用通用寄存器表示,在沒有分析具體功能之前,只能在類C代碼中沿用地址和通用寄存器,類C代碼將以C語言的形式表示每個子函數(shù)的代碼結(jié)構(gòu)。本階段獲得類C代碼文件。
子函數(shù)與變量逆向,是根據(jù)類C代碼分別逆向解析各個函數(shù)和變量的功能及含義。本階段獲得全局變量與函數(shù)功能表。
通信協(xié)議分析,是基于函數(shù)和變量分析結(jié)果從總體上分析DCU的通信協(xié)議,以在功能驗證階段通過模擬各種操作指令驗證DCU的逆向解析結(jié)果是否符合預(yù)期。
3 函數(shù)及變量逆向分析方法
針對不同的情況,采用函數(shù)及變量逆向分析方法,如圖4所示。
3.1 中斷響應(yīng)函數(shù)上下文分析法
在軟件框架分析階段,可以在匯編代碼中找到中斷響應(yīng)函數(shù),再對該函數(shù)進行上下文分析,解析出相關(guān)的函數(shù)和變量。
以定時器中斷函數(shù)為例,圖5為反匯編階段得到的匯編源碼。查看最后一行,結(jié)合上述分析,可以確認sub_158函數(shù)是一個中斷響應(yīng)函數(shù)。由于中斷響應(yīng)函數(shù)必然有其相關(guān)聯(lián)的配置,因此在匯編代碼中搜索所有sub_158的調(diào)用位置,在sub_5320函數(shù)中找到了相關(guān)的配置代碼,匯編源碼及類C代碼如圖6所示。
可以看到,VICVectAddr4寄存器賦值為sub_158函數(shù)的地址,結(jié)合該部分代碼上下文所使用的寄存器,如T1MR0和T1MCR,可以得到:sub_5320為Timer1的初始化配置函數(shù),sub_158為Timer1的中斷響應(yīng)函數(shù),且Timer1的定時時間為2ms。得到定時時間后,進一步分析sub_158內(nèi)的調(diào)用函數(shù),可以逆向解析出更多信息。
3.2 電路功能反向分析方法
通過對電路功能的理解,可以反向解析出軟件的含義。
如圖7所示,溫度傳感器芯片為LM20BIM7,輸出模擬信號,輸出引腳直接連接到MCU的P0.29。因此可以判斷P0.29必然配置為ADC采用的AIN2功能。在類C代碼中查找ADCR寄存器的配置,發(fā)現(xiàn)在sub_4D88中,ADCR寄存器配置為0x210307。因此,sub_4D88必然為ADC的配置函數(shù),且可以看到DCU共配置了AIN0/1/2三個ADC輸入。
由于在ARM7TDMI中讀取ADC的值,必然會使用ADDR寄存器,因此在類C代碼中查找讀取ADDR0/1/2寄存器的函數(shù),可以看到是在sub_5E88函數(shù)中讀取了ADDR寄存器(見圖8)。
由此得到sub_5E88函數(shù)為ADC讀取函數(shù),且地址0x40000014、0x40000016、0x40000018分別為保存ADC結(jié)果的全局變量。
3.3 寄存器分析法
通過類C代碼中對外設(shè)寄存器的讀取和配置,可以分析出部分初始化函數(shù)和變量信息。以串口配置為例,在類C代碼中,有對寄存器的直接讀寫操作,分析函數(shù)或變量與寄存器的關(guān)系,可以分析出其含義。
以圖9中串口配置為例,按上述電路功能反向分析方法可知sub_501C為串口配置函數(shù)。在sub_501C中有switch語句,根據(jù)0x4000003F的值,配置U0THR和U1THR寄存器為不同的值。UxTHR寄存器是波特率配置寄存器,則變量0x4000003F中保存的必然是波特率配置參數(shù)。同時,由于DCU采用switch語句,可知DCU只支持switch語句中4種case的波特率,即9600bps、19200bps、38400bps、115200bps,且DCU的默認配置為9600bps(default語句)。
3.4 變量賦值與使用分析法
部分全局變量沒有與寄存器直接關(guān)聯(lián),也無法通過電路反向解析獲得,但變量只要有賦值和使用,就可以根據(jù)變量賦值和使用的上下文信息解析其功能。
以串口數(shù)據(jù)包超時參數(shù)(0x40000D94)為例,0x40000D94只在兩個函數(shù)中賦值或使用。其中,在串口接收處理函數(shù)sub_A48中,有如圖10所示的清零操作。
函數(shù)sub_A48的輸入?yún)?shù)為Uart0/1接收數(shù)據(jù)結(jié)構(gòu)體,根據(jù)采用其他方法解析的結(jié)果,地址a+0xA表示Uart0/1已接收到的一幀數(shù)據(jù)包的長度。通過類C代碼可以看到,當已接收到的長度>0時,0x40000D94變量清零,0x40000D90變量置為1。結(jié)合其他分析方法,可知0x40000D90變量的含義為串口新數(shù)據(jù)到達標志。
另一處使用0x40000D94變量的函數(shù)為定時2ms處理函數(shù)sub_6FD8(見圖11)。
在sub_6FD8中,0x40000D98變量在初始化時被賦值為0x28,之后沒有其他操作。分析sub_6FD8中的邏輯,當0x40000D90為1時,說明串口收到新的數(shù)據(jù),此時0x40000D94開始每隔2ms自加1,直到0x40000D94的值到達0x40000D98,則收到的數(shù)據(jù)包全部清除。此時,若串口又收到了新數(shù)據(jù),則會調(diào)用sub_A48,0x40000D94變量清零。通過以上線索可以理解,0x40000D94為數(shù)據(jù)包超時檢測變量,當串口收到一次新數(shù)據(jù)后,在定時處理中開始計時,超過80ms后認為數(shù)據(jù)包超時,則之前收到的數(shù)據(jù)包無效。
3.5 正向代碼對比分析法
盡管不同的編譯器對同樣的C代碼編譯結(jié)果可能稍有差異,但ARM7TDMI芯片的啟動代碼通常為一段匯編程序,大多數(shù)的IDE工具都提供了芯片的模板啟動代碼。本文使用keil uVision軟件提供的startup.s文件與二進制反匯編代碼進行對比分析,可以得到DCU項目的各地址空間分配配置。
反匯編代碼的起始階段代碼如圖12所示,可以看到,在ROM地址0x00000000處,即上電后第一條指令是跳轉(zhuǎn)到loc_58位置。而圖13所示為正向代碼的第一條指令,對比可知,loc_58為Reset_Addr,loc_40為Undef_ Addr,loc_44為SWI_Addr,loc_48為PAbt_Addr,loc_4C為DAbt_Addr。
進一步對比loc_58的配置(見圖14),正向代碼與反匯編代碼非常接近,但具體配置參數(shù)不同,直接對比分析,可以得到:DCU的Stack_Top為0x40003608,用戶模式堆棧空間大小為0x400,管理模式堆??臻g大小為0x200,IRQ模式堆??臻g大小為0x400,F(xiàn)IQ模式堆??臻g大小為0x8,中止模式堆??臻g大小為0x8,未定義模式堆??臻g大小為0x8。
此外,對比最后的代碼,可以發(fā)現(xiàn),sub_5BB4即為main函數(shù)。
4 分析結(jié)果
1)全局變量解析結(jié)果
DCU代碼中,部分使用的全局變量解析結(jié)果如表3所示。
2)函數(shù)解析結(jié)果
DCU中部分函數(shù)的解析結(jié)果如表4所示。
3)通信協(xié)議解析結(jié)果
數(shù)據(jù)幀格式如表5所示;地面模式協(xié)議如表6所示;飛行模式通信協(xié)議如表7所示。
5 結(jié)論
本文闡述了一種基于ARM7TDMI架構(gòu)的嵌入式軟件二進制逆向流程和方法,根據(jù)ARM7TDMI架構(gòu)與ARM指令集的特點以及數(shù)據(jù)采集器軟硬件的功能特性,全面解析軟件的全部子函數(shù)功能和全局變量含義,這對于充分吸收、學習數(shù)據(jù)采集器和發(fā)動機控制相關(guān)技術(shù)有重要參考價值。
受限于DCU嵌入式軟件中提供的線索,部分變量只有賦值信息,沒有被使用,因此采用本文的方法不能逆向分析這些變量的含義。此外,F(xiàn)lash中存儲的內(nèi)容只有有限的幾幀數(shù)據(jù)可以采用本文的方法解析出,這也是本文方法的不足之處。盡管如此,這些沒有解析出來的變量或數(shù)據(jù)并不會從根本上影響DCU的功能分析,從逆向解析結(jié)果可以看到,本文的方法可以解析出全部的子函數(shù)和全局變量的含義。下一步的工作將基于上述分析結(jié)果,對軟件進行正向還原,為后續(xù)數(shù)據(jù)采集器國產(chǎn)化正向開發(fā)提供參考。
參考文獻
[1] 蔣烈輝. 固件代碼逆向分析關(guān)鍵技術(shù)研究[D]. 鄭州:解放軍信息工程大學,2007.
[2] 趙亞新,郭玉東,舒輝. 基于JTAG的嵌入式設(shè)備固件分析技術(shù)[J].計算機工程與設(shè)計,2014,35(10).
[3] 周麗娜. ARM反編譯中的類型分析技術(shù)研究[D]. 鄭州:解放軍信息工程大學,2010.
[4] 井靖,何紅旗,司彬彬,等.嵌入式軟件逆向分析中的動靜態(tài)分析交互機制[J].信息工程大學學報,2015,16(5).
[5] 鮑慶國. 嵌入式設(shè)備固件分析的關(guān)鍵技術(shù)研究[D]. 北京:北京工業(yè)大學,2016.