本文默認讀者已安裝所有必要工具,如果還不熟悉,建議先參考以下文章:
Ghidra 逆向實戰|STM32(ARM) MCU 韌體逆向工程 : 工具說明本實做將以 STM32H7A3 系列微控制器為範例,示範如何在 Ghidra 中進行無符號表(Symbol-less)韌體靜態分析,方法不分先後,依照實際需求與情況選擇適合的步驟進行。這些方法可協助使用者在缺乏符號表的情況下,仍能有效地進行韌體分析。
注意事項:
在韌體中,字串常數(如 ASCII 或 Unicode 格式)常見於除錯訊息、錯誤提示、人機介面標示等。若編譯時未移除這些資訊,便能在韌體中直接找到相關字串。
這些字串對逆向工程極為有用,不僅能協助判斷韌體所用的架構或函式庫,還能快速定位程式碼中調用這些字串的位置,是分析流程的重要切入點。
Window → Defined Strings
功能,快速檢視與搜尋所有字串常數,並追蹤其被調用的程式區段。
在韌體中,啟動入口(如 Reset_Handler
)與 中斷向量表
是韌體執行的起點。這些區域通常包含初始化程式碼、系統設定與中斷處理程式等。而這些位置的程式碼通常會在韌體啟動時被執行,因此可以作為分析的起點。
不同架構中斷向量表的位置與格式可能有所不同,但通常會包含一系列的函式指標,指向各種中斷服務程式(ISR)或系統呼叫。在 ARM Cortex-M 架構中,中斷向量表規定位於韌體開頭(例如 STM32 通常從 0x08000000 開始,這是由於重定向和偏移),格式如下:
Offset 內容
0x00 初始堆疊指標(Initial Stack Pointer)
0x04 Reset_Handler(重設處理函式)
0x08 NMI_Handler(不可屏蔽中斷)
0x0C HardFault_Handler
0x10 MemManage_Handler
0x14 BusFault_Handler
0x18 UsageFault_Handler
... 其他中斷服務程式(ISR)指標
這些指標實際上是函式位址,Ghidra 可自動辨識並標註為函式。啟動時便是從 Reset_Handler
開始,追蹤其初始化流程與主程式流向。
附註:
Reset_Handler
、SVC
、PendSV
、SysTick
,因為這些 ISR
服務被用於 RTOS 的上下文切換、排程與任務。
在 Ghidra 逆向韌體時,標記 ISR(中斷服務函數)是分析的重要一步,以下以 STM32/ARM MCU 為例,說明實際操作流程:
Data → Pointer
或使用快捷鍵 'p'
進行手動標記(請注意 Initial Stack Pointer 是
uint
或 dword
)。
Function → Create Function
,讓 Ghidra
將該位址標記為一個函式。
Edit Function
,輸入正確的函式名稱(如
Reset_Handler
、SysTick_Handler
等),並可加上註解說明其用途。
Window → Function Graph
或
Window → Function Call Tree
,分析其內部邏輯與呼叫關係。
Window → Symbol Tree
快速檢查所有已建立的函式,或用 Window → Defined Strings
搜尋相關字串輔助判斷。
SVC
、PendSV
、SysTick
這三個與 RTOS 核心功能高度相關的 ISR。即便沒有符號表,依然可從程式流與常數變數中進行逆向工程判斷。韌體架構主要分為 裸機(Bare-metal) 與 RTOS(即時作業系統) 兩大類型。此判斷將直接影響後續的分析策略。
main()
函式,初始化後進入明顯的大型無限迴圈(如 while(1)
)。SVC
、PendSV
、SysTick
)包含複雜控制流程,負責上下文切換與任務排程。0xE000ED04
(此位址為 ARM 架構專用的中斷控制暫存器 ICSR)觸發 PendSV
中斷,或強制「軟體內」觸發計時器等外設中斷。FreeRTOS
、RTX
、ThreadX
等關鍵字,可大概率判定 RTOS 類型。Kernel
、Thread
、task
、Queue
等關鍵字,可判定存在
RTOS。0xE000ED04 (ICSR)
(此位址為 ARM 架構專用的中斷控制暫存器)觸發
PendSV
,或強制觸發計時器等外設中斷。這些多為 RTOS 系統調用與任務切換。(這種方法還能找出 RTOS 的部分函數位址)
SVC
、PendSV
、SysTick
等 ISR
的程式流。若這些中斷服務程式包含複雜控制流程(極可能是:上下文切換、排程、系統呼叫),多半為 RTOS 架構;若未使用或邏輯簡單,則偏向裸機。
FreeRTOS
、RTX
、ThreadX
等關鍵字。這些字串通常會以常數形式存在,若發現則高度懷疑採用對應
RTOS。此外,Kernel
、Thread
、task
、Queue
這些關鍵字也可用來判斷是否存在
RTOS。
當完成基本架構分析後,利用 BinDiff 這類二進位比對工具,搭配官方 HAL 層範例程式碼 或已知韌體版本,建立「參考檔案」進行比對。
具體步驟如下:
BinExport
外掛 (BinDiff 通常是獨立工具)。File → Export Program
,選擇 BinExport
格式,匯出兩個檔案。