arm彙編傳參

開發環境:android studio 3.3
調試工具:IDA7.0

so代碼:

#include <jni.h>
#include <string>
#include <stdlib.h>
#include <stdio.h>

int GetSum(int a1,int a2) {

    int sum = a1+a2;
    return sum;
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {

    char s[12];
    memset(s,0, sizeof(s));
    int sum =  GetSum(2,5);
    sprintf(s,"%d",sum);
    return env->NewStringUTF(s);
}

arm彙編:

libnative_lib.so:AEE46872 LDR             R4, [R4]                ; __stack_chk_guard
libnative_lib.so:AEE46874 LDR.W           R12, [R4]
libnative_lib.so:AEE46878 STR.W           R12, [SP,#0x34]
libnative_lib.so:AEE4687C STR             R0, [SP,#0x24]
libnative_lib.so:AEE4687E STR             R1, [SP,#0x20]
libnative_lib.so:AEE46880 MOVS            R0, #0
libnative_lib.so:AEE46882 STR             R0, [SP,#0x2C]
libnative_lib.so:AEE46884 STR             R0, [SP,#0x28]
libnative_lib.so:AEE46886 STR             R0, [SP,#0x30]
//arm傳遞參數是使用固定寄存器r0-r3 超過使用堆棧方式傳入
//與x86彙編不一樣,x86使用的是push 傳遞參數。
libnative_lib.so:AEE46888 MOVS            R0, #2   ////傳入參數1爲常量2
libnative_lib.so:AEE4688A MOVS            R1, #5  //傳入參數2爲常量5
libnative_lib.so:AEE4688C STR             R3, [SP,#0x18]
libnative_lib.so:AEE4688E STR             R4, [SP,#0x14]
libnative_lib.so:AEE46890 STR             R2, [SP,#0x10]
libnative_lib.so:AEE46892 BLX             unk_AEE46764   //調用GetSum 方法
libnative_lib.so:AEE46896 STR             R0, [SP,#0x1C]  //R0返回值爲7
libnative_lib.so:AEE46898 LDR             R2, [SP,#0x1C]

GetSum方法:
libnative_lib.so:AEE46848 ; =============== S U B R O U T I N E =======================================
libnative_lib.so:AEE46848
libnative_lib.so:AEE46848
libnative_lib.so:AEE46848 _Z6GetSumii
libnative_lib.so:AEE46848
libnative_lib.so:AEE46848 var_14= -0x14
libnative_lib.so:AEE46848 var_10= -0x10
libnative_lib.so:AEE46848 var_C= -0xC
libnative_lib.so:AEE46848 var_8= -8
libnative_lib.so:AEE46848 var_4= -4
libnative_lib.so:AEE46848
libnative_lib.so:AEE46848 SUB             SP, SP, #0x14           ; CODE XREF: sub_AEE46764+8↑j
libnative_lib.so:AEE46848     libnative_lib.so:off_AEE49FD0↓o
libnative_lib.so:AEE4684A MOV             R2, R1
libnative_lib.so:AEE4684C MOV             R3, R0
libnative_lib.so:AEE4684E STR             R0, [SP,#0x14+var_4] //參數1值存入[SP,#0x14+var_4]中
libnative_lib.so:AEE46850 STR             R1, [SP,#0x14+var_8]//參數2值存入[SP,#0x14+var_8]中
libnative_lib.so:AEE46852 LDR             R0, [SP,#0x14+var_4]//[SP,#0x14+var_4]的值載入到寄存器R0中 值爲2
libnative_lib.so:AEE46854 LDR             R1, [SP,#0x14+var_8]//[SP,#0x14+var_8]的值載入到寄存器R1中 值爲5
libnative_lib.so:AEE46856 ADD             R0, R1  //R0+R1 = 7
libnative_lib.so:AEE46858 STR             R0, [SP,#0x14+var_C]
libnative_lib.so:AEE4685A LDR             R0, [SP,#0x14+var_C] //作爲返回值存入R0中
libnative_lib.so:AEE4685C STR             R2, [SP,#0x14+var_10]
libnative_lib.so:AEE4685E STR             R3, [SP,#0x14+var_14]
libnative_lib.so:AEE46860 ADD             SP, SP, #0x14
libnative_lib.so:AEE46862 BX              LR
libnative_lib.so:AEE46862 ; End of function _Z6GetSumii

指令解釋
R0-R3:用於函數參數及返回值的傳遞
R4-R6, R8, R10-R11: 普通的通用寄存器
R7:棧幀指針(Frame Pointer).指向前一個保存的棧幀(stack frame)和鏈接寄存器(link register, lr)在棧上的地址。
R9:操作系統保留
R12:IP(intra-procedure scratch )
R13:SP(stack pointer),是棧頂指針
R14:LR(link register),存放函數的返回地址。
R15:PC(program counter),指向當前指令地址

 

4121383-2fce54002b3dc6d1.png

IDA動態調試 ,單步跟蹤的時候,右邊的能看到每個寄存器的值。

ADD 加指令
SUB 減指令
STR 把寄存器內容存到棧上去
LDR 把棧上內容載入一寄存器中
BL 執行函數調用,並把使lr指向調用者(caller)的下一條指令,即函數的返回地址
BLX 同上,但是在ARM和thumb指令集間切換。
CMP 指令進行比較兩個操作數的大小

4121383-5767cc5ad7ee987d.png

LDR R0, [SP,#0x14+var_4]  //在例子中sp的地址值是BE9A3894  = 
R0= [BE9A3894  +0x14-4]= BE9A38A4 = 2
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章