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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值