musl libc ldso 动态加载研究笔记:02

前言

  • 本篇继续研究 musl libc ldso 的动态加载过程中遇到的关键性的概念:到底要加载ELF 文件的哪些内容到 内存

  • 当前如果遇到 ELF 动态加载,当前系统需要有【文件系统】,并且有较大的内存,因为 ELF 文件是无法直接运行的,首先通过解析 ELF 头部 获取入口函数,把需要载入到内存中的文件内容复制到指定内存区域,然后执行ELF 的入口函数,通常不是 ELF的 main 函数,而是更早的执行函数,如 _start 或者 _dlstart 函数。此时 PC 指针指向 ELF 加载的基地址 + ELF 入口函数。

ELF 加载基地址

  • 一个 ELF 文件,是否可以随意的加载?

当前验证发现: ELF 文件包括我们通常见到的 可以执行的文件,以及 共享库(如 xx.so)。共享库没有连接地址,基址是 0,但入口函数不一定是 0,如果遇到入口函数也是 0 的,需要注意这个 偏移地址 为 0 的入口函数,是否只是个空的符号,无法执行

  • 为何有的 xxx.so 也称作 ELF 文件? 比如 musl libc.so,本身是个 库,但是它 有入口函数,并且可以执行。 当前 musl libc.so 确实如此,通常我们一般区分 执行文件与 库,库不用于执行。但是 musl libc.so 具备执行的功能,就像是我们见到的普通的执行文件,但是它依旧具备普通库的功能,为其他动态编译的应用程序提供共享库。

  • 作为 共享库与可执行 集成在一起的 musl libc.so,基地址:0,入口函数不为0,基地址为0 可以重定位加载,如手动把 libc.so 加载到 0x200000 地址, 那么 libc.so 的入口函数就是: 0x200000 + libc.so 入口地址

  • 普通静态或者动态链接的ELF 文件,由于基地址 不为0,就无法手动加载到 随意的地址。

  • 如下 ELF 文件:基地址 0x200000,这个基地址跟链接脚本中的链接地址有关系,可以查看这个 elf 的连接脚本配置

  • 入口点:入口地址,这个地址 已经是基于基地址 0x200000的,所以这个地址就不能随机加载了。如果想改变 这个 elf 的基地址,需要更改 相应的 链接脚本 链接地址的设置

在这里插入图片描述

动态加载需要加载哪些 ELF 内容到内存

  • 有的 ELF 文件特别的大,尤其是开启了 【DEBUG】的,比如编译时使用 -O0 -g, gdb 的调试信息都加入 ELF 文件了, ELF 文件不同于单片机的烧写文件 bin 文件,里面还有一些内容,如调试信息,是不需要加载到内存的,那么到底需要加载什么内容呢?

  • 这部分可以查看 Linux 内核代码 elf 加载部分,如 linux-6.3.8/fs/binfmt_elf.c 中的 load_elf_binary

  • Linux 系统由于默认支持 mmu,执行文件的 mmap 映射,所以没有文件没有使用常规的 内存分配,不过依旧是先把文件内容映射 到用户地址空间,之所以不填充,是因为 Linux文件mmap 有缺页异常机制,需要访问时才会真正载入文件内容到内存,这样有很多好处,开始只映射(占位子)不加载,这样节省了加载时间,一个 ELF 文件,不可能上来全部执行到,可能只会执行部分内容,这样采用 访问时再加载,将会节省数量可观的内存,节省大量的加载时间。加上文件 mmap 有 cache 功能,如果加载过后,缓存暂时不清掉,这样下次执行就不再重复加载了。Linux 这个文件mmap 映射加载机制,对于 ELF 加载非常的有用。

  • 经过熟悉 Linux 的 load_elf_binary ,发现只需要 加载 PT_LOAD

  • 那么 ELF 的 PT_LOAD 段,真的覆盖 ELF 的所有需要加载到内存中的内容范围吗?有没有漏下的?或者说 elf 不是还有 重定位、符号、.text.data、等等吗?这些包含在里面吗?

  • 通过 elf 查看工具,加上对实际加载到内存的内容进行反向 dump 出来,肯定的一点就是: ELF 的 PT_LOAD 段 包含了所有需要加载到内存的文件内容,是所有,如果在其他的系统上,发现动态加载后, 内存中的文件内容不正确,或者部分内容为0,需要查看文件加载部分是否有处理不当的地方。

查看 PT_LOAD

  • 可以使用 Die 这个工具,查看 ELF文件

在这里插入图片描述

  • 这里了解到, PT_LOAD 段 第一个段 文件偏移是 0,也就是把 ELF 文件头部也加入了内存

  • 两个 PT_LOAD 段 的大小:Program 中的 p_filesz 就是当前的段大小,总大小: 0x23528 + 0x9f8 = 0x23f20,之所以这么计算,是因为 当前的两个段 是连在一起的。

  • 由于段有多个节(section),可以查看 节 信息,

在这里插入图片描述

  • 通过 计算 PT_LOAD 段的总大小,知道 这个 elf 文件 前面 0 ~ (0x23f20 -1) ,也就是 0x23f20 个字节已经加载到内存,剩下 的节,.bss 没有实际内容,但内存中需要留位置,并且清 0。其他的节全部是 调试信息 debug 相关的。

  • 所以通过加载 PT_LOAD 段,确实实现了整个 ELF 必需文件内容的全部加载

加载大小

  • 这里需要提一下:段的加载大小,不是 段的 p_filesz,而是 段的 p_memsz, p_memsz 一般等于或者大于 p_filesz,超出的大小,就是 .bss section 的大小,这部分大小需要手动清零,不清零,可能引发程序启动后的异常,比如定义了一个变量,但是没有初始化就使用,而程序员默认没有初始化的变量会被初始化 为 0。 清零 .bss 就是清零 PT_LOAD 段 中 p_memsz - p_filesz 大小的区域,这个区域的起始地址应该是: base +elf_ppnt->p_vaddr + elf_ppnt->p_filesz,如果是静态连接编译的 elf 程序, base 是0,也就是 elf_ppnt->p_vaddr + elf_ppnt->p_fileszelf_ppnt->p_vaddr 是这个文件段的起始地址。

  • 这里需要提一下: 段的 p_offset,这个是相对文件本身的偏移,通过情况下, p_offsetp_vaddr 是相同的,但也有不相同的。所以在文件填充时,需要把 文件内容 偏移 p_offset 后,读取到内存地址 p_vaddr 的位置,也就是说: 文件内容的存放位置 与 文件映射到内存的地址,并非一一对应。

在这里插入图片描述

小结

  • 本篇注意讲解一下 ELF文件在 动态加载时需要加载哪些内容到内存,注意这里的动态加载,是动态加载 ELF 文件,这个 ELF文件,不单是 动态编译链接的 ELF,也包括静态编译链接的 ELF 以及 经常遇到的 动态共享库 (xx.so)

  • 需要熟悉 ELF 的 头部、Program Header、了解 各个 Segment 段,了解 Section 节信息,这样对理解 动态加载程序,熟悉 动态加载非常有用。

  • 需要了解操作系统的进程、线程机制,文件映射 mmap 机制。注意需要反复确认 内存的文件内容是否正确、完整。可以同 dump 的方式,把内存中的文件内容 dump 成一个文件,然后与实际的文件进行内容对比。

  • 需要深刻了解 文件段的本身的偏移 :p_offset 与 内存地址 p_vaddr 的关系,也需要了解 段真实文件大小 p_filesz 与 p_memsz 的关系,也就是 .bss 节的存在

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何快速的合并多个PPT使之成为一个PPT?

如何快速的合并多个PPT使之成为一个PPT? 项目过程中,经常给客户汇报,经常做PPT,有时候,需要把之前的ppt内容整合到新的内容中,如何快速合并以及使用呢? 幻灯片(PPT中)点…

JMeter接口自动化测试实例—JMeter引用javaScript

Jmeter提供了JSR223 PreProcessor前置处理器,通过该工具融合了Java 8 Nashorn 脚本引擎,可以执行js脚本以便对脚本进行前置处理。其中比较典型的应用就是通过执行js脚本对前端数据进行rsa加密,如登录密码加密。但在这里我就简单的应用javaScr…

7.maven

1 初始Maven 1.1 什么是Maven Maven是Apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。 官网:https://maven.apache.org/ Apache 软件基金会,成立于1999年7月,是目前世界上最大的最受欢迎的开源软件基金会&…

AI工程师招募;60+开发者AI工具清单;如何用AI工具读懂插件源码;开发者出海解读;斯坦福LLM课程 | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🤖 一则AI工程师招募信息:新领域需要新技能 Vision Flow (目的涌现) 是一家基于 AGI 原生技术的创业公司,是全球探…

Harmony OS教程学习笔记

基础知识 1.如何修改程序启动的第一个页面? 不想使用创建的默认的页面,这时需要修改启动页面,修改的地方在EntryAbility文件中的onWindowStageCreate方法中。 onWindowStageCreate(windowStage: window.WindowStage) {// Main window is cr…

Java中的异常

认识异常 异常就是程序出现的问题; Integer.valueOf("aaaa"); 异常体系 因为写代码时经常会出现问题,Java的设计者们早就为我们写好了很多个异常类,来描述不同场景下的问题。而有些类是有共性的所以就有了异常的继承体系 Error&…

【Windows系统编程】03.远线程注入ShellCode

shellcode&#xff1a;本质上也是一段普通的代码&#xff0c;只不过特殊的编程手法&#xff0c;可以在任意环境下&#xff0c;不依赖于原有的依赖库执行。 远程线程 #include <iostream> #include <windows.h> #include <TlHelp32.h>int main(){HANDLE hPr…

[JavaWeb]【六】web后端开发-请求响应

前言&#xff1a;请求响应 目录 一 引子 二 请求 2.1 Postman 2.1.1 安装 2.1.2 创建工作空间 2.1.3 添加接口 2.2 简单参数 2.2.1 原始方式&#xff08;不推荐&#xff09; 2.2.2 SpringBoot方式-GET(参数名与形参变量名相同) 2.2.3 SpringBoot方式-POST(参数名与形参…

苹果iOS16曝出新漏洞:飞行模式下依旧可连接网络

近日&#xff0c;网络安全研究人员发现iOS 16存在一种新的漏洞利用后持久化技术&#xff0c;即使受害者的苹果设备处于离线状态&#xff0c;也可以利用该技术悄无声息地访问该设备。 Jamf Threat Labs 的研究人员 Hu Ke 和 Nir Avraham 在与 The Hacker News 分享的一份报告中…

【C++】AVL树(平衡二叉树)

目录 一、AVL树的定义二、AVL树的作用三、AVL树的插入操作插入——平衡因子的更新插入——左单旋插入——右单旋插入——左右双旋插入——右左双旋 四、ALVL树的验证五、AVL树的性能 一、AVL树的定义 AVL树&#xff0c;全称 平衡二叉搜索&#xff08;排序&#xff09;树。 二…

广州华锐互动:3D数字孪生开发编辑器助力企业高效开发数字孪生应用

3D数字孪生开发编辑器是一种新兴的技术&#xff0c;它可以帮助企业更好地管理和维护其物联网设备。这些工具可以帮助企业实现对设备的实时监控、故障排除和优化&#xff0c;从而提高生产效率和降低成本。 数字孪生系统是一种将物理世界与数字世界相结合的技术&#xff0c;它可以…

openGauss学习笔记-43 openGauss 高级数据管理-事件触发器

文章目录 openGauss学习笔记-43 openGauss 高级数据管理-事件触发器43.1 语法格式43.2 参数说明43.3 示例 openGauss学习笔记-43 openGauss 高级数据管理-事件触发器 触发器会在指定的ddl事件发生时自动执行函数。目前事件触发器仅在PG兼容模式下可用。 43.1 语法格式 创建事…

BIO、NIO和AIO

一.引言 何为IO 涉及计算机核心(CPU和内存)与其他设备间数据迁移的过程&#xff0c;就是I/O。数据输入到计算机内存的过程即输入&#xff0c;反之输出到外部存储&#xff08;比如数据库&#xff0c;文件&#xff0c;远程主机&#xff09;的过程即输出。 I/O 描述了计算机系统…

韦东山-电子量产工具项目:页面系统

代码结构 所有代码都已通过测试跑通&#xff0c;其中代码结构如下&#xff1a; 一、include文件夹 1.1 common.h #ifndef _COMMON_H #define _COMMON_Htypedef struct Region {int iLeftUpX; //区域左上方的坐标int iLeftUpY; //区域左下方的坐标int iWidth; //区域宽度…

爬虫逆向实战(三)--天某云登录

一、数据接口分析 主页地址&#xff1a;天某云 1、抓包 通过抓包可以发现登录接口是account/login 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过“载荷”模块可以发现password、comParam_signature、comParam_seqCode是加密的 请求头是否加密&#xff1f; 无…

Lnton羚通关于PyTorch的保存和加载模型基础知识

SAVE AND LOAD THE MODEL (保存和加载模型) PyTorch 模型存储学习到的参数在内部状态字典中&#xff0c;称为 state_dict, 他们的持久化通过 torch.save 方法。 model models.shufflenet_v2_x0_5(pretrainedTrue) torch.save(model, "../../data/ShuffleNetV2_X0.5.pth…

港科夜闻|香港科大校长叶玉如教授、香港科大(广州)校长倪明选教授等两校领导共同出席香港科大(广州)首批本科新生见面会...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大校长叶玉如教授、香港科大(广州)校长倪明选教授等两校领导共同出席香港科大(广州)首批本科新生见面会。8月16日&#xff0c;香港科大(广州)首批本科新生参加了一次具有特殊意义的见面会。香港科大、香港科大(广州…

山西电力市场日前价格预测【2023-08-20】

日前价格预测 预测明日&#xff08;2023-08-20&#xff09;山西电力市场全天平均日前电价为341.71元/MWh。其中&#xff0c;最高日前电价为367.66元/MWh&#xff0c;预计出现在20: 30。最低日前电价为318.47元/MWh&#xff0c;预计出现在04: 15。 价差方向预测 1&#xff1a; 实…

Flink CDC系列之:基于 Flink CDC 构建 MySQL 和 Postgres 的 Streaming ETL

Flink CDC系列之&#xff1a;基于 Flink CDC 构建 MySQL 和 Postgres 的 Streaming ETL 一、技术路线二、MySQL数据库建表三、PostgreSQL数据库建表四、在 Flink SQL CLI 中使用 Flink DDL 创建表五、关联订单数据并且将其写入 Elasticsearch 中六、Kibana查看商品和物流信息的…

【Hibench 】完成 HDP-Spark 性能测试

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的…