匯編指令
針對(duì)匯編來說,匯編指令是必須了解的,而且匯編中匯編指令比較多,但是每一個(gè)匯編指令對(duì)應(yīng)的機(jī)器碼是固定不變的,看下下面的匯編代碼
_A:
sub sp,sp,#0x10
mov w8,#0x1e
str w8,[sp,#0xc]
mov w9,#0xa
str w9,[sp,#0x8]
sub w0,w8,w9
add sp,sp,#0x10
ret
之前介紹逆向的時(shí)候就說過,可以通過匯編代碼反向推算高級(jí)語言,所以經(jīng)過推算后,可以得到以下C代碼:
int A(){
int a = 30;
int b = 10;
return a-b;
}
那么怎么推算的,匯編里面的指令是什么意思呢?今天我們一起去探索
sub指令
sub/subs匯編指令是進(jìn)行減法運(yùn)算指令。一般在函數(shù)內(nèi)部第一句就是sub指令,是用來開辟內(nèi)存空間。之前就說過棧空間是從高地址向低地址擴(kuò)展的,而且是一塊連續(xù)的空間,sp之前介紹寄存器的時(shí)候就說過是棧頂,所以第一條指令就是sp向低地址移動(dòng)一段距離,也就是開辟一塊??臻g。
mov指令
mov指令是數(shù)據(jù)傳輸指令,也是基本的編程指令,用于將一個(gè)數(shù)據(jù)從源地址傳送到目標(biāo)地址
str指令
str指令是寫入操作,將制定數(shù)據(jù)寫入到某個(gè)寄存器中
add指令
add指令是加法運(yùn)算指令,經(jīng)常出現(xiàn)在函數(shù)結(jié)束后返回前,因?yàn)闂?臻g是高地址向低地址擴(kuò)展的,所以??臻g使用完畢后釋放時(shí)就是將sp寄存器地址向高地址移動(dòng)
b指令
b指令是跳轉(zhuǎn)指令,在函數(shù)嵌套的時(shí)候經(jīng)常能看見,而且大多數(shù)都是bl指令。
b與bl指令的相同點(diǎn):都是跳轉(zhuǎn)指令
b與bl指令的不同點(diǎn):b指令只是單純的跳轉(zhuǎn),跳進(jìn)函數(shù)后,無法回到原來的位置,bl指令是帶有l(wèi)r寄存器地址的跳轉(zhuǎn),跳入其他函數(shù)后,可以根據(jù)lr寄存器的內(nèi)存回到之前的位置進(jìn)行下一步操作
ldr指令
ldr指令是讀取指令,從寄存器讀取內(nèi)容的指令
cmp指令
cmp指令是比較指令,其內(nèi)部就是進(jìn)行減法運(yùn)算,最后的結(jié)果收到cpsr寄存器中NZCV標(biāo)志位的影響
b.le指令
b.le指令是判斷是否大于
b.ne
b.ne指令是比較是否等于
b.ge
b.ge指令是判斷是否小于
b.lt
b.lt指令是判斷是否大于等于
b.gt
b.gt指令是判斷是否小于等于
b.ls
b.ls指令是判斷是否無符號(hào)大于
b.ne
b.ne指令是判斷是否無符號(hào)等于
b.hs
b.hs指令是判斷是否無符號(hào)小于
b.lo
b.lo指令是判斷是否無符號(hào)大于等于
b.hi
b.hi指令是判斷是否無符號(hào)小于等于
b.eq
b.gt指令是比較結(jié)果是等于,執(zhí)行標(biāo)號(hào),否則不跳轉(zhuǎn)
ubfx
ubfx指令是無符號(hào)位域提取指令,一般在一些復(fù)雜算法中容易出現(xiàn)
and
and指令是與運(yùn)算指令
orr
orr指令是或運(yùn)算指令
eor
eor指令是異或運(yùn)算指令
stp
stp指令是入棧指令
ldp
ldp指令是出棧指令
cbz
cbz指令是運(yùn)算結(jié)果如果為0進(jìn)行轉(zhuǎn)移指令
cbnz
cbnz指令是如果結(jié)果為非零就進(jìn)行轉(zhuǎn)移指令
ret
ret指令是返回指令