iOS逆向学习笔记3 (函数的本质上)

1. 栈

1.1 栈的概念

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

1.2 栈中最重要的两个寄存器

  SP寄存器:栈顶寄存器,在任意时刻都会保存栈顶的地址。
  FP寄存器:栈底寄存器(也称为x29寄存器,属于通用寄存器,在某些时刻利用它来保存栈底的地址)

  注意:ARM64中对栈的操作是16字节对齐的,寄存器存储空间是8字节大小的,也就是128bit

1.3 栈的读写指令

  • 读指令:ldr(load register)、LDR 、LDP,将内容读取到寄存器中。
  • 写指令:str(store register)、STR、STP,将寄存器其中的值存储到内存中

1.4 汇编练习

  • 指令
    1. sub sp, sp, #0x10 ;拉伸16个字节大小的栈空间
    2. stp x29, x30, [sp, #0x10] ;往sp所在位置向高地址方向分别存储x29以及x30的值
  • 简写形式:stp x29, x30, [sp, #-0x10]! (不需要额外的栈空间的时候可以这么写,!的意思是将[]中运算的结果保存到sp寄存器中)。(这句汇编应该是先写入,再拉伸栈空间)

注意:在ARM64中栈的开口方向是由高地址向低地址的,保存寄存器的值是从栈底开始存储的。

2. bl指令

  • bl指令:跳转指令,表示程序执行到标号处,会将下一条指令的地址保存到lr寄存器中。b代表跳转,l代表lr(x30寄存器)。

3. ret指令

  ret指令:返回指令,类似函数中的return,让cpu执行lr寄存器所指向的指令。

**  注意:函数内部调用函数的时候就需要保护现场,在ret指令调用之前,将之前存在栈中的lr寄存器的值取出来赋值给lr寄存器 **

4. 函数的参数

  在ARM64中,参数是存放在x0到x7这8个寄存器中的。

注意:如果是浮点数,就会用浮点寄存器,如果超过8个参数,就会使用栈传递参数

5. 函数的返回值

  在ARM64中,一般函数的返回值是使用x0寄存器保存的。

注意:如果返回值大于8个字节,就会利用内存传递返回值。
  在函数的编写过程中,参数一般都不应超过8个,返回值的字节大小也不应大于8字节,因为会降低效率

你可能感兴趣的:(iOS逆向学习笔记3 (函数的本质上))