iOS逆向学习笔记之--ARM处理器的寄存器学习

iOS逆向学习笔记之–ARM处理器的寄存器学习

对于逆向过程中需要分析目标APP某个方法实现的时候,需要了解一些汇编指令。下面就来了解一些常用汇编指令的用法。

ARM官方文档地址http://infocenter.arm.com

ARM32

R0 - R3 传递参数与返回值
R7      帧指针,指向母函数与被调用子函数在栈中的交界
R9      iOS 3.0以前被系统保留
R12     内部调用寄存器,dynamic linker会用到它
R13     SP寄存器
R14     LR寄存器,保存函数地址
R15     PC寄存器

// 比较
EQ      结果为零
NE     结果不为零
// 算术操作
ADD R0, R1, R2R0=R1+R2
ADC R0, R1, R2R0=R1+R2 + C(array)
SUB R0, R1, R2R0=R1-R2
SBC R0, R1, R2R0=R1-R2 - !C
RSB R0, R1, R2R0=R2-R1
RSC R0, R1, R2R0=R2-R1 - !C


CMP r1r2;  // r1 - r2并依结果设置flag

LDR 将数据从内存中读取出来,放到寄存器中
STR 将数据从寄存器取出来放到内存中

LDM 把Rd开始,地址连续的内存数据存入寄存器中
STM 是把寄存器中的值存入从Rd开始,地址连续的内存中

// 金句
函数前4个参数存放在R0R3中,其他参数存放在栈中,返回值在R0

AArch64

  • 常用寄存器
寄存器位数描述
X0-X3064bit通用寄存器,如果有需要可以当做32位是使用W0-W30
FP(X29)64bit保存栈帧地址(栈底指针)
LP(X30)64bit通常称X30为程序链接寄存器,保存跳转返回信息地址
SP64bit保存栈指针
PC64bit程序计数器,PC指针,总是指向即将要执行的下一条指令
  • 通用寄存器32位位于64位名称
位数
64bitXn(通用)XZR(0寄存器)SP(堆栈指针)
32bitWn(通用)WZR(0寄存器)WSP(栈指针)
  • 通用寄存器用法
    x0…x7 用于子程序调用时的参数,x0还用于返回值传递
    x8 间接寻址结果
    x29 通常用作FP
    x30 通常用作LR

  • 常用汇编指令

// 算术指令
ADD    X0,X1,X2   // 寄存器X1和X2的值相加后传送到X0
SUB    X0,X1,X2   // 寄存器X1和X2的值相减后传送到X0
CMP    w0, #0x0     // w0 - 0 比较指令,相当于SUBS,影响程序状态寄存器CPSR 
CMN    w0, #0x10     // w0 + 0x10 并影响条件标志位

// 逻辑指令
AND    X0,X0,#0xF   // x0 = x0 & 0xF  X0的值与0xF相位与后的值传送到X0 ADNS表示影响条件标志位
ORR    X0,X0,#9     // x0 = x0 | 9    X0的值与9相位或后的值传送到X0
EOR    X0,X0,#0xF   // x0 = x0 ^ 0xF  X0的值与0xF相异或后的值传送到X0

// 数据传输指令
MOV X1, X0 // x1 = x0 将寄存器x0的值存到x1

// 地址偏移指令
ADR 

// 移位运算指令
ASR xd,xn, #uimm // 算术右移,移位过程中符号位不变
LSL xd,xn, #uimm // 逻辑左移,移位后寄存器空出的低位补0
LSR xd,xn, #uimm // 逻辑右移,移位后寄存器空出的高位补0
ROR xd,xn, #uimm // 循环右移,从右端移出的位将被插入左侧空出的位

// 加载存储指令
LDR    X5,[X6,#0x08]    // X6寄存器加0x08的和的地址值内的数据传送到X5
STR    X0, [SP, #0x8]    // X0寄存器的数据传送到SP+0x8地址值指向的存储空间
STUR   w0, [x29, #0xfffffff8] // w0的值写入x29 +0xfffffff8指向的内存
LDUR   w9, [x29, #0xffffffec] // 将x29 + 0xffffffec地址内存处的值,写入w9寄存器
STP    x29, x30, [sp, #0x10]   // 入栈指令
LDP    x29, x30, [sp, #0x10]   // 出栈指令

// 条件跳转指令
B.cond 0x100007f70  // cond为真 跳转到0x100007f70
CBZ x8, 0x100007f70  // x8=0 跳转到0x100007f70  比较(Compare),如果结果为零(Zero)就转移(只能跳到后面的指令)
CBNZ x8, 0x100007f70 // x8!=0 跳转到0x100007f70  比较,如果结果非零(Non Zero)就转移(只能跳到后面的指令)

// 无条件跳转指令
B/BL 0x100007f70 // 绝对跳转0x100007f70, 返回地址保存到LR(X30)
RET   // 子程序返回指令,返回地址默认保存在LR(X30
BR xn // 无条件跳转到xn寄存器地址

// 其他寄存器
PC 寄存器:记录当前代码执行的地址
SP 寄存器:指向栈帧指针,在内存指令中通过x31寄存器来访问
LR 寄存器:指向返回地址,对应于寄存器x30
FP 寄存器:指向栈帧的底部对应于寄存器x29
  • 条件码标志
    N、Z、C、V均为条件标志位。它们的内容可被算术或逻辑运算的结果所改变,并且可以决定某条指令是否被执行。条件码标志各位的具体含义如下表所示:
标志位含义
N当两个有符号额整数运算时: N=1:表示运算的结果为负数 N=0:表示运算结果为正数或零
ZZ=1表示运算的结果为零,Z=0表示结果非零。对于CMP指令,Z=1表示进行比较的两个数相等
C可以有4种方法设置C的值: 1、在加法指令中(包括比较指令CMP),当结果产生了进位,则C=1,表示无符号运算发生上溢出,其他情况C=0。 2、在减法指令(包括减法指令CMP),当运算中发生了借位,则C=0,表示无符号运算数发生下溢出;其他情况下C=1。 3、对于包含移位操作的非加减运算指令,C中包含最后一次溢出位的数值。 4、对于其他非加减运算指令,C位的值通常不受影响
V对于加减运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢出;通常其他指令不影响V位
  • 常见的指令的条件码
条件码助记符标志含义
NEZ清零不相等
EQZ置位相等
LEZ清零或N不等于V带符号数小于或等于
GEN等于V带符号数大于或等于
LTN不等于V带符号数小于
GTZ清零且N等于V带符号数大于
HlC置位Z清零无符号数大于
LSZ置位C清零无符号数小于或等于
CC(LO)C清零无符号数小于
CS(HS)C置位无符号数大于或等于

如何编写代码,编译成汇编指令

有时候我们需要将自己编写的代码,编译然后查看对应的汇编代码

将c代码编译成.m文件,然后将.m文件拖入IDA查看汇编代码
clang -O0 -arch arm64 -isysroot xcrun --sdk iphoneos --show-sdk-path test.c -o test.m
// xcrun –sdk iphoneos –show-sdk-path 是获取xcode环境中iPhoneOS sdk的目录

还有一种方法就是直接在Xcode下断点,设置Debug->Debug workflow->Awayls show Disassembly 查看对应的汇编代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值