STM32 & RT-Thread的逆向入門


STM32 & RT-Thread的逆向入門

backahasten@0xFA

​                現在,各種MCU的價格越來越低,同等條件下能買到的ROM和RAM資源也多了。對一些復雜邏輯的應用,相比於花費大量的時間去扣底層還不如使用操作系統加快開發速度,使用了操作系統之后,針對固件的逆向會比無os的固件逆向有一些不同。

​                RT-Thread是國產實時操作系統的典范,我個人的特別喜歡。RT-Thread有很多的BSP可以適配眾多的芯片和架構,在本文還是使用最常見的stm32來進行介紹。

​                硬件上我是用了正點原子核RT-Thread聯合開發的潘多拉開發板,在本文中沒有使用潘多拉的硬件,我比較偷懶的使用了開發板配套的例子去做逆向。

啟動

​                我一直相信一句話,不會開發也就不會安全,開發能力決定着安全能力的天花板。在逆向STM32 & RT-Thread的過程中也是這個樣子的。我們打開一個bin文件,第一件事就是找到main函數,這個main函數並不是stm32的main函數而是操作系統的main函數。例如在stm32 & keil開發中,RT-Thread使用$Sub$$main調用初始化操作系統,如果是不帶操作系統的裸開發,這個函數就是邏輯的main函數了。

​                詳細的啟動過程可以在https://www.rt-thread.org/document/site/tutorial/quick-start/stm32f103-simulator/stm32f103-simulator/中找到,為了本文的完整,我們復制過來一些代碼。

//components.c 中定義 /* re-define main function */ int $Sub$$main(void) {     rt_hw_interrupt_disable();     rtthread_startup();     return 0; }

這里面調用了兩個函數,第一個函數關閉了中斷,開始初始化操作系統。

int rtthread_startup(void) {     rt_hw_interrupt_disable();     /* board level initalization      * NOTE: please initialize heap inside board initialization.      */     rt_hw_board_init();     /* show RT-Thread version */     rt_show_version();     /* timer system initialization */     rt_system_timer_init();     /* scheduler system initialization */     rt_system_scheduler_init(); #ifdef RT_USING_SIGNALS     /* signal system initialization */     rt_system_signal_init(); #endif     /* create init_thread */     rt_application_init();     /* timer thread initialization */     rt_system_timer_thread_init();     /* idle thread initialization */     rt_thread_idle_init();     /* start scheduler */     rt_system_scheduler_start();     /* never reach here */     return 0; }

rtthread_startup();函數中,進行各個組件的初始化,其他我們不用管,重點看其中的rt_application_init();函數,這個函數用於線程任務的初始化,在其中,我們就可以脫離操作系統代碼的范疇,進入到真正的邏輯代碼的位置。

操作

​                我們使用潘多拉開發板的例子29_iot_web_server,這個例子復雜程度中等,可以充分的分析各個點。keil編譯之后,會的帶axf文件和Hex文件,其中axf帶有符號表,而hex文件只有基礎的組織結構,由於嵌入式的特點,為了節約資源,燒錄進芯片里的固件基本都不會帶符號表。為了仿造真實情況下拿到的固件,我們使用jlink的工具打開hex文件之后保存成bin文件。之后使用ida pro打開。

​                打開文件之后,正確載入逆向,顯示如下:(使用IDA PRO逆向ARM M核心的方法請參考我之前的文章

 

選中的地址 0x8000495為芯片的上電PC載入地址,找到地址之后,如下:

 

由於最開始是硬件PC設置,沒有軟件引用關系,ida pro沒有識別,在0x8000494處按C,進行反匯編:

 

發現可以看到stm32的啟動代碼,進入函數0x800188:

 

發現0x800018C處的函數沒有識別,依舊按C:

 

發現識別出來一個函數的跳轉,繼續跟蹤,進入:

 

發現有四個函數,具體函數的意義是什么,沒有符號表不得而知。

這里介紹一個小技巧,我們現在處於上帝模式,我們有axf文件,axf文件中有符號表,並且,這一段程序在操作系統中,所有的stm32都是一樣的,我們現在反匯編axf文件,與bin文件互相參照,可以更好的分析啟動過程。打開axf文件,找到位置:

 

選中的函數,也就是第二個函數,是有關操作系統線程的設置,選擇進入:

 

發現又是一堆函數,我們依舊參考axf文件:

 

第六個函數跳轉是任務的設置,選擇進入:

 

在這里我們可以發現任務main函數的設置,進入函數0x802485C


還有兩個函數,參考一下axf: 

 

上面的是任務進入的設置,下面是main函數的邏輯,進入main函數:

 

按F5轉變成偽代碼:

 

這就是任務main函數的邏輯,接下來就可以進行下一步的分析了。

實際上,還有另外一個方法,直接搜索字符串main:

 

同樣可以找到main函數的位置。但是由於任務名稱可能修改,從啟動代碼 逐步分析是最可靠的方法。

沒有符號表依然很難受,我在那篇文章中也介紹了恢復符號表的方法,有需要大家可以參考。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM