一、DYLD
dyld(the dynamic link editor
)是苹果的动态链接器,是苹果操作系统一个重要组成部分,在系统内核做好程序准备工作之后,交由dyld负责余下的工作。
二、加载流程

- dyld加载所有的库和可执行文件
- dyld加载流程
- 程序执行从_dyld_start开始
- 进入dyld:main函数
- 配置一些环境变量
- 加载共享缓存库(一开始就判断是否禁用,iOS无法被禁用的)
- 实例化主程序
- 加载动态库(插入的库,三方库,link)
- 链接主程序
- 最关键的地方:初始化方法
- 经过一系列初始化调用notifySingle函数
- 该函数会执行一个回调
- 通过断点调试:该回调是_objc_init初始化的时候赋值的一个函数load_images
- load_images里面执行call_load_methods函数
- call_load_methods函数循环调用各个类的load方法!
- load_images里面执行call_load_methods函数
- doModInitFunctions函数
- 内部会调用带
__attribute__((constructor))
的c函数
- 内部会调用带
- 返回主程序的入口函数。开始进入主程序的main函数!
- 经过一系列初始化调用notifySingle函数
三、操作
- 是否显示汇编



-
dyld
源码搜索dyldbootstrap
,然后找到start
函数

uintptr_t start(const struct macho_header* appsMachHeader, int argc, const char* argv[],
intptr_t slide, const struct macho_header* dyldsMachHeader,
uintptr_t* startGlue)
{
// if kernel had to slide dyld, we need to fix up load sensitive locations
// we have to do this before using any global variables
slide = slideOfMainExecutable(dyldsMachHeader);
bool shouldRebase = slide != 0;
#if __has_feature(ptrauth_calls)
shouldRebase = true;
#endif
if ( shouldRebase ) {
rebaseDyld(dyldsMachHeader, slide);
}
// allow dyld to use mach messaging
mach_init();
// kernel sets up env pointer to be just past end of agv array
const char** envp = &argv[argc+1];
// kernel sets up apple pointer to be just past end of envp array
const char** apple = envp;
while(*apple != NULL) { ++apple; }
++apple;
// set up random value for stack canary
__guard_setup(apple);
#if DYLD_INITIALIZER_SUPPORT
// run all C++ initializers inside dyld
runDyldInitializers(dyldsMachHeader, slide, argc, argv, envp, apple);
#endif
// now that we are done bootstrapping dyld, call dyld's main
uintptr_t appsSlide = slideOfMainExecutable(appsMachHeader);
return dyld::_main(appsMachHeader, appsSlide, argc, argv, envp, apple, startGlue);
}
-
command + shift + j
定位到文件的位置 -
command + shift + o
搜索类 -
dyld::_main(appsMachHeader, appsSlide, argc, argv, envp, apple, startGlue);
,点击_main()
-
DYLD_PRINT_OPTS
、DYLD_PRINT_ENV
打印环境变量

....
- 加载动态库顺序、Load调用顺序、
__attribute__((constructor))
调用顺序



....
void _dyld_objc_notify_register(_dyld_objc_notify_mapped mapped,
_dyld_objc_notify_init init,
_dyld_objc_notify_unmapped unmapped)
{
dyld::registerObjCNotifiers(mapped, init, unmapped);
}
- 下一个符号
_dyld_objc_notify_register
断点 register read x0
register read x1
-
register read x2
网友评论