0x6.so逆向深化及IDA靜態(tài)分析-1

so逆向深化及IDA靜態(tài)分析-1 :  反匯編之ARM指令介紹


本文介紹部分常用ARM指令,偏理論介紹,初學(xué)者僅做了解,后續(xù)會(huì)有實(shí)戰(zhàn)分析,先上框架圖:

基礎(chǔ)篇中曾給大家提供ARM指令集,方便查閱,未下載的請(qǐng)從本文附件下載。
接下來(lái)介紹四類常用的指令,分別是 跳轉(zhuǎn)指令、數(shù)據(jù)處理指令、加載/存儲(chǔ)指令、移位指令

0x1.跳轉(zhuǎn)指令
跳轉(zhuǎn)指令用于實(shí)現(xiàn)程序流程的跳轉(zhuǎn),不僅在逆向分析中常用到,而且在逆向修改中也常用來(lái)實(shí)現(xiàn)某些程序或流程的繞過。

1.1  B指令
  B指令的格式為:  B{條件}      <地址>
  B指令是最簡(jiǎn)單的跳轉(zhuǎn)指令。一旦遇到一個(gè)B指令,ARM處理器將立即跳轉(zhuǎn)到給定的目標(biāo)地址,從那里繼續(xù)執(zhí)行。
  例:
  B   Label_1234 ;     程序無(wú)條件跳轉(zhuǎn)到標(biāo)號(hào)Label處執(zhí)行

1.2  BL指令
  BL指令格式為:   BL{條件}      <地址>
  BL在跳轉(zhuǎn)之前,會(huì)在寄存器R14中保存PC寄存器的內(nèi)容。
  簡(jiǎn)言之,當(dāng)跳轉(zhuǎn)后的指令執(zhí)行結(jié)束后,可通過將R14中的內(nèi)容重新加載到PC寄存器來(lái)實(shí)現(xiàn)返回跳轉(zhuǎn)指令后的那個(gè)指令處執(zhí)行。
  也就相當(dāng)于在指令執(zhí)行過程中實(shí)現(xiàn)了一個(gè)子程序調(diào)用。
  例: 
  MOV   R0, R1
  BL       Label_1234
  MOV   R0, R2
  上述指令首先實(shí)現(xiàn)了R1中的內(nèi)容轉(zhuǎn)移給R0,之后跳轉(zhuǎn)到Label_1234,在Label_1234執(zhí)行完畢后,會(huì)返回執(zhí)行MOV  R0, R2。

1.3  BEQ指令、BNE指令
  BEQ和BNE是條件跳轉(zhuǎn),也就是上面我們指令格式 "B{條件}      <地址>"中的“{條件}”,在smali和il中也有類似的指令,此處不再贅述。

0x2.數(shù)據(jù)處理指令
數(shù)據(jù)處理指令可分為數(shù)據(jù)傳送指令、算術(shù)/邏輯運(yùn)算指令、比較指令等。
- 數(shù)據(jù)傳送指令用于在寄存器和存儲(chǔ)器之間進(jìn)行數(shù)據(jù)的雙向傳輸。
- 算術(shù)邏輯運(yùn)算指令完成常用的算術(shù)與邏輯的運(yùn)算,該類指令不但將運(yùn)算結(jié)果保存在目的寄存器中,同時(shí)更新CPSR中的相應(yīng)條件標(biāo)志位。
- 比較指令不保存運(yùn)算結(jié)果,只更新CPSR中相應(yīng)的條件標(biāo)志位。
【 首先來(lái)解釋一下CPSR( 程序狀態(tài)寄存器current program status register)中的條件標(biāo)志位,比如在BEQ中,EQ即條件標(biāo)志。
     也就是說(shuō)CPSR中存儲(chǔ)的是譬如大于、小于、等于、不等于之類的條件標(biāo)志,作為后續(xù)執(zhí)行跳轉(zhuǎn)的判斷條件?!?/span>

2.1  MOV指令
  MOV指令常見格式為:  MOV{條件} 目的寄存器,源操作數(shù)
  MOV指令可完成從另一個(gè)寄存器、被移位的寄存器或?qū)⒁粋€(gè)立即數(shù)加載到目的寄存器。
  例:
  MOV  R1, R0   ;將寄存器R0的值傳送到寄存器R1

2.2  CMP指令
  CMP指令格式為: CMP{條件} 操作數(shù)1,操作數(shù)2
  CMP指令用于把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行比較,同時(shí)更新CPSR中條件標(biāo)志位的值。。
  例:
  CMP  R1, #100  ;將寄存器R1的值與立即數(shù)100相減,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位

2.3  ADD指令、SUB指令、MUL指令

  2.3.1  ADD指令
    ADD指令常用格式為: ADD{條件} 目的寄存器,操作數(shù)1,操作數(shù)2
    ADD指令用于把兩個(gè)操作數(shù)相加,并將結(jié)果存放到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。
    例:
    ADD   R0, R1, R2           ; R0 = R1 + R2
    ADD   R0, R1, #123        ; R0 = R1 + 123

  2.3.2  SUB指令
    SUB指令常用格式為: SUB{條件} 目的寄存器,操作數(shù)1,操作數(shù)2
    SUB指令用于把操作數(shù)1減去操作數(shù)2,并將結(jié)果存放到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。
    例:
    SUB   R0, R1, R2           ; R0 = R1 - R2
    SUB   R0, R1, #123        ; R0 = R1 - 123 

  2.3.3  MUL指令
    MUL指令常用格式為: MUL{條件} 目的寄存器,操作數(shù)1,操作數(shù)2
    MUL指令完成將操作數(shù)1與操作數(shù)2的乘法運(yùn)算,并把結(jié)果放置到目的寄存器中,同時(shí)可以根據(jù)運(yùn)算結(jié)果設(shè)置CPSR中相應(yīng)的條件標(biāo)志位。
    例:
    MUL  R0, R1, R2      ;R0 = R1 × R2 

2.4  AND指令、ORR指令、EOR指令

  2.4.1  AND指令
    AND指令常用格式為: AND{條件} 目的寄存器,操作數(shù)1,操作數(shù)2
    AND指令用于在兩個(gè)操作數(shù)上進(jìn)行邏輯與運(yùn)算,并把結(jié)果放置到目的寄存器中。
   操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。
   例:
    AND   R0, R0, #3           ; 該指令保持R0的0、1位,其余位清零。

  2.4.2  ORR指令
    ORR指令常用格式為: ORR{條件} 目的寄存器,操作數(shù)1,操作數(shù)2
   ORR指令用于在兩個(gè)操作數(shù)上進(jìn)行邏輯或運(yùn)算,并把結(jié)果放置到目的寄存器中。
   操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。
   例:
   ORR   R0, R0, #3           ; 該指令設(shè)置R0的0、1位,其余位保持不變。

  2.4.3  EOR指令
    EOR指令常用格式為: EOR{條件} 目的寄存器,操作數(shù)1,操作數(shù)2
   EOR指令用于在兩個(gè)操作數(shù)上進(jìn)行邏輯異或運(yùn)算,并把結(jié)果放置到目的寄存器中。
   操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。
   例:
   EOR   R0, R0, #3          ; 該指令反轉(zhuǎn)R0的0、1位,其余位保持不變。

0x3.加載/存儲(chǔ)指令
ARM微處理器支持加載/存儲(chǔ)指令用于在寄存器和存儲(chǔ)器之間傳送數(shù)據(jù),加載指令用于將存儲(chǔ)器中的數(shù)據(jù)傳送到寄存器,存儲(chǔ)指令則完成相反的操作。

3.1  LDR指令
LDR指令格式為: LDR{條件} 目的寄存器,<存儲(chǔ)器地址>
LDR指令用于從存儲(chǔ)器中將一個(gè)32位的字?jǐn)?shù)據(jù)傳送到目的寄存器中。
例:
LDR   R0, [R1]                  ;將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入寄存器R0。
LDR   R0, [R1, R2]           ;將存儲(chǔ)器地址為R1+R2的字?jǐn)?shù)據(jù)讀入寄存器R0。
LDR   R0, [R1, #3]          ;將存儲(chǔ)器地址為R1+3的字?jǐn)?shù)據(jù)讀入寄存器R0。

3.2  STR指令
STR指令格式為: STR{條件} 源寄存器,<存儲(chǔ)器地址>
STR指令用于從源寄存器中將一個(gè)32位的字?jǐn)?shù)據(jù)傳送到存儲(chǔ)器中。
例:
STR  R0, [R1], #8         ;將R0中的字?jǐn)?shù)據(jù)寫入以R1為地址的存儲(chǔ)器中,并將新地址R1+8寫入R1。
STR  R0, [R1, #8]         ;將R0中的字?jǐn)?shù)據(jù)寫入以R1+8為地址的存儲(chǔ)器中。

0x4.移位指令
ARM微處理器內(nèi)嵌的桶型移位器(Barrel Shifter),支持?jǐn)?shù)據(jù)的各種移位操作。
移位操作在ARM指令集中不作為單獨(dú)的指令使用,它只能作為指令格式中是一個(gè)字段,在匯編語(yǔ)言中表示為指令中的選項(xiàng)。

4.1  LSL指令、ASL指令
LSL(或ASL)操作格式為: 通用寄存器,LSL(或ASL) 操作數(shù)     
LSL(或ASL)可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行邏輯(或算術(shù))的左移操作,按操作數(shù)所指定的數(shù)量向左移位,低位用零來(lái)填充。
例:
MOV    R0, R1, LSL#2          ;將R1中的內(nèi)容左移兩位后傳送到R0中。

4.2  LSR指令
LSR操作格式為: 通用寄存器,LSR 操作數(shù)     
LSR可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行右移的操作,按操作數(shù)所指定的數(shù)量向右移位,左端用零來(lái)填充。
例:
MOV    R0, R1, LSR#2         ;將R1中的內(nèi)容右移兩位后傳送到R0中,左端用零來(lái)填充。

4.3  ASR指令
ASR操作格式為: 通用寄存器,ASR 操作數(shù)     
ASR可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行右移的操作,按操作數(shù)所指定的數(shù)量向右移位,左端用第31位的值來(lái)填充。
例:
MOV    R0, R1, ASR#2        ;將R1中的內(nèi)容右移兩位后傳送到R0中,左端用第31位的值來(lái)填充。 

?