IOS 逆向开发(二十二) 汇编-探索函数

1. bl指令

cpu从何处执行指令是由PC中的内容决定的,我们可以通过改变PC的内容来控制CPU执行目标指令

ARM64提供了一个mov指令(传送指令),可以用来修改大部分寄存器的值,比如

mov x0,#10、mov x1,#20

但是,mov指令不能用于设置pc的值,arm64没有提供这样的功能

Arm64提供另外的指令来修改PC的值,这些指令统称为转移指令,最简单的是bl指令

2. 栈

是一种具有特殊的访问方式的存储空间(后进先出,LIFO)

栈

3. SP和FP寄存器

  • sp寄存器在任意时刻会保存我们栈顶的地址.
  • fp寄存器也称为x29寄存器属于通用寄存器,但是在某些时刻我们利用它保存栈底的地址!

注意:ARM64开始,取消32位的 LDM,STM,PUSH,POP指令! 取而代之的是ldr\ldp str\stp
ARM64里面 对栈的操作是16字节对齐的!!

4. 函数调用栈

常见的函数调用开辟和恢复的栈空间

扫描二维码关注公众号,回复: 8751661 查看本文章
sub    sp, sp, #0x40             ; 拉伸0x40(64字节)空间
stp    x29, x30, [sp, #0x30]     ;x29\x30 寄存器入栈保护
add    x29, sp, #0x30            ; x29指向栈帧的底部
... 
ldp    x29, x30, [sp, #0x30]     ;恢复x29/x30 寄存器的值
add    sp, sp, #0x40             ; 栈平衡
ret

函数调用栈

5. 内存读写指令

  • 读/写 数据是都是往高地址读/写
  • str(store register)指令

将数据从寄存器中读出来,存到内存中.

  • ldr(load register)指令

将数据从内存中读出来,存到寄存器中

  • 此ldr 和 str 的变种ldp 和 stp 还可以操作2个寄存器.

  • 实例1: 使用32个字节空间作为这段程序的栈空间,然后利用栈将x0和x1的值进行交换.

sub    sp, sp, #0x20    ;拉伸栈空间32个字节
stp    x0, x1, [sp, #0x10] ;sp往上加16个字节,存放x0 和 x1
ldp    x1, x0, [sp, #0x10] ;将sp偏移16个字节的值取出来,放入x1 和 x0

6. bl和ret指令

  • bl标号

将下一条指令的地址放入lr(x30)寄存器
转到标号处执行指令

  • ret

默认使用lr(x30)寄存器的值,通过底层指令提示CPU此处作为下条指令地址!
ARM64平台的特色指令,它面向硬件做了优化处理的

  • x30寄存器

x30寄存器存放的是函数的返回地址.当ret指令执行时刻,会寻找x30寄存器保存的地址值!

注意:在函数嵌套调用的时候.需要讲x30入栈!

7. 函数和参数返回值

  • ARM64下,函数的参数是存放在X0到X7(W0到W7)这8个寄存器里面的.如果超过8个参数,就会入栈.

  • 函数的返回值是放在X0 寄存器里面的.

8. 函数的局部变量

函数的局部变量放在栈里面.

发布了202 篇原创文章 · 获赞 89 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/kyl282889543/article/details/103216317
今日推荐