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" // 被破坏的寄存器
);
// 现在 result 包含 add 函数的返回值
}

汇编调用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文件替换旧的,并进行对齐和签名

对齐操作

签名操作