欢迎阅读iOS逆向系列(按序阅读食用效果更加)
写在前面
dyld
作为苹果的动态链接器,是苹果操作系统的一个重要组成部分,在系统内容做好程序准备工作之后交由dyld
负责余下的工作。因此了解dyld
的加载过程对我们的逆向之旅有一定的帮助
由于在iOS探索系列已经通过iOS探索 浅尝辄止dyld加载流程对dyld
有过一定的介绍,本文只会精简介绍一下具体流程
一、_dyld_start
_dyld_start
是程序执行的起点,可以通过bt指令
查看到
在汇编中
_dyld_start
调用
dyldbootstrap::start
二、dyldbootstrap::start
dyldbootstrap::start
函数中做了一些保护手段,并调用dyld::_main
三、dyld::_main
3.1 配置环境变量
只要设置了这两个环境变量参数,在App启动时就会打印相关参数、环境变量信息
3.2 加载共享缓存库
调用checkSharedRegionDisable
函数检查并加载共享缓存库(iOS无法禁用共享缓存库)
3.3 实例化主程序
调用instantiateFromLoadedImage
函数
3.4 加载动态库
越狱的插件一般是在这里发光发热的
3.5 链接主程序
链接主程序和动态库
接下来就是dyld最重要的部分
3.6 初始化方法
调用initializeMainExecutable
初始化方法,这是一个复杂的遍历过程——先处理动态库,再处理主程序
initializeMainExecutable
调用runInitializers
runInitializers
调用
processInitializers
processInitializers
调用
recursiveInitialization
recursiveInitialization
调用
notifySingle
和
doInitialization
notifySingle
先判断
sNotifyObjCInit
是否为空,再调用
sNotifyObjCInit
回调
全局搜索,发现是在
registerObjCNotifiers
中注册的
sNotifyObjCInit
回调
_dyld_objc_notify_register
调用
registerObjCNotifiers
在
objc源码
中的
_objc_init
处调用了
_dyld_objc_notify_register
作为
_dyld_objc_notify_register
的第二个参数,
notifySingle
回调被调用也随之调用,然后遍历调用动态库中的
+load
方法
在notifySingle
之后会调用doInitialization
doImageInit
会去判断libSystem
是否初始化
doModInitFunctions
遍历调用c++构造方法
3.7 进入主程序
至此,dyld流程就结束了,接下来就是main函数的舞台
四、dyld流程图
五、证明
新建动态库,分别在主程序和动态库中添加+load方法
和c++构造方法
+ (void)load {
NSLog(@"主程序——load");
}
__attribute__((constructor)) void funcCooci(){
printf("主程序——c++");
}
Framework(Feng)——load
Framework(Feng)——c++
主程序——load
主程序——c++
事实证明动态库
先于主程序
执行+load方法
和c++构造方法
- 多个动态库的执行先后顺序取决于
General -> Framework, Libraries, and Embedded Content
顺序
- 主程序中多个编译单元的执行先后顺序取决于
Build Phases -> Compile Sources
顺序
写在后面
迫于个人的强迫症,还是选择了在iOS逆向系列中加了一篇关于dyld流程的文章,但与iOS探索系列不同的是,这篇文章更加精炼、易于理解
今天的文章iOS逆向 dyld流程分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21281.html