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