当前位置: 首页 > 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.dtcms.com/a/290673.html

相关文章:

  • 【AI论文】EXAONE 4.0:融合非推理模式与推理模式的统一大语言模型
  • Neovim 安装与解压 tar.gz 文件
  • AXI接口学习
  • Python 模块未找到?这样解决“ModuleNotFoundError”
  • Dev C++下载安装和使用教程(图文并茂,保姆级教程)
  • dolphinscheduler中sqoop无法执行
  • 机器人工程专业本科阶段的学习分析(腾讯元宝)
  • Real-World Blur Dataset for Learning and Benchmarking Deblurring Algorithms
  • 系统分析师-计算机系统-操作系统-存储器管理设备管理
  • Oracle From查看弹性域设置
  • (3)Oracle基本语法与常用函数
  • Oracle自治事务——从问题到实践的深度解析
  • 基于MySQL实现分布式调度系统的选举算法
  • CLIP与SIGLIP对比浅析
  • RuoYi配置多数据源失效
  • vscode 使用说明二
  • 前端图像视频实时检测
  • AJAX 概念与 axios 使用
  • AI探索 | 基于 Node.js 开发 MCP 客户端+服务端及优秀项目分享
  • 【华为机试】240. 搜索二维矩阵 II
  • Node.js- node管理工具nvm
  • Git上传与下载GitHub仓库
  • 新手向:基于Python的快捷启动器(本地应用/文件秒开工具)
  • 本地项目提交到git教程
  • 代码随想录算法训练营二十二天|回溯part04
  • 第十八节:第八部分:java高级:动态代理设计模式介绍、准备工作、代码实现
  • 【设计模式C#】简单工厂模式(用于简化获取对象实例化的复杂性)
  • Spring Boot注解详解
  • PDF 表单字段属性详解
  • 泛型:C#中的类型抽象艺术