ELF的文件结构

本文详细解读了ELF文件的基本结构,包括ELFheader、程序头部表、动态链接相关节等,重点讲解了动态链接器、符号表、重定位信息和内存布局。

基本结构如下所示:

+====================+

+     ELF header     + // 包含了整个文件的基本属性,如:文件版本,目标机器型号,入口地址。

+====================+

+Program header table+ // 程序标头表是一组程序标头,它们定义了运行时程序的内存布局。对于.obj文件可选的

+====================+

+      .interp       + // 可执行文件所需要的动态链接器的位置。

+--------------------+

+   .note.ABI-tag    + // 用于声明ELF的预期运行时ABI。包括操作系统名称及其运行时版本。

+--------------------+

+ .note.gnu.build-id + // 表示唯一的构建ID位串。

+--------------------+

+     .gnu.hash      + // 符号hash表。若段名是.hash,则使用的是SYSV hash,其比gnu hash性能差。

+--------------------+

+      .dynsym       + // 动态符号表用来保存与动态链接相关的导入导出符号,不包括模块内部的符号。

+--------------------+

+      .dynstr       + // 动态符号字符串表,用于保存符号名的字符串表。静态链接时为.strtab

+--------------------+

+    .gnu.version    + // 表中条目与.dynsym动态符号表相同。每个条目指定了相应动态符号定义或版本要求。

+--------------------+

+   .gnu.version_r   + // 版本定义。

+--------------------+

+     .rela.dyn      + // 包含共享库(PLT除外)所有部分的RELA类型重定位信息。

+--------------------+

+     .rela.plt      + // 包含共享库或动态链接的应用程序的PLT节的RELA类型重定位信息。

+--------------------+

+       .init        + // 程序初始化段。

+--------------------+

+        .plt        + // 过程链接表(Procedure Linkage Table),用来实现延迟绑定。

+--------------------+

+      .plt.got      + // 暂无。。。。。

+--------------------+

+       .text        + // 代码段

+--------------------+

+       .fini        + // 程序结束段

+--------------------+

+      .rodata       + // 只读变量(const修饰的)和字符串变量。

+--------------------+

+      .rodata1      + // 据我所知,.rodata.rodata1是相同的。一些编译器会.rodata分为2个部分。

+--------------------+

+   .eh_frame_hdr    + // 包含指针和二分查找表,(一般在C++)运行时可以有效地从eh_frame中检索信息。

+--------------------+

+     .eh_frame      + // 它包含异常解除和源语言信息。此部分中每个条目都由单个CFI(呼叫帧信息)表示。

+--------------------+

+    .init_array     + // 包含指针指向了一些初始化代码。初始化代码一般是在main函数之前执行的。

+--------------------+

+    .fini_array     + // 包含指针指向了一些结束代码。结束代码一般是在main函数之后执行的。

+--------------------+

+      .dynamic      + // 保存动态链接器所需的基本信息。

+--------------------+

+        .got        + // 全局偏移表,存放所有对于外部变量引用的地址。

+--------------------+

+      .got.plt      + // 保存所有对于外部函数引用的地址。延迟绑定主要使用.got.plt表。

+--------------------+

+       .data        + // 全局变量和静态局部变量。

+--------------------+

+       .data1       + // 据我所知,.data.data1是相同的。一些编译器会.data分为2个部分。

+--------------------+

+        .bss        + // 未初始化的全局变量和局部局部变量。

+--------------------+

+      .comment      + // 存放编译器版本信息

+--------------------+

+   .debug_aranges   + // 内存地址和编译之间的映射

+--------------------+

+    .debug_info     + // 包含DWARF调试信息项(DIE)的核心DWARF数据

+--------------------+

+   .debug_abbrev    + // .debug_info部分中使用的缩写

+--------------------+

+    .debug_line     + // 程序行号

+--------------------+

+     .debug_str     + // .debug_info使用的字符串表

+--------------------+

+      .symtab       + // 静态链接时的符号表,保存了所有关于该目标文件的符号的定义和引用。

+--------------------+

+      .strtab       + // 默认字符串表。

+--------------------+

+     .shstrtab      + // 字符串表。

+====================+

+Section header table+ // 用于引用Sections的位置和大小,并且主要用于链接和调试目的。对于Exec文件可选

+====================+

### ELF 文件格式结构详解 ELF(Executable and Linkable Format)文件是一种广泛使用的标准文件格式,主要用于存储可执行文件、库以及目标代码。以下是其主要组成部分及其作用: #### 1. **ELF Header (头部)** ELF 头部是整个文件的第一个部分,它描述了文件的整体布局和其他重要信息。主要包括以下几个字段: - `e_ident`:用于识别文件是否为有效的 ELF 文件,并提供有关字节顺序的信息[^1]。 - `e_type`:定义文件的类型,例如可执行文件 (`ET_EXEC`) 或共享对象文件 (`ET_DYN`)。 - `e_machine`:指定目标机器架构,如 x86 或 ARM 架构[^4]。 - `e_version`:表示 ELF 的版本号。 - `e_entry`:程序入口地址,在加载到内存后会跳转至此位置运行。 - `e_phoff` 和 `e_shoff`:分别指向程序头表和节头表的位置。 #### 2. **Program Headers (程序头表)** 程序头表描述如何将文件中的各个段映射到进程的虚拟地址空间中。对于可执行文件来说,这是非常重要的部分之一。每个条目通常包含以下信息: - 类型 (`p_type`):指明此段的作用,比如 `.text` 段对应的是代码区域。 - 偏移量 (`p_offset`) 及大小 (`p_filesz`, `p_memsz`):表明数据在磁盘上的起始位置及长度。 - 权限标志 (`p_flags`):设置读写权限等属性。 #### 3. **Section Headers (节头表)** 虽然不是所有类型的 ELF 文件都需要有节头表,但对于调试或者链接阶段而言却是不可或缺的部分。通过这些记录可以找到源码对应的符号表、重定位信息等内容所在的具体地方。每一条记录都包含了名称索引(`sh_name`)、类型(`sh_type`)以及其他参数来进一步细化说明该区段的功能特性等等[^3]。 #### 4. **Sections & Segments** - 节(sections): 主要服务于静态分析工具, 如汇编器/连接器; 它们按逻辑分组原始资料. - 段(segments): 面向动态装载过程设计, 把实际需要载入RAM里的那部分内容组合起来形成连续区块. 此外还有其他辅助性的表格或数组也构成了完整的elf体系框架的一部分, 这些可能涉及但不限于字符串池(string table), 符号表(symbol table) 等等方面. ```python import struct def parse_elf_header(file_path): with open(file_path, 'rb') as f: e_ident = f.read(16) ei_class = e_ident[4] if ei_class != b'\x01' or ei_class != b'\x02': raise ValueError('Not a valid ELF file') # Read more fields... ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值