营销网站建设报价,石家庄网站建设接单,订制网站,网站建设属于服务还是货物参考#xff1a;认识 dyld #xff1a;动态链接器
dyld简介
dyld#xff08;Dynamic Linker#xff09;是 macOS 和 iOS 系统中的动态链接器#xff0c;它是负责在运行时加载和链接动态共享库#xff08;dylib#xff09;或可执行文件的组件。在 macOS 系统中#xf…参考认识 dyld 动态链接器
dyld简介
dyldDynamic Linker是 macOS 和 iOS 系统中的动态链接器它是负责在运行时加载和链接动态共享库dylib或可执行文件的组件。在 macOS 系统中dyld 位于 D/usr/lib/dyld。
dyld源码地址
dyld 2
dyld 2Dynamic Linker 2是 macOS 和 iOS 系统中的第二代动态链接器。它是前代 dyld 1的进化版本在性能、功能和安全性方面都有所改进和优化。dyld 2 主要负责在运行时加载和链接动态共享库或可执行文件的组件并使程序能够正确执行。
以下是 dyld 2 的一些主要特点和改进
它具有对 C 初始化程序语义的正确支持扩展了 Mach-O 格式并更新了 dyld 以便有效支持的 C 库。支持更多的架构及平台。 自从Power PC上 发布 dyld 2.0 以来添加了 x86x86 64 armarm64 等架构支持了 iOS, tvOS, 和 watchOS 平台。通过多种方式提高了安全性。 Codesigning 代码签名。为了提高应用程序的安全性dyld 2 支持验证应用程序和共享库的代码签名以确保它们没有被篡改或恶意修改。ASLR Address space layout randomization 地址空间配置随机加载。bounds checking对 Mach-O Header 中的许多内容添加了重要的边界检查功能从而可以避免恶意二进制数据的注入。 模拟器支持dyld 2 在 iOS 模拟器中提供了更好的性能和功能支持使得开发者能够更方便地在模拟器上进行应用程序调试和测试。提升性能使用 shared cache 技术完全替代了预绑定 prebinding。增量加载dyld 2 支持增量加载Incremental Loading即在应用程序启动时只加载必要的共享库和符号而不是一次性加载所有动态库。这可以进一步减少启动时间和内存占用。并发加载dyld 2 充分利用了多核处理器的优势支持并发加载动态共享库从而加速动态链接的过程。符号隔离为了提高安全性dyld 2 引入了符号隔离机制。它将共享库的符号表隔离起来使得共享库之间的符号不会相互影响从而避免符号冲突和符号泄
执行流程 dyld 2 初始化一旦 dyld 2 加载到内存中它会执行一些初始化操作准备好执行动态链接的任务。主要代码在 dyldbootstrap::start接着执行 dyld::_main dyld::_main 代码较多是 dyld 加载的核心部分检查并准备环境比如获取二进制路径检查环境变量解析主二进制的 image heade 等信息实例化主二进制的 image loader 校验主二进制和 dyld 的版本是否匹配检查 shared cache 是否已经 map 没有的话则先执行 map shared cache 操作检查 DYLD_INSERT_LIBRARIES有的话则加载插入的动态库实例化 image loader;执行 link 操作。这个过程比较复杂会先递归加载依赖的所有动态库会对依赖库进行排序被依赖的总是在前面同时在这阶段将执行符号绑定以及rebasebinding 操作执行初始化方法。Objective-C 的 load 以及 C 的 constructor方法都会在这个阶段执行读取 Mach-O 的 LC_MAIN段 获取程序的入口地址调用 main 方法。
加载共享缓存
因为 Foundation 还会依赖一些其他动态库这些依赖的其他库还会再依赖更多的库所以相互依赖的符号会很多需要处理的时间也会比较长。这里系统上的动态链接器会使用共享缓存共享缓存在 /var/db/dyld/。当加载 Mach-O 文件时动态链接器会先检查是否有共享缓存。每个进程都会在自己的地址空间映射这些共享缓存这样做可以起到优化 App 启动速度的作用。 加载共享缓存Shared Cache是 dyld 2 在 macOS 和 iOS 系统中用于加快动态链接的一项优化技术。共享缓存是一种预先生成的动态库集合包含了多个应用程序常用的动态共享库。当应用程序启动时dyld 2 可以直接从共享缓存中加载所需的动态库而无需再重新从磁盘上逐个加载动态库从而加快应用程序的启动速度。 共享缓存的加载过程可以简要概括如下
生成共享缓存在系统安装或更新时操作系统会预先生成一个共享缓存其中包含了多个常用的系统动态共享库和框架。这个过程通常在设备首次启动、操作系统升级或开发者重新编译系统库时进行。共享缓存路径共享缓存被保存在系统文件中其路径是 /System/Library/Caches/com.apple.dyld/dyld_shared_cache_x86_64macOS或 /System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64iOS等具体路径会根据设备和架构而有所不同。应用程序启动当应用程序启动时dyld 2 会首先检查共享缓存是否可用并尝试加载共享缓存。加载共享缓存如果共享缓存可用dyld 2 会直接将共享缓存映射到内存中并建立共享缓存中动态库与应用程序之间的链接关系。符号解析和重定位在加载共享缓存后dyld 2 会进行符号解析和重定位将应用程序中的符号引用与共享缓存中的符号地址进行关联。动态库链接如果应用程序还依赖其他未包含在共享缓存中的动态共享库dyld 2 会根据需要逐个加载这些动态共享库并进行链接和符号解析。应用程序初始化一旦所有动态共享库都加载并完成符号解析后dyld 2 会开始执行应用程序的main()函数从而正式启动应用程序的执行。
动态库加载
链接的共用库分为静态库和动态库
静态库是编译时链接的库需要链接进 Mach-O 文件里如果需要更新就要重新编译一次无法动态加载和更新动态库是运行时链接的库使用 dyld 就可以实现动态加载。 Mach-O 文件是编译后的产物而动态库在运行时才会被链接并没参与 Mach-O 文件的编译和链接所以 Mach-O 文件中并没有包含动态库里的符号定义。也就是说这些符号会显示为“未定义”但它们的名字和对应的库的路径会被记录下来。运行时通过 dlopen 和 dlsym 导入动态库时先根据记录的库路径找到对应的库再通过记录的名字符号找到绑定的地址。 dlopen 会把共享库载入运行进程的地址空间载入的共享库也会有未定义的符号这样会触发更多的共享库被载入。dlopen 也可以选择是立刻解析所有引用还是滞后去做。dlopen 打开动态库后返回的是引用的指针dlsym 的作用就是通过 dlopen 返回的动态库指针和函数符号得到函数的地址然后使用。 dyld 2 存在的问题
Parse mach-o headers 可以使用撰改过的 Mach-O 文件头进行攻击Find dependencies 可以使用 rpaths 即搜索路径。通过撰改这些路径或者将库插到适当的位置可以破坏程序Perform symbol lookups 符号查找部分因为在给定的库中除非进行软件更新或者在磁盘上更改库符号将始终位于库中的相同偏移位置
dyld 3
dyld 3是全新的动态链接器它完全改变了动态链接概念。WWDC-App Startup Time: Past, Present, and Future 提到在iOS 13系统中iOS 全面采用新的 dyld 3 以替代之前版本的 dyld 2。dyld 3带来了可观的性能提升减少了APP的启动时间。 因为 dyld 3 完全兼容 dyld 2API 接口是一样的所以在大部分情况下开发者不需要做额外的适配就能平滑过渡。
执行流程 dyld 3 包含这三个部分:
进程外 Mach-O 分析器和编译器 out-of-process mach-o parser由于 dyld 2 存在的问题dyld 3 中将采用提前写入把结果数据缓存成文件的方式构成一个 lauch closure可以理解为缓存文件进程内引擎 执行 launch closure 处理 (in-process engine)验证”lauch closures“是否正确映射dylib执行main函数。此时它不再需要分析mach-o header和执行符号查找节省了不少时间。launch closure 缓存服务 (launch closure cache )系统程序的 lauch closure 直接内置在 shared cache 中而对于第三方APP将在APP安装或更新时生成这样就能保证 launch closure 总是在 APP 打开之前准备好。 大多数程序启动会使用缓存而不需要调用进程外 mach-o分析器或编译器并且 launch closure 比 Mach-O 更简单它们是内存映射文件不需要用复杂的方法进行分析我们可以简单地验证它们其作用是为了提高速度 dyld 3的符号缺失问题
dyld 2 默认采取的是 lazy symbol 的符号加载方式但在 dyld 3中在 App 启动之前符号解析的结果已经在 lauch closure 内了所以 lazy symbol 就不再需要。这时如果有符号缺失的情况APP 的行为会有不同在 dyld 2 中首次调用缺失符号时 APP 会 crash而 dyld 3 中缺失符号会导致 APP 一启动就会 crash。