Arm汇编
工具网站
谷歌官网:https://developer.arm.com/documentation-beta/
ARM汇编-opcode转换:http://armconverter.com
寻址方式
1、立即数寻址:mov r0,#0x1
2、寄存器寻址:mov r0
3、寄存器间接寻址:ldr r0,[r1]
4、寄存器偏移寻址:mov r0,r1,[r1,#4]
5、寄存器基址变址寻址:ldr r0,[r1,#4]
6、多寄存器寻址:ldmia r0,{r1,r2,r3,r4}
7、相对寻址:bl label
8、堆栈寻址:stmfd sp!,{r1-r7,lr}
9、块拷贝寻址:stmia r0,{r1-r7}
跳转指令
B label:直接跳,无条件,需要条件就B后面增加条件
BL:跳转之前,下一条指令地址保存到LR寄存器中,然后再调
MOV PC,LR:直接修改PC指针,实现跳转
LDR PC,0x?:和上一条一样,修改PC寄存器
传参
参数小于等于4:用r0,r1,r2,r3
大于4:多出来的用栈
内联汇编
方式
asm(“指令” :输出 :输入 :变化寄存器);
方式
asm_volatile_(
“mov r0,r1\n\t”
“mov r2,r3\n\t”
…………..
);volatile的作用是让代码不会被优化
修饰符
输出:asm->C 用于定义输出的参数,通常只能是变量
r:任何可用寄存器
m:使用变量的内存地址
+:可读可写
=:只写
&:表示该输出操作数不能使用输入部分使用过的寄存器,只能用” +& “ 或 “ =& “ 的方式使用
输入:C->asm 用于定义输入的参数,可以使用变量也可以使用立即数
r:可以使用任何可用的寄存器和立即数和变量
m:表示使用变量的内存地址
i:表示使用立即数
_volatile_:加上代表让编译器不优化
注意:可以字符串组合,但组合中间不能有回车换行
举例
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/mman.h> #include <dlfcn.h> #include <errno.h> #include <elf.h>
int add(int aa, int bb, int cc) { int ret = 0; asm("add %0, %1, %2" : "=r"(ret) : "r"(aa), "r"(bb) : "memory"); asm("add %0, %1, %2" : "+r"(ret) : "r"(ret), "r"(cc) : "memory"); return ret; }
int add2(int aa, int bb, int cc) { int ret = 0, tmp = 0; asm( "add %[bmTMP], %[bmAA], %[bmBB]\n\t" "add %[bmRET], %[bmTMP], %[bmCC]\n\t" :[bmTMP]"+r"(tmp), [bmRET]"=r"(ret) :[bmTMP]"r"(aa), [bmBB]"r"(bb),[bmCC]"r"(cc) :"memory" ); asm("mov r0, %[bmRET]" ::[bmRET]"r"(ret):"memory"); asm("mov pc, lr"); asm("mov r0, #0x11" "mov r1, #0x22" "mov r2, #0x33" "bl add" ) return ret; } int main(int argc, char** argv) { getchar(); int addRet = add(3,4,5); int addRet2 = add2(6,7,8); printf("ret:%d\n",addRet,addRet2); return addRet; }
|
C调用汇编
通常在 C 代码中嵌入汇编代码,通过内联汇编来执行特定的汇编指令
int add(int a, int b, int c);
void example() { int result; asm("mov r0, #0x11\n" "mov r1, #0x22\n" "mov r2, #0x33\n" "bl add\n" "mov %[result], r0\n" : [result] "=r" (result) : : "r0", "r1", "r2", "memory" ); }
|
汇编调用C
汇编代码可以使用 bl
指令跳转到 C 函数,传递参数通过寄存器,并执行 C 函数的逻辑。
#include <stdio.h>
void add(int a, int b, int c) { printf("Sum: %d\n", a + b + c); }
void example() { asm("mov r0, #1\n" "mov r1, #2\n" "mov r2, #3\n" "bl add\n" : : : "r0", "r1", "r2", "memory" ); }
|
修改应用ARM代码实现破解功能
android:extractNativeLibs="true"
android:extractNativeLibs="true":表示在应用安装时,APK 中的本地库(lib 目录中的 .so 文件)将被提取到设备的 /data/app/<package-name>/lib 目录中。这是 Android 系统的默认行为。在应用运行时,系统会从这个目录中加载本地库。
android:extractNativeLibs="false":表示本地库将不会被提取到设备的 /data/app/<package-name>/lib 目录中。相反,系统会直接从 APK 文件中加载本地库。这可以减少设备上存储的重复文件,但要求应用的 APK 必须是完整且没有被压缩的,以确保本地库可以从 APK 文件中直接读取。
|
IDA打开.so文件,把return 0全部修改为return 1
将修改后的so文件替换旧的,并进行对齐和签名
对齐操作
签名操作