iOS逆向:函数本质(上)

本文深入探讨iOS开发中的函数调用机制,包括栈的概念、SP和FP寄存器的作用、内存读写指令、bl和ret指令的使用,以及x30寄存器在函数返回中的关键角色。通过讲解和练习,帮助开发者理解arm64架构下的函数调用栈和返回过程。
摘要由CSDN通过智能技术生成

本文的主要目的是理解函数栈以及涉及的相关指令

在讲函数的本质之前,首先需要讲下以下几个概念栈、SP、FP

常识

  • 栈:是一种具有特殊的访问方式的存储空间(即先进后出 Last In Out First, LIFO

  • 高地址往低地址存数据(存:高-->低
- 栈空间开辟:往低地址开辟(`开辟:高-->低`)
复制代码

SP和FP寄存器

  • SP寄存器:在任意时刻会保存栈顶的地址

  • FP寄存器(也称为x29寄存器):属于通用寄存器,但是在某些时刻(例如函数嵌套调用时)可以利用它保存栈底的地址

注意:

  • arm64开始,取消了32位的LDM、STM、PUSH、POP指令,取而代之的是 ldr/ldp、str/stp(r和p的区别在于处理的寄存器个数,r表示处理1个寄存器,p表示处理两个寄存器)

  • arm64中,对栈的操作是16字节对齐的!!!

以下是arm64之前和arm64之后的一个对比 !

  • 在arm64之前,栈顶指针是压栈时一个数据移动一个单元

  • 在arm64开始,首先是从高地址往低地址开辟一段栈空间(由编译器决定),然后再放入数据,所以不存在push、pop操作。这种情况可以通过内存读写指令(ldr/ldp、str/stp)对其进行操作

函数调用栈

以下是常见的函数调用开辟 (sub)以及恢复栈空间 (add)的汇编代码

//开辟栈空间
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

作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的iOS开发交流群:130595548,不管你是小白还是大牛都欢迎入驻 ,让我们一起进步,共同发展!(群内会免费提供一些群主收藏的免费学习书籍资料以及整理好的几百道面试题和答案文档!)

内存读写指令

  • str(store register)指令(能和内存和寄存器交互的专门的指令):将数据从寄存器中读出来,存到内存中 (即一个寄存器是8字节-64位

  • ldr(load register)指令:将数据从内存中读出来,存到寄存器中

  • 此时ldr和str的变种 ldp和stp 还可以操作2个寄存器(即128位-16字节

注意:

  • 读/写数据都是往高地址读/写

  • 写数据:先拉伸栈空间,再拿sp进行写数据,即先申请空间再写数据

练习

使用32个字节空间作为

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值