【DeepSeek】ELF 中的PT_LOAD

张开发
2026/4/14 9:38:07 15 分钟阅读

分享文章

【DeepSeek】ELF 中的PT_LOAD
在 ELFExecutable and Linkable Format文件格式中PT_LOAD是程序头表中最重要的段类型。以下是对PT_LOAD的定义、具体包含的种类以及与其类似的其他段类型的完整解析。1. 什么是PT_LOAD定义PT_LOAD表示一个可加载段。当操作系统加载器将 ELF 文件加载到内存中执行时它会遍历程序头表寻找所有类型为PT_LOAD的段并根据其描述信息将文件中的数据映射到进程的虚拟地址空间中。核心机制它是磁盘文件与内存镜像之间的桥梁。PT_LOAD告诉操作系统从哪里读文件中的偏移量 (p_offset)。放到哪里内存中的虚拟地址 (p_vaddr)。读多少文件中的大小 (p_filesz)。占多大内存中的大小 (p_memsz)。注意如果p_memszp_filesz多余的部分会被填充为 0这通常用于.bss段即未初始化的全局变量。权限如何读 (PF_R)、写 (PF_W)、执行 (PF_X) 权限。2. PT_LOAD 包含的具体种类虽然PT_LOAD在 ELF 头中只是一个常量值值为 1但在实际二进制文件中根据内存权限和包含的具体内容它逻辑上划分为几种固定的种类。一个标准的 ELF 可执行文件通常包含2 到 3 个PT_LOAD段。A. 代码段这是程序中最核心的PT_LOAD段通常也是第一个被加载的。权限标志PF_X | PF_R可读、可执行通常不可写。包含的内容.text主要的程序机器指令。.init/.fini程序初始化和结束时的代码。.plt动态链接的跳转桩代码。.interp动态链接器路径字符串需加载到内存供内核读取。.rodata只读数据如字符串常量有时会合并在此段中。特点在内存中多个进程可以共享同一个物理页节省内存。B. 数据段这是用于存储程序运行时状态数据的段。权限标志PF_W | PF_R可读、可写通常不可执行。包含的内容.data已初始化的全局变量和静态变量。.bss未初始化的全局变量。特殊处理在段描述中p_filesz不包含.bss的大小但p_memsz包含。加载器会将多余的内存空间清零。.got全局偏移表。.dynamic动态链接信息物理数据存储于此。特点这是进程私有的每个进程运行时都有独立的副本数据会在运行中发生修改。C. 只读数据段现代链接器为了安全性和性能优化有时会将只读数据从代码段中剥离出来单独作为一个PT_LOAD段。权限标志PF_R仅可读不可写不可执行。包含的内容.rodata字符串常量、虚函数表。.eh_frame_hdr异常处理信息。存在的意义增强安全性防止代码执行攻击。映射关系示意表PT_LOAD 种类典型包含的 Section (节)典型权限说明LOAD #1 (代码).text,.init,.plt,.rodataR-X最基础的指令段。LOAD #2 (数据).data,.bss,.got,.dynamicRW-可读写的数据段。LOAD #3 (只读数据).rodata,.noteR--(可选) 现代安全加固模式下常独立出来。3. 类似的定义有哪些程序头类型对比在 ELF 标准中除了PT_LOAD还有多种段类型。它们虽然也是“段”但大多数不直接加载用户代码数据而是提供元数据或特殊功能。A. 核心标准类型类型名称含义与PT_LOAD的关系/区别PT_NULL未使用/忽略程序头数组的第一个条目通常作为占位符使用。PT_DYNAMIC动态链接信息指向动态链接段包含.dynamic节。它告诉动态链接器需要哪些共享库。它通常位于一个PT_LOAD段内部。PT_INTERP程序解释器指定要使用的动态链接器路径如/lib64/ld-linux-x86-64.so.2。它本身不加载代码而是告诉系统“先运行这个解释器来加载我”。PT_NOTE辅助信息用于存储构建信息、ABI 版本等元数据。加载器通常忽略其内容。PT_PHDR程序头表自身指定程序头表在内存中的位置和大小。PT_TLS线程局部存储定义线程局部存储的模板。每个线程运行时都会根据此段拥有一份独立的数据副本。B. 特定于架构或扩展的类型 (常见于 Linux)类型名称含义作用PT_GNU_EH_FRAME异常处理帧用于 C 异常处理帮助运行时快速查找异常处理代码。PT_GNU_STACK栈权限控制非常重要。它不加载任何数据而是用来控制栈内存的权限是否可执行。如果权限不可执行则开启NX保护防止缓冲区溢出攻击。PT_GNU_RELRO只读重定位用于安全加固。指示加载器在完成重定位后将特定的内存区域如 GOT 表设置为只读防止运行时被篡改。4. 总结可以将 ELF 加载过程类比为搬运和 setup 一个房间PT_LOAD是**“货物”**集装箱里的东西如家具、电器。这是唯一真正占用进程物理/虚拟内存空间、包含实际指令和数据的段。PT_DYNAMIC/PT_INTERP是**“说明书”或“搬运工信息”**告诉系统怎么组装、需要谁帮忙。PT_GNU_STACK/PT_GNU_RELRO是**“安全守则”**规定哪些地方不能放东西、哪些地方要上锁。操作系统加载器的核心逻辑就是遍历程序头表把所有PT_LOAD段映射到内存然后根据PT_INTERP调用动态链接器处理依赖最后跳转执行。

更多文章