当前位置: 首页 > news >正文

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

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

目录

一、ELF文件基本结构

二、关键概念:虚拟地址(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),包含以下关键信息:

#define EI_NIDENT 16typedef 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)

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

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)

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

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文件布局:

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

对应的程序头可能如下:

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文件结构

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

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

    nm file

九、实际应用场景

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

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

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

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

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

http://www.lryc.cn/news/594785.html

相关文章:

  • 开源 Arkts 鸿蒙应用 开发(八)多媒体--相册和相机
  • 一个适合MCU的分级菜单框架
  • 格式工厂5.21.0简介
  • 设计模式六:工厂模式(Factory Pattern)
  • 从安装到上手:Ubuntu 22.04 玩转 Containerd 2.1.3 容器运行时
  • 在 Windows上用WSL和VSCode进行Linux开发环境配置
  • 《使用 IDEA 部署 Docker 应用指南》
  • 在Anolis8.6上源码编译安装部署OpenVAS(GVM)未完待续
  • git bash命令不够完善,想整合msys2该怎么办?
  • Dynamics 365 Contact Center是什么
  • Java 解析前端上传 ZIP 压缩包内 Excel 文件的完整实现方案
  • 前端开发者快速理解Spring Boot项目指南
  • 在 Angular 应用程序中使用 Genkit 的完整指南
  • docker 容器学习
  • Three.js 全景图(Equirectangular Texture)教程:从加载到球面映射
  • AR技术:应急响应的加速利器
  • AR技术:石化行业培训的“游戏规则改变者”
  • Web开发:ABP框架12——中间件Middleware的创建和使用
  • AR巡检和传统巡检的区别
  • CCLink IE转ModbusTCP网关与三菱PLC通讯无纸记录器
  • uni-app开发小程序,根据图片提取主题色值
  • 网络编程基础:从 OSI 模型到 TCP/IP 协议族的全面解析
  • Android 中 SystemServiceManager 和 ServiceManager 的应用场景、区别与联系
  • 漏洞扫描 + 渗透测试:双轮驱动筑牢网络安全防线
  • Ubuntu 22.04 使用 Docker 安装 Redis 5 (安装包形式)
  • 内网与外网是通过什么进行传输的?内外网文件传输的安全方法
  • C#最佳实践:为何应尽量减少静态类的使用
  • 迅为八核高算力RK3576开发板摄像头实时推理测试 RetinaFace人脸检测
  • Curtain e-locker 易锁防泄密:无需网络隔离,实现安全与效率并存
  • 大腾智能国产3D CAD软件正式上架华为云云商店