ELF文件头结构

转自 https://blog.youkuaiyun.com/tangyuesb/article/details/54630787

ELF文件头结构定义在“/usr/include/elf.h”头文件下,ELF文件有32位版本和64位版本,故其头文件结构也有32位结构和64位结构,分别定义为Elf32_Ehdr和Elf64_Ehdr。两种版本文件内容一样,只是有些成员的大小不一样。以下是32位版本的文件头结构Elf32_Ehdr。

typedef struct{
    unsigned char e_ident[EI_NIDENT];
    Elf32_Half e_type;
    Elf32_Half e_machine;
    Elf32_Word e_version;
    Elf32_Addr e_entry;
    Elf32_Off  e_phoff;
    Elf32_Off  e_shoff;
    Elf32_Word e_flags;
    Elf32_Half e_ehsize;
    Elf32_Half e_phentsize;
    Elf32_Half e_phnum;
    Elf32_Half e_shentsize;
    Elf32_Half e_shnum;
    Elf32_Half e_shstrndx;
}Elf32_Ehdr;

readelf -h test.o 可得如下输出:

ELF 头:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF32
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              REL (可重定位文件)
  系统架构:                          Intel 80386
  版本:                              0x1
  入口点地址:               0x0
  程序头起点:          0 (bytes into file)
  Start of section headers:          916 (bytes into file)
  标志:             0x0
  本头的大小:       52 (字节)
  程序头大小:       0 (字节)
  Number of program headers:         0
  节头大小:         40 (字节)
  节头数量:         14
  字符串表索引节头: 11
  • 我们将Elf32_Ehdr结构与readelf命令输出的信息对比可得如下对应关系:
成员readelf输出结果
e_identMagic,类别,数据,版本,OS/ABI,ABI
e_type类型
e_machine系统架构
e_version版本
e_entry入口点地址
e_phoffstart of program headers
e_shoffstart of section headers
e_flags标志
e_ehsize文件头的大小
e_phentsize程序头大小
e_phnumnumber of program headers
e_shentsize节头大小
e_shnumnumber of program headers
e_shstrndx字符串表段索引

下面我们依次分析各个部分。

魔数: 
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
7f 、45、4c、46分别对应ascii码的Del(删除)、字母E、字母L、字母F。这四个字节被称为ELF文件的魔数,操作系统在加载可执行文件时会确认魔数是否正确,如果不正确则拒绝加载。 
第五个字节标识ELF文件是32位(01)还是64位(02)的。 
第六个字节标识该ELF文件字节序是小端(01)还是大端(02)的。 
第七个字节指示ELF文件的版本号,一般是01。 
后九个字节ELF标准未做定义。一般为00.

文件类型: 
类型: REL (可重定位文件) 
e_type成员标识文件类型,ELF文件有三种类型,如下表所示。

常量标识类型
ET_REL1可重定位文件,一般位.o文件
ET_EXEC2可执行文件
ET_DYN3共享目标文件,一般位.so文件

系统架构: 
系统架构: Intel 80386 
e_machine成员标识系统架构(机器类型),ELF定义了以下多种系统架构。可在“/usr/include/elf.h”头文件中查看,以下是其中的几种

常量标识系统架构
EM_M321AT&T WE 32100
EM_SPARC2SPARC
EM_3863Intel 80386
EM_68K4Motorola m68k family
EM_88K5Motorola m88k family
EM_8606Intel 80860
### 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、付费专栏及课程。

余额充值