iOS 逆向--汇编指令入门

150 阅读4分钟

一、简介

        ARM64(也称为ARMv8-A架构)是ARM处理器的64位版本,广泛用于移动设备、服务器和嵌入式系统。苹果的 iPhone 设备从 5s( 2013 年 9 月)开始支持ARM64。

二、寄存器

    1、通用寄存器 x0~x30, 可以存储整数,指针和其他数据。具体详情如下:

x0~x7通常用于传递函数参数和返回值
x8有时被称为间接结果寄存器,通常用于返回结构体之类的大数据
x29(FP)帧指针(FP),在标准调用约定中用于指向当前堆栈帧。
x30(LR)链接寄存器(LR),用于存储子程序返回地址

   2、SP: 用于指向当前方法栈的顶部

    3、PC: 总是指向即将要执行的下一条指令

    4、状态寄存器(CPSR) :用于存放运算,主要是要了解NZCV这四位

N运算结果为负数
Z运算结果为零
C运算结果产生了进位或借位
V运算结果产生了溢出

三、指令

1、运算指令

     1.1、add

        用于执行加法运算。它可以将两个寄存器的值相加,或者将寄存器的值和一个立即数相加

//将 x0和 x1 的值相加存放到 x2中add x2 x0 x1 //将 x1 和整数 10相加存放d到 x0 中add x0 x1 #10

  1.2、sub

        用于执行减法法运算。与加法操作类似

//x2 = x0 - x1sub x2 x0 x1 //x0 = x1 - 10sub x0 x1 #10

    1.3、mul

        用于两个数相乘

//x2 = x0 * x1mul x2 x0 x1 //x0 = x1 * 10mul x0 x1 #10

2、加载存储指令

2.1、mov

    用于将一个值(立即数或另一个寄存器的值)复制到目标寄存器中。

//将一个立即数加载到寄存器 x0mov x0 #1234//将x0的值复制到 x1 中mov x1 x0

2.2、ldr

    用于从内存加载数据到寄存器,有众多的变体,例如:如ldrldrbldrhldrsw等。

// 从内存地址(x1 + 8)处加载数据到寄存器x0ldr x0, [x1, #8]// 从内存地址(x1 + x2)处加载数据到寄存器x0ldr x0, [x1, x2]

2.3、str

        用于将寄存器中的数据存储到内存中。类似于ldr指令,str指令也有多种变种,用于不同大小和类型的数据存储。

//将寄存器x0中的数据存储到内存地址(x1 + 8)处str x0, [x1, #8]//将寄存器x0中的数据存储到内存地址(x1 + x2)处str x0, [x1, x2]

3、比较指令

  3.1、cmp

        用于比较两个寄存器的值。它实际上执行一个隐式的减法运算,不存储结果,只更新条件标志(flags)。这些标志(N, Z, C, V)可用于后续的条件分支指令,以决定程序的执行路径。经常与跳转指令搭配使用,例如 b.eq、b.lt、b.gt。

.global _start​_start:    mov x0, #5       //5 加载到寄存器 x0    mov x1, #10      //10 加载到寄存器 x1​    cmp x0, x1       // 比较寄存器 x0 和 x1 的值    b.eq equal_case  // 如果 x0 == x1,跳转到 equal_case    b.lt less_case   // 如果 x0 < x1,跳转到 less_case    b.gt greater_case // 如果 x0 > x1,跳转到 greater_case​equal_case:    // x0 和 x1 相等的情况下执行的代码    b end​less_case:    // x0 小于 x1 的情况下执行的代码    b end​greater_case:    // x0 大于 x1 的情况下执行的代码​end:    // 程序结束    mov x8, #93    // 系统调用号(sys_exit)    mov x0, #0     // 退出状态码    svc #0         // 触发系统调用​

4、跳转指令

  4.1、b

        用于无条件跳转到指定的标签,常与相关的比较指令搭配使用。

b.eq <label>  // 如果相等(Z = 1),跳转到标签 <label>b.ne <label>  // 如果不相等(Z = 0),跳转到标签 <label>b.lt <label>  // 如果小于(N ≠ V),跳转到标签 <label>b.le <label>  // 如果小于或等于(Z = 1 或 N ≠ V),跳转到标签 <label>b.gt <label>  // 如果大于(Z = 0 且 N = V),跳转到标签 <label>b.ge <label>  // 如果大于或等于(N = V),跳转到标签 <label>