Linux中ELF区域与文件偏移量的关系

ELF(Executable and Linkable Format)是Linux系统中可执行文件、目标文件和共享库的标准格式。理解ELF文件中各个区域与文件偏移量之间的关系对于程序分析、调试和逆向工程至关重要。

目录

一、ELF文件基本结构

[二、关键概念:虚拟地址(VMA) vs 文件偏移量(Offset)](#二、关键概念:虚拟地址(VMA) vs 文件偏移量(Offset))

三、ELF头与文件偏移量

四、程序头表与段(Segments)

五、节头表与节(Sections)

六、常见节区及其偏移量关系

七、地址转换示例

八、使用工具查看ELF信息

九、实际应用场景


一、ELF文件基本结构

ELF文件由以下几部分组成:

  1. ELF头(ELF Header)

  2. 程序头表(Program Header Table) - 用于程序加载

  3. 节头表(Section Header Table) - 用于链接和调试

  4. 各种节(Sections)和段(Segments)


二、关键概念:虚拟地址(VMA) vs 文件偏移量(Offset)

  • 文件偏移量(Offset): 指数据在ELF文件中的物理位置,从文件开始计算的字节数

  • 虚拟地址(VMA, Virtual Memory Address): 指该数据在进程虚拟地址空间中的位置

  • 加载地址(LMA, Load Memory Address): 指数据在物理内存中的位置(通常与VMA相同)


三、ELF头与文件偏移量

ELF头总是位于文件的起始位置(偏移量0),包含以下关键信息:

cpp 复制代码
#define EI_NIDENT 16

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;
  • e_phoff: 程序头表在文件中的偏移量

  • e_shoff: 节头表在文件中的偏移量


四、程序头表与段(Segments)

程序头表描述了如何将文件映射到进程地址空间,每个条目(程序头)描述一个段:

cpp 复制代码
typedef struct {
    Elf32_Word p_type;   // 段类型
    Elf32_Off  p_offset; // 段在文件中的偏移量
    Elf32_Addr p_vaddr;  // 段的虚拟地址
    Elf32_Addr p_paddr;  // 段的物理地址
    Elf32_Word p_filesz; // 段在文件中的大小
    Elf32_Word p_memsz;  // 段在内存中的大小
    Elf32_Word p_flags;  // 段权限标志
    Elf32_Word p_align;  // 段对齐方式
} Elf32_Phdr;

关键字段关系:

  • p_offset → 文件偏移量

  • p_vaddr → 虚拟地址

  • 运行时加载器会将p_offset处的p_filesz字节数据映射到p_vaddr地址


五、节头表与节(Sections)

节头表描述了文件中的各个节,主要用于链接和调试:

cpp 复制代码
typedef struct {
    Elf32_Word sh_name;      // 节名称字符串表索引
    Elf32_Word sh_type;      // 节类型
    Elf32_Word sh_flags;     // 节标志
    Elf32_Addr sh_addr;      // 节在内存中的地址
    Elf32_Off  sh_offset;    // 节在文件中的偏移量
    Elf32_Word sh_size;      // 节大小
    Elf32_Word sh_link;      // 链接到其他节
    Elf32_Word sh_info;      // 附加信息
    Elf32_Word sh_addralign; // 节对齐要求
    Elf32_Word sh_entsize;   // 条目大小(如果有)
} Elf32_Shdr;

关键字段关系:

  • sh_offset → 文件偏移量

  • sh_addr → 虚拟地址(如果该节会被加载到内存)


六、常见节区及其偏移量关系

以下是典型ELF文件中的常见节区及其与文件偏移量的关系:

  1. .text节: 包含可执行代码

    • sh_offset: 代码在文件中的位置

    • sh_addr: 代码在内存中的虚拟地址

  2. .data节: 包含已初始化的全局变量

    • sh_offset: 数据在文件中的位置

    • sh_addr: 数据在内存中的虚拟地址

  3. .bss节: 包含未初始化的全局变量

    • sh_offset: 通常为0(因为.bss不占用文件空间)

    • sh_addr: 内存中的虚拟地址

    • sh_size: 需要在内存中分配的大小

  4. .rodata节: 只读数据

    • sh_offset: 只读数据在文件中的位置

    • sh_addr: 只读数据在内存中的虚拟地址

  5. .symtab/.strtab节: 符号表和字符串表

    • sh_offset: 符号信息在文件中的位置

    • sh_addr: 通常为0(这些节不会被加载到内存)


七、地址转换示例

假设一个简单的ELF文件布局:

cpp 复制代码
文件偏移量   内容
0x000       ELF头
0x034       程序头表
0x100       .text节 (文件大小0x200)
0x300       .data节 (文件大小0x100)
0x400       节头表

对应的程序头可能如下:

cpp 复制代码
p_type=PT_LOAD, p_offset=0x100, p_vaddr=0x08048000, p_filesz=0x200, p_memsz=0x200
p_type=PT_LOAD, p_offset=0x300, p_vaddr=0x08049000, p_filesz=0x100, p_memsz=0x120

地址转换关系:

  • 文件偏移0x100处的代码 → 虚拟地址0x08048000

  • 文件偏移0x300处的数据 → 虚拟地址0x08049000


八、使用工具查看ELF信息

  1. readelf: 查看ELF文件结构

    bash 复制代码
    readelf -h file    # 查看ELF头
    readelf -l file    # 查看程序头
    readelf -S file    # 查看节头
  2. objdump: 反汇编和查看节信息

    bash 复制代码
    objdump -h file    # 查看节信息
    objdump -d file    # 反汇编代码
  3. nm: 查看符号表

    bash 复制代码
    nm file

九、实际应用场景

  1. 调试器使用: 调试器需要将虚拟地址转换为文件偏移量来定位源代码

  2. 二进制补丁: 修改文件时需要知道要修改的数据在文件中的位置

  3. 动态链接: 动态链接器需要解析重定位信息,涉及地址计算

  4. 核心转储分析: 将核心文件中的地址映射回原始文件位置

理解ELF区域与文件偏移量之间的关系是Linux系统编程和逆向工程的基础知识,对于深入理解程序加载和执行过程至关重要。

相关推荐
大树8824 分钟前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠27 分钟前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质1 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush41 小时前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5201 小时前
Linux 11 动态监控指令top
linux
小宇宙Zz1 小时前
Maven依赖冲突
java·服务器·maven
Inhand陈工2 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智2 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
不会C语言的男孩2 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
shushangyun_2 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化