当 运行 一个 iOS 应用程序时,存储在 MachO __objc_classlist 部分中的指针数据如何变基?

How does pointer data stored in MachO __objc_classlist section rebased when run a iOS app?

在 MachOView 中,我可以看到在 iOS 二进制文件中,class 指针存储在 __objc_classlist 部分。它们是绝对地址值,指向 __objc_data 段中的 class 数据。但是我们知道iOS使用的是ASLR,所以加载的时候,真实地址一定是不同的。

我检查了“getsectiondata”方法,找不到任何变基逻辑。

所以问题是:

  1. 指针数据何时以及如何变基?
  2. 变基后的数据是脏的吗?

dyld 将变基处理作为加载二进制文件的一部分,远在您调用 getsectiondata 之前。二进制文件中的 LC_DYLD_INFO_ONLY load 命令指向 rebase 操作码,其中包含有关更新哪些地址以及如何更新的信息。

您可以使用 xcrun dyldinfo -rebase <binary> 查看 dyld 将变基的地址列表。您将在 __DATA,__objc_classlist 中看到每个 class 的条目。您可以在启动前在环境中设置 DYLD_PRINT_REBASINGS=1dyld 打印出它变基的每个地址。​​

是的,因为 dyld 在变基时修改数据,页面不再匹配底层存储并且是脏的。避免在加载期间弄脏页面一直是将某些 Objective-C 数据结构从使用指向相对偏移量的指针切换的动机。