DYLD

作者: Code_人生 | 来源:发表于2019-10-22 15:01 被阅读0次

一、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方法!
        • doModInitFunctions函数
          • 内部会调用带__attribute__((constructor))的c函数
        • 返回主程序的入口函数。开始进入主程序的main函数!

三、操作

  • 是否显示汇编
  • 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_OPTSDYLD_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

相关文章

网友评论

      本文标题:DYLD

      本文链接:https://www.haomeiwen.com/subject/jpgtvctx.html