-
基于dyld-851.27 和 objc4-818.2 版本
-
配置一系列环境变量:rebase dyld等
-
加载共享缓存 mapSharedCache-> loadDyldCache
-
判断根据dyld3(闭包模式)还是dyld2加载主程序
- 闭包模式:缓存中找闭包,然后验证闭包,验证不成功,再继续缓存中找闭包,还是找不到,就创建一个闭包,接着启动闭包模式,如果启动不成功,或者闭包模式过期等等,再创建一次闭包,有了闭包,直接return主程序的main
-
实例化主程序 instantiateFromLoadedImage->instantiateMainExecutable->sniffLoadCommands->addImage(segCount不能大于255个,libCount不能大于4095个,放入allimages数组里的第一位)
-
加载插入动态库 loadInsertedDylib->load(越狱环境可修改变量DYLD_INSERT_LIBRARIES,来添加插件)
-
链接主程序:linkingMainExecutable,rebase主程序
-
链接动态库:link
-
绑定符号:no-lazy表、weak表(lazy表是运行时用到的时候才绑定的)
-
初始化主程序:initializeMainExecutable
- runInitializers
- processInitializers
- recursiveInitialization
- notifySingle(到这里,就在也找不到怎么调用load_images,但是看到调用了一个block sNotifyObjCInit 是registerObjCNotifiers函数的第二个参数,跟踪registerObjCNotifiers,看下是谁调用registerObjCNotifiers传来的第二个参数是什么 ?找到_dyld_objc_notify_register调用的,全局查找是谁调用了_dyld_objc_notify_register,找不到,那么就给示例工程下符号断点:_dyld_objc_notify_register,看下是谁调用了_dyld_objc_notify_register,结果发现是libobjc.A.dylib`_objc_init:调用的,接着就去objc源码查看_objc_init函数的第二个参数是什么,在文件objc-os.mm找到了函数void _objc_init(void),看到了调用了 _dyld_objc_notify_register(&map_images, load_images, unmap_image);,所以第二个参数是调用了load_images,调用了call_load_methods。接着调用call_class_loads)
- recursiveInitialization
- processInitializers
- runInitializers
-
doInitialization->doModInitFunctions c++的全局函数定义
- 拿到主程序的main函数入口:getEntryFromLC_MAIN
- 进入主程序man函数
-
网友评论