获取 macOS/iOS 系统库 dylib 二进制文件
从 dyld Shared Cache 和 IPSW 固件中提取 macOS/iOS 系统库的真实 dylib 二进制文件,并使用 Hopper 进行静态分析,探索 Apple 系统框架的内部实现。
参考 https://juejin.cn/post/7041965159652769806。原文档有些方法过时了,本文做一些修改和补充。
现在想要获取 iOS 的系统库二进制文件比之前麻烦多了。以前能直接在 mac 上找到 iOS 模拟器对应的 framework 二进制文件。现在 Xcode Developer 里面的 framework 只有 tbd(Text-Based Stub Library)文件。tbd 说白了就是用文本描述库链接信息、symbol、架构等信息的文本文件,并不是真正的二进制 dylib,而是 Apple 用来减少 Xcode SDK 体积、提升索引和链接速度的。
获取 dylib
有两个获取系统库 dylib 的方法。
第一种是直接读取 mac 本地的 dyld 缓存,里面包含 macOS 系统用到的动态库缓存,以及一部分 iOS 的动态库缓存(不确定 iOS 版本是怎么对应)。然后从缓存中把 dylib 抽取出来。
另一种是下载 iOS IPSW 固件(用来刷机的),解压后从里面找到动态库。这个方式的好处是可以根据系统版本下载对应的固件,系统版本和提取出来的 dylib 版本对的上。
从 dyld 缓存中抽取
为了提升软件启动速度,减少 dylib 的磁盘占用体积,dyld 将所有系统框架的二进制都打包到了一个大的缓存文件中,在系统启动之后就会进行加载。我们可以从动态库缓存里把动态库一个个抽取出来,得到动态库二进制文件。
macOS 系统本身的动态库缓存文件位置在以下位置。
/System/Library/dyld/dyld_shared_cache_{arch} (Big Sur / Monterey 及之前的版本)
/System/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_{arch} (Ventura 及之后的版本).
我的 MacBook Pro 系统版本是 26.6。可以在 /System/Cryptexes/OS/System/Library/dyld 文件夹里找到名字是 dyld_shared_cache_arm64e 的文件。

从动态库缓存中提取 framework 二进制
Apple 官方提供了一个从 dyld 缓存中提取 dylib 的工具 dsc_extractor。
首先,我们需要先把 https://github.com/apple-oss-distributions/dyld 仓库 clone 下来。然后找到 dsc_extractor.cpp 文件,最底下有一个用 #if 0 宏包裹的代码,把这个文件里面 #if 0 宏外面的代码都注释掉,仅保留宏里面的代码。或者把宏里面的代码单独复制出来,新建一个 cpp 文件。

然后在终端执行命令。
clang++ -o dsc_extractor ./dsc_extractor.cpp
会得到一个 dsc_extractor 的可执行文件。然后用它提取前面提到的动态库缓存。
./dsc_extractor path/to/your/dyld_shared_cache_arm64e ~/Downloads/arm64e
能提出来很多系统 dylib,有 macOS 的,也有 iOS 的。


从 IPSW 固件中提取
可以从 https://ipsw.me/ 这个网站下载各种机型、各个系统的固件。

下载之后把文件后缀从 .ipsw 改成 .zip,双击解压。
解压后的文件创建时间都是 2007 年 1 月 9 日 09:41,也就是第一代 iPhone 的发布时间。


在解压的文件里面找到 size 比较大的那个 dmg,不要直接双击(双击可能会出现文件是损坏的提示)。用 Keka 等可以解压 dmg 的软件,对 dmg 文件进行解压提取。
在提取出来的文件夹里可以找到一系列系统 dylib 的二进制文件。

利用 Hopper 分析二进制文件
找到 dylib 的二进制文件后,就可以拖到 Hopper 里面分析了。

可以参考 Hopper 的官方教程 https://www.hopperapp.com/tutorial.html,学习简单的 Hopper 使用方法。