c++如何读取和修改ELF可执行文件头_Linux二进制分析【附源码】

大强大大_9812

大强大大_9812

2026-03-24

244人浏览

原创

读取ELF文件头必须先验证魔数“\x7fELF”、EI_CLASS(64位)、EI_DATA(字节序),再安全解析;修改e_entry需确保其落在PT_LOAD段虚拟地址范围内,并整块覆写64字节头部,最后调用fsync。

c++如何读取和修改elf可执行文件头_linux二进制分析【附源码】

读取 ELF 文件头必须先验证魔数和架构

直接用 fread 读 sizeof(Elf64_Ehdr) 不等于拿到有效头——很多“ELF 文件”其实是脚本、损坏文件或非目标架构(比如在 x86_64 上打开 arm64 的 ELF)。不检查就往下读,e_type、e_machine 等字段全是垃圾值。

  • 先读前 4 字节,确认是 "\x7fELF"(即 ehdr.e_ident[EI_MAG0] 到 [EI_MAG3])
  • 检查 ehdr.e_ident[EI_CLASS]:值为 ELFCLASS64 才能当 Elf64_Ehdr* 解析,否则可能是 32 位
  • 检查 ehdr.e_ident[EI_DATA]:ELFDATA2LSB 或 ELFDATA2MSB 决定字节序,硬按本地序 reinterpret_cast 会错读 e_entry、e_phoff 等字段

修改 e_entry 后必须重写整个 ELF 头,不能只改偏移处的 8 字节

ELF 头本身是固定长度(sizeof(Elf64_Ehdr) == 64),但它的位置不一定在文件开头之后立刻开始——虽然绝大多数情况下是,可 e_ident[EI_PAD] 区域可能被工具填充,且某些链接器(如 gold)会在头前塞注释段。更关键的是:e_entry 是程序入口虚拟地址,不是文件偏移;你改的是内存布局概念,但文件里它只是头中一个字段。

  • 用 lseek(fd, 0, SEEK_SET) 定位到文件起始,再 read() 全部头数据到缓冲区
  • 修改缓冲区里的 ehdr.e_entry 字段(注意字节序!)
  • 用 lseek(fd, 0, SEEK_SET) 回到开头,write(fd, &ehdr, sizeof(ehdr)) 整块覆写——只写 8 字节大概率破坏 e_phnum 或 e_shnum,导致 readelf 报 Bad value
  • 改完后记得 fsync(fd),否则 chmod +x 后执行仍走旧入口

修改后 ELF 可能无法加载:内核校验和动态链接器不买账

Linux 内核在 load_elf_binary() 中会检查 e_entry 是否落在某个 PT_LOAD 段的 p_vaddr..p_vaddr+p_memsz 范围内;glibc 的 _dl_start() 也会验证程序头表合法性。你把 e_entry 改成一个没映射的地址(比如 0x1000),execve() 直接返回 -ENOEXEC,错误信息就是 Exec format error,不提示具体哪错了。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 用 readelf -l your_bin 查看所有 LOAD 段的 VirtAddr 和 MemSize,确保新 e_entry 落在其中一段内
  • 不要改 e_phoff、e_phnum 这类描述程序头表位置/数量的字段——除非你同时重写了整个程序头表,否则动态链接器找不到 PT_INTERP 就放弃加载
  • strip 过的二进制可能删掉了 .interp 段,此时它变成静态链接,e_entry 必须指向实际代码段起始,否则 SIGSEGV

用 libelf 比裸 read/write 更安全,但要注意版本和符号可见性

手撸解析容易漏掉对齐、扩展字段或新版 ELF 标准(如 ET_LOOS 类型),libelf 封装了这些细节。但它默认不导出写入接口——elf_update(elf, ELF_C_WRITE) 在较老系统(如 CentOS 7 自带 elfutils 0.160)中仅支持只读模式,调用后返回 ELF_C_NULL,且不报错。

  • 编译时加 -lelf,运行时确保 libelf.so.1 版本 ≥ 0.168(Ubuntu 20.04+ / Fedora 32+ 默认满足)
  • 必须用 elf_version(EV_CURRENT) 初始化,否则 elf64_getehdr() 返回 NULL
  • 修改 e_entry 后,要调用 gelf_update_ehdr(elf, &ehdr),再 elf_update(elf, ELF_C_WRITE),缺一不可
  • 别依赖 libelf 自动处理段对齐——它不会帮你把新代码段塞进文件末尾并更新 e_shoff,那属于重链接范畴,得用 objcopy 或 ld

改 ELF 头看着只是几个字段的事,但每个字段背后都绑着内核加载逻辑、动态链接器协议和 mmap 布局规则。最常被忽略的是:你改的不是“一个数字”,而是整个程序生命周期的起点坐标。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

569

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1698

6

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1869

3

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.06.27

1231

7

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

1069

5

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.25

3520

5

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3248

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

5469

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3909

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习