《iOS底层原理文章汇总》
上一篇文章介绍了iOS-逆向12-MachO文件,本文介绍Dyld链接器如何加载MachO文件,dyld的加载流程,可参考前面的文章iOS-底层原理12-应用程序加载
dyld:动态链接器:加载所有的库和可执行文件
dyld加载流程:
- 程序执行从_dyld_start开始->dyld`dyldbootstrap::start
- 进入dyld main函数
- 配置一些环境: rebase_dyld
- 加载共享缓存
dyld2/dyld3(闭包模式)
- 实例化主程序
- 加载动态库(首先是插入的动态库(项目运用到的第三方库),系统库等),dyldinsertLibrary,无论是主程序还是动态库都会添加进allImage中,loadAllImages)
- 链接主程序,绑定符号表(非懒加载,弱符号)等等
- 最关键的初始化方法initializeMainExecutable
- dyld`ImageLoader:runInitializers
- dyld`ImageLoader::processInitializers
- dyld`ImageLoader::recursiveInitialization
- dyld`context.notifySingle
- 此函数执行一个回调
- 通过断点调试:此回调是_objc_init()初始化时赋值的一个函数load_images
3.load_images里面执行call_load_methods函数
4.call_class_loads函数,会循环调用各个类的load方法
- dyld`ImageLoaderMachO::doModInitFunctions:
1.函数内部会调用全局C++对象的构造函数attribute((constructor))的C函数- 返回主程序的入口函数,进入主程序的main函数
思考:给主程序添加load方法,是主程序中的load先执行,还是frameworks中的load先执行?与imagelist顺序有关,是正序加载还是倒序加载呢?
在主程序的AppDelegate,ViewController类中中和动态库的CloudHook中类Inject的load方法中分别断点调试,发现会先走动态库CloudHook中的类Inject中的load方法
主程序中类的load方法顺序会依据Build Phases中的Compile sources中的文件顺序