so逆向深化及IDA靜態(tài)分析-1 :
反匯編之ARM指令介紹
本文介紹部分常用ARM指令,偏理論介紹,初學(xué)者僅做了解,后續(xù)會(huì)有實(shí)戰(zhàn)分析,先上框架圖:
基礎(chǔ)篇中曾給大家提供ARM指令集,方便查閱,未下載的請(qǐng)從本文附件下載。
接下來介紹四類常用的指令,分別是 跳轉(zhuǎn)指令、數(shù)據(jù)處理指令、加載/存儲(chǔ)指令、移位指令。
0x1.跳轉(zhuǎn)指令
跳轉(zhuǎn)指令用于實(shí)現(xiàn)程序流程的跳轉(zhuǎn),不僅在逆向分析中常用到,而且在逆向修改中也常用來實(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 ; 程序無條件跳轉(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寄存器來實(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)志位。
【 首先來解釋一下CPSR(
程序狀態(tài)寄存器current program status register)中的條件標(biāo)志位,比如在BEQ中,EQ即條件標(biāo)志。
也就是說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è)字段,在匯編語言中表示為指令中的選項(xiàng)。
4.1 LSL指令、ASL指令
LSL(或ASL)操作格式為: 通用寄存器,LSL(或ASL) 操作數(shù)
LSL(或ASL)可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行邏輯(或算術(shù))的左移操作,按操作數(shù)所指定的數(shù)量向左移位,低位用零來填充。
例:
MOV R0, R1, LSL#2 ;將R1中的內(nèi)容左移兩位后傳送到R0中。
4.2 LSR指令
LSR操作格式為: 通用寄存器,LSR 操作數(shù)
LSR可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行右移的操作,按操作數(shù)所指定的數(shù)量向右移位,左端用零來填充。
例:
MOV R0, R1, LSR#2 ;將R1中的內(nèi)容右移兩位后傳送到R0中,左端用零來填充。
4.3 ASR指令
ASR操作格式為: 通用寄存器,ASR 操作數(shù)
ASR可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行右移的操作,按操作數(shù)所指定的數(shù)量向右移位,左端用第31位的值來填充。
例:
MOV R0, R1, ASR#2 ;將R1中的內(nèi)容右移兩位后傳送到R0中,左端用第31位的值來填充。