DYLD--动态链接器

news2024/11/18 11:51:07

概念

dyld(the dynamic link editor)是苹果的动态链接器,是苹果操作系统一个重要组成部分,在系统内核 XNU 完成 Mach-O 文件的加载,做好程序准备工作之后,交由 dyld 负责余下的工作。在 macOS 系统中,dyld 位于 D/usr/lib/dyld

dyld 1.0(1996 - 2004)

  • 在 NeXTStep 3.3 中引入了 dyld 1.0,在此之前,NeXT 使用 static binaries
  • POSIX dlopen() 进行了标准化
  • 预绑定 Prebinding

dyld 2(2004 - 2017)

  • dyld 2 对 dyld 1.0 进行了全面的重写;
    • 它具有对 C++ 初始化程序语义的正确支持,扩展了 Mach-O 格式,并更新了 dyld ,以便有效支持的 C++ 库。
  • dyld 2 具有完整的 dlopen 和 dlsym 实现,此时弃用了旧版 API。
  • 支持更多的架构及平台
    • 自从Power PC上 发布 dyld 2.0 以来,添加了 x86,x86 64 arm,arm64 等架构,支持了 iOS, tvOS, 和 watchOS 平台
  • 通过多种方式提高了安全性
    • Codesigning : 代码签名
    • ASLR :Address space layout randomization 地址空间配置随机加载
    • bounds checking:对 Mach-O Header 中的许多内容添加了重要的边界检查功能,从而可以避免恶意二进制数据的注入
  • 提升性能
    • 使用 shared cache 技术完全替代了预绑定 prebinding;

执行流程

请添加图片描述

  • dyld 的初始化,主要代码在 dyldbootstrap::start,接着执行 dyld::_main ,dyld::_main 代码较多,是 dyld 加载的核心部分;
  • 检查并准备环境,比如获取二进制路径,检查环境变量,解析主二进制的 image header 等信息;
    实例化主二进制的 image loader ,校验主二进制和 dyld 的版本是否匹配;
  • 检查 shared cache 是否已经 map ,没有的话则先执行 map shared cache 操作;
  • 检查 DYLD_INSERT_LIBRARIES,有的话则加载插入的动态库(实例化 image loader);
  • 执行 link 操作。这个过程比较复杂,会先递归加载依赖的所有动态库(会对依赖库进行排序,被依赖的总是在前面),同时在这阶段将执行符号绑定,以及rebase,binding 操作;
  • 执行初始化方法。Objective-C 的 +load 以及 C 的 constructor方法都会在这个阶段执行;
  • 读取 Mach-O 的 LC_MAIN段 获取程序的入口地址,调用 main 方法。

加载共享缓存

因为 Foundation 还会依赖一些其他动态库,这些依赖的其他库还会再依赖更多的库,所以相互依赖的符号会很多,需要处理的时间也会比较长。这里系统上的动态链接器会使用共享缓存,共享缓存在 /var/db/dyld/。当加载 Mach-O 文件时,动态链接器会先检查是否有共享缓存。每个进程都会在自己的地址空间映射这些共享缓存,这样做可以起到优化 App 启动速度的作用。

动态库加载

链接的共用库分为静态库和动态库:

  • 静态库是编译时链接的库,需要链接进 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 符号查找部分,因为在给定的库中,除非进行软件更新或者在磁盘上更改库,符号将始终位于库中的相同偏移位置

Tips : -Wl,-sectcreate,__RESTRICT,__restrict,/dev/null 虽然在 iOS 10 以前才可以避免动态库的注入,但是可以通过修改 Mach-O 绕过

Tips : 一般情况下,动态库的路径都是 @rpath ,比如: @excutable/Frameworks

dyld 3 (2017)

dyld 3是全新的动态链接器,它完全改变了动态链接概念WWDC-App Startup Time: Past, Present, and Future 提到在iOS 13系统中,iOS 全面采用新的 dyld 3 以替代之前版本的 dyld 2。dyld 3带来了可观的性能提升,减少了APP的启动时间。 因为 dyld 3 完全兼容 dyld 2,API 接口是一样的,所以在大部分情况下,开发者不需要做额外的适配就能平滑过渡。

执行流程

请添加图片描述
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

dyld 4 (2022)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/788728.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2引入lottie动画

说明下:如果你是vue3的话请移步:https://blog.csdn.net/qq_67801847/article/details/128386661,这里只针对vue2. 同时动画官网链接:lottie官网 实现思路: 1. 安装lottie-web (版本无所谓) 2. 在使用的页面引入组件 #…

一起来看看音频转文字怎么弄吧

从前有一个名叫小明的学生,他在学校里总是很喜欢录制各种有趣的音频,包括老师的讲课、同学们的笑声,以及校园里的各种声音。有一天,他在课堂上录下了老师的授课内容,想着晚上回家后再将它们转换成文字,便于…

网络安全(黑客)学习手册

1.什么是网络安全? 网络安全可以基于攻击和防御视角来分类,我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一是市场需求量高; 二则是发展…

Python+大数据开发拿到25k的offer!

随着95后、00后的登场,80后好似成为“古早”的存在,看似被生活磨平了棱角的他们,其实也在渴望重新“支棱”起来。今天分享的这位80后的逆袭故事,希望你能感受到他的力量…… 学科 | Python大数据开发 校区 | 北京 薪资 | 25k 我…

【深度学习之YOLO8】视频流推断

官方V8模型下载 需要准备两个东西 simsun.ttc字体包YOLOv8官方模型成品 ScreenCapture屏幕图像类 import cv2 import mss import numpy as npclass ScreenCapture:"""parameters----------screen_resolution : Tuple[int, int]屏幕宽高,分别为x&a…

5.2.11.添加读写接口

5.2.11.添加读写接口 5.2.11.1、在驱动中添加 5.2.11.2、在应用中添加 5.2.11.3、测试 1. app.c #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>#define FILE "/dev/test" // 刚才mknod创建的设…

K8S中网络如何通信

Kubernetes 提出了一个自己的网络模型“IP-per-pod”&#xff0c;能够很好地适应集群系统的网络需求&#xff0c;它有下面的这 4 点基本假设&#xff1a; 集群里的每个 Pod 都会有唯一的一个 IP 地址。Pod 里的所有容器共享这个 IP 地址。集群里的所有 Pod 都属于同一个网段。…

WT588F02B-8S 血压计语音芯片如何选型?低功耗语音ic方案

一、血压计语音提示方案需求设计&#xff1f; 血压计语音提示方案的需求设计是为了实现在测量血压过程中&#xff0c;通过语音提示用户操作指引、测量结果和健康建议等功能。以下是血压计语音提示方案需求设计的主要需求&#xff1a; &#xff08;1&#xff09;测量操作引导 …

QT---day1(QT的介绍、常用类及组件)

代码&#xff1a; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//设置窗口尺寸this->setFixedSize(600,500);//设置窗口标题this->setWindowTitle(&q…

【MySQL】库和表的操作

目录 一、库的操作 1.1创建数据库 1.2创建数据库案例 1.3字符集和校验规则 &#xff08;1&#xff09;查看系统默认字符集以及校验规则 &#xff08;2&#xff09;查看数据库支持的字符集 &#xff08;3&#xff09;查看数据库支持的字符集校验规则 &#xff08;4&…

万向节死锁

要理解万向节死锁的产生原因&#xff0c;首先要理解欧拉角变换&#xff0c;欧拉角变换是基于最初始的坐标进行变换而非变换后的坐标进行变换。 欧拉角变换需要空间中的三个角&#xff08;即变换后每个轴的偏移量&#xff09;&#xff0c;另外还有每个轴的变换顺序。值得注意的…

SpringSecurity6--认证和授权的原理

SpringSecurity6–认证和授权的原理&#xff0c;项目gitee地址在文章末尾。 文章目录 一、Spring Security简介二、Spring Security框架中认证流程中几个非常重要的类1、 FilterChainProxy2、 AbstractAuthenticationProcessingFilter3、 UsernamePasswordAuthenticationFilter…

打开Android device monitor

X:\assdk\tools monitor.bat 双击 更新到最新

如何优雅地下载huggingface上模型,以llama2模型下载为例

背景 由于llama2模型的下载需要经过官方的授权&#xff0c;这就需要登陆hugging face的&#xff0c;对模型页面进行申请。等待审核通过后&#xff0c;才能够下载。如果在单纯用 git lfs 的方式进行下载&#xff0c;需要输入账号和密码。为了更快速地进行下载&#xff0c;既能够…

Java刷题记录(小白边刷边学)7.25

Java刷题记录&#xff08;小白边刷边学&#xff09;7.25 1 最长公共前缀 题目分析: 首先一定需要创建一个数组存储最长公共前缀的值 为了方便比较&#xff0c;先把strs的第一个字符串放进新的数组中即strs[0] 因此比较时从strs【1】开始 数字j需要小于两个被比较的字符串的长度…

视频超分新方法--助力实现高清wav2lip数字人

文章目录 前言一、解决方案详解总结前言 ` 随着人工智能的不断发展,数字人技术也越来越重要,很多人都开启了学习模型 但是使用神级模型wav2lip生成的数字人嘴部不清晰怎么办。 很影响使用效果,接下来教大家如何优化这个问题,如下图所示: 一、解决方案详解 因为wav2lip是…

Centos8+Jenkins+微信小程序前端自动发布体验版

文章目录 **一、 实现&#xff1a;****二、项目&#xff1a;****三、环境配置&#xff1a;****四、步骤&#xff1a;****五、遇到的问题** 一、 实现&#xff1a; jenkins打通微信开发平台&#xff0c;自动上传代码 二、项目&#xff1a; 微信小程序原生开发 三、环境配置&…

PowerPoint如何修改“默认保存路径”?

很多时候&#xff0c;我们做好PPT后都要保存&#xff0c;一般会保存在创建PPT的文件夹里&#xff0c;或者另外设置保存的路径。 如果经常需要制作PPT&#xff0c;又不想每次都要重新选择保存位置&#xff0c;我们可以创建或修改“默认保存路径”&#xff0c;这样每次关闭PPT后…

集群及LVS简介、LVSNAT模式原理、LVSNAT模式配置、LVSDR模式原理、LVSDR模式配置、LVS错误排查

day01 day01集群LVS配置LVS NAT模式配置LVS NAT模式步骤LVS DR模式配置LVS DR模式 集群 将很多机器组织到一起&#xff0c;作为一个整体对外提供服务 集群在扩展性、性能方面都可以做到很灵活 集群分类&#xff1a; 负载均衡集群&#xff1a;Load Balance高可用集群&#x…

wangeditor编辑器配置

vue项目中使用编辑器&#xff0c;轻量&#xff0c;操作栏选取自己需要的 官网地址&#xff1a;用于 Vue React | wangEditor 使用在vue项目中引入 npm install wangeditor/editor --savenpm install wangeditor/editor-for-vue --save 封装成组件使用 <template>&…