1. 程式人生 > >Android 圖解逆向工程中ARM常用匯編指令(一)

Android 圖解逆向工程中ARM常用匯編指令(一)

我們走得太快,靈魂都跟不上了。
微小的幸福就在身邊,容易滿足就是天堂。


在逆向和爆破中我們經常會在IDA中接觸到彙編,一般做安卓的不會太瞭解VB回編等,不太瞭解的同學可以先檢視上篇文章《Android ARM常用的彙編指令合集》 再來繼續我們的學習,我們先來看張圖。

深圳市米奇雲科技奧特曼超人杜錦陽

這個view裡面有 PUSH/LDR/SUB/MOVS/BLX/SUBS/BEQ/CMP ,這些差不多都是常見的,不過也不需要看得懂,理解這個指令即可,接下來我們就來分析下這些指令分別有什麼作用吧。

先引入 概念性 東西,免得大家後面被搞混,那就是為什麼會有S和!

  • S:指令執行後程序狀態暫存器的條件標誌位將被重新整理 , 如ADDS R1,R0,#2
  • ! :指令中的地址表示式中含有!字尾時,指令執行後,基址暫存器中的地址值將發生變化,變化的結果是:基址暫存器中的值(指令執行後)=指令執行前的值 + 地址偏移量,如 LDR R3,[R0,#2]! 指令執行後,R0 = R0 + 2

接下來分別講解這個View裡面的指令分別有什麼作用。

PUSH,顧名思義,直接PUSH進棧了。相反的,POP則為出棧了。

 指令示例:

  • PUSH{cond} reglist PUSH將暫存器推入滿遞減堆疊
  • PUSH {r0,r4-r7} 將R0,R4-R7暫存器內容壓入堆疊
  • POP{cond} reglist POP從滿遞減堆疊中彈出資料到暫存器
  • POP {r0,r4-r7} 將R0,R4-R7暫存器從堆疊中彈出

LDR,指令語法:LDR{條件} 目的暫存器,<儲存器地址>,LDR指令用於從儲存器中將一個32位的字資料傳送到目的暫存器中。該指令通常用於從儲存器中讀取32位的字資料到通用暫存器,然後對資料進行處理,當程式計數器PC作為 目的暫存器時,指令從儲存器中讀取的字資料被當作目的地址,從而可以實現程式流程的跳轉。該指令在程式設計 中比較常用,且定址方式靈活多樣。
  詳情可見上篇文章中 Ctrl + F 搜尋《Android ARM常用的彙編指令合集》:載入/儲存指令

 指令示例:

  • LDR R0,[R1] ;將儲存器地址為R1的字資料讀入暫存器R0。
  • LDR R0,[R1,R2] ;將儲存器地址為R1+R2的字資料讀入暫存器R0。

MOVS 、LDR 這些是跳轉指令,直接向程式計數器PC寫入跳轉地址值,通過向程式計數器PC寫入跳轉地址值,可以實現在4GB的地址空間中的任意跳轉,那有人會問,如果說從當前指令向前或向後的32MB的地址空間的跳轉是怎麼個實現原理?其實在 上篇文章中提及到了,它們是B\BL\BLX\BX 四大指令,這個我們最後才來講解,其實它們有點像我們常說的分支結構,我們從圖片裡面選第四條指令作為檢視資料。

深圳市米奇雲科技奧特曼超人杜錦陽

則可以看到,R5是原地址,其實為0xFF8->0x104A,複製返回地址到PC,實現子的返回,做安卓的同學可能會有個疑問,為什麼有個S,因為語法就是 MOV{條件}{S} 目的暫存器+源運算元

看到這裡大家可能會頭暈,怎麼感覺都是看不懂的數字,那其它那些,如ADD、等就給大家整理了一份表格。

助記符 指令功能描述 助記符 指令功能描述
ADD 加法指令 MRS 傳送CPSR或SPSR的內容到通用暫存器指令
ADC 帶進位加法指令 MRC 從協處理器暫存器到ARM暫存器的資料傳輸指令
AND 邏輯與指令 MSR 傳送通用暫存器到CPSR或SPSR的指令
B 分支指令 MUL 32位乘法指令
BL 帶返回的分支指令 BIC 位清零指令
BLX 帶返回和狀態切換的分支指令 MLA 32位乘加指令
BX 帶狀態切換的分支指令 MVN 資料取反傳送指令
TST 位測試指令 ORR 邏輯或指令
CDP 協處理器資料操作指令 RSC 帶錯位的逆向減法指令
RSB 逆向減法指令 SBC 帶錯位減法指令
CMN 比較反值指令 CMP 比較指令
STC 協處理器暫存器寫入儲存器指令 EOR 異或指令
STM 批量記憶體字寫入指令 LDC 儲存器到協處理器的資料傳輸指令
STR 暫存器到儲存器的資料儲存指令 LDM 載入多個暫存器指令
SUB 減法指令 LDR 儲存器到暫存器的資料載入指令
SWI 軟體中斷指令 MCR 從ARM暫存器到協處理器暫存器的資料傳輸指令
TEQ 相等測試指令 MOV 資料傳送指令



SUBS 從表中可以看到,SUB是減法指令,如SUB R0,R1,R2則對應了R0 = R1 - R2,SUB R0,R1,#1 則是R0 = R1 -1,要注意的是 SUBS 是低32位相減。

BEQ 呢?!不要著急,來看下圖
奧特曼超人杜錦陽

BEQ 指令是跳轉指令,但是跳轉要滿足一定的條件,滿足則跳轉執行,看下圖紅框部分。

奧特曼超人杜錦陽

那就只剩下 CMP 了,CMP是比較指令,指令格式:CMP{條件} 運算元1,運算元2

 指令示例:

  • 如 CMP R1,#10,則等於比較R1和10,並設定CPSR的標誌位。
  • CMP R1,R0 ;將暫存器R1的值與暫存器R0的值相減,並根據 結果設定CPSR的標誌位
  • CMP R1,#100 ;將暫存器R1的值與立即數100相減,並根 據結果設定CPSR的標誌位
  • 如果和BEQ一起使用話則是:CMP R1,#0 換行 BEQ Label ;當CPSR暫存器中的Z條件碼置位時,程式跳轉到標號Label處執行

OK , 從第一張圖中我們看到後面跟的是兩位,那如果是複雜一點的兩位以上怎麼看

 指令示例:

  • 先來看MOV的,如MOV R0,R1 , LSL R3 ,這個又是何解?其實它是將R1的值左移R3位,然後將結果存放到R0中 。
  • 再來看LDR的,LDR R0,[R1],R2 ,這個何解? 它是將儲存器地址為R1的字資料讀入暫存器R0,並將新地址R1+R2寫入R1 , 要記住,R1是最終落地的地址 。

上篇文章中提及了其它更復雜的指令示例,不太明白這些可以看上篇文章的《Android ARM常用的彙編指令合集》,然後Ctrl + F 搜:資料載入/儲存指令 或者搜尋 資料處理指令,又或者搜尋 自己需要的指令