简述
在使用系统的ODR功能的时候,我们碰到了一个系统内部崩溃问题,通过苹果官方的 feedbackassistant 平台反馈问题,并没有得到有价值的回复;并且该功能实在iOS 9.x 支持的功能,历史版本问题也无法让他们解决;所以只能自己分析系统的实现,来找到解决系统奔溃的解决办法。
日常开发的过程中,我们需要读取几百个文件,到内存当中。如果我们逐个读取这些文件,会有很大一部分时间消耗在,文件打开过程中。iOS系统的动态库,也面临着类似的问题,苹果将所有的动态库合并成一个巨大的二进制文件 dyld_shared_cache(iOS 13.3.1 版本 1.62 GB)。当设备启动时,系统的一些服务也需要引用动态库,故在iPhone首次启动时,加载到内存中,其他App启动后,只需要使用已加载好的动态库,避免影响冷启动速度
dyld_shared_cache (简称:DSC)拥有当前系统下,所有动态库的信息,APM的Crash平台,也是通过dsc_extractor工具,提取出每个动态库,来符号化奔溃日志中系统符号。
路径
iOS DeviceSupport 路径下的文件,会在连接真机之后生成
iOS 13.3.1 版本的 dyld_shared_cache 路径:
1 | ~/Library/Developer/Xcode/iOS\ DeviceSupport/13.3.1\ \(17D50\)/Symbols/System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64 |
处理模式
IDA也支持了解析 DSC 文件,并且提供了三种模式
1、加载全部的动态库 (iOS 14.2 DSC 曾有人在Windows 32GB 内存 IDA 7.5 耗时10天才解析完整个缓存,共约25GB)
2、加载单个动态库
3、加载单个动态库及其依赖库
IDA 在7.2、7.5版本,分别优化了解析DYLD Cache 的相关功能,主要调整为:按需加载部分动态库,当碰到其他未解析的动态库时,可以右键动态去加载对应的信息
如果有7.5版本,可直接下载解析好的idb数据库,来直接去分析系统实现,而不需要自己一直开着电脑去解析很多天
可惜的是,目前macOS系统下,目前只有7.0版本。在使用7.0版本的时候,可以用第三种单模块依赖模式,来分析DSC文件
效果对比
通过下面的对比效果可以知道,依赖模式可以加载当前分析动态库的依赖库,并且在分析对应的符号时,将依赖其它动态库的符号也解析出来。曾经用 Hopper Disassembler 软件分析过一个动态库,在解析其它动态库符号时,由于没有其动态库数据,会错误解析成其他符号,对我们的分析工作造成误导,这点需要注意下
单模块依赖效果
单模块效果