1 load部分
1.1 调用堆栈
frame #0: MyApp`+[XXX load]
frame #1: libobjc.A.dylib`call_load_methods + 680
frame #2: libobjc.A.dylib`load_images + 144
frame #3: dyld`dyld::notifySingle() + 312
frame #4: dyld`ImageLoader::recursiveInitialization() + 344
frame #5: dyld`ImageLoader::recursiveInitialization() + 260
frame #6: dyld`ImageLoader::processInitializers() + 144
frame #7: dyld`ImageLoader::runInitializers() + 84
frame #8: dyld`dyld::initializeMainExecutable() + 184
frame #9: dyld`dyld::_main() + 3784
frame #10: dyld`_dyld_start + 68
1.2 加载时机
dyld调到obc库,objc库调用各个load方法。
objc库调用load过程:_getObjc2NonlazyClassList获取所有类列表,判断load实现,生成一份指针列表,然后挨个调用。
详细参考:
https://zhuanlan.zhihu.com/p/20816991
实际发现_getObjc2NonlazyClassList获取到的就是一堆实现了load方法的类,这些类都保存在Section(_DATA,_obj_nlclslist)。(MachOView工具)
dyld源码分析参考:
http://turingh.github.io/2016/03/01/dyld%E4%B8%ADmacho%E5%8A%A0%E8%BD%BD%E7%9A%84%E7%AE%80%E5%8D%95%E5%88%86%E6%9E%90/
https://github.com/turingH/dyld_soucecode_analysis
http://opensource.apple.com/tarballs/dyld/dyld-360.18.tar.gz
obj库源码参考:
http://opensource.apple.com/tarballs/objc4/
1.3 找出所有实现load方法的OC类
符号断点load找出来;
或者Hopper Disassembler/IDA打开debug版二进制文件,跳到_obj_nlclslist section,可以找到如下列表:
_OBJC_CLASS_$_XXX1
_OBJC_CLASS_$_XXX2
_OBJC_CLASS_$_XXX3
...
2 静态函数部分
2.1 调用堆栈
frame #0: MyApp`XXXFunction() + 24
frame #1: dyld`ImageLoaderMachO::doModInitFunctions() + 260
frame #2: dyld`ImageLoaderMachO::doInitialization() + 36
frame #3: dyld`ImageLoader::recursiveInitialization() + 368
frame #4: dyld`ImageLoader::processInitializers() + 144
frame #5: dyld`ImageLoader::runInitializers() + 84
frame #6: dyld`dyld::initializeMainExecutable() + 220
frame #7: dyld`dyld::_main() + 3784
frame #8: dyld`_dyld_start + 68
2.2 加载时机
dyld调到obc库,objc库调用各个静态函数。说明:静态函数是main函数前被触发的那些静态函数。
2.3 找出所有启动时被执行的静态函数
section里位置:Section(_DATA,__mod_init_func)
Hopper Disassembler/IDA打开debug版二进制文件,跳到__mod_init_func段.