c++如何从内存映像中提取可执行文件的Section信息【深度】

风萱君_2184

风萱君_2184

2026-04-08

805人浏览

原创

PE文件节表位于IMAGE_NT_HEADERS之后,数量由FileHeader.NumberOfSections决定,每个IMAGE_SECTION_HEADER固定40字节;VirtualAddress需加基址转为内存地址,PointerToRawData仅适用于文件上下文。

c++如何从内存映像中提取可执行文件的section信息【深度】

如何用 IMAGE_SECTION_HEADER 解析 PE 文件的节表

PE 文件的节(Section)信息不存于磁盘文件头的“显式目录”里,而是紧接在 IMAGE_OPTIONAL_HEADER 之后的一组连续 IMAGE_SECTION_HEADER 结构。从内存映像中读取时,关键不是“找节表起始”,而是确认当前映像是否已按对齐粒度加载、且节表未被运行时修改(如 ASLR 后偏移变化但结构布局不变)。

  • 内存映像中节表地址 = NT_HEADERS->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress 不相关 —— 这是证书位置;正确路径是:先定位 DOS_HEADER → 跳到 NT_HEADERS → 读 FileHeader.NumberOfSections → 节表起始地址 = (BYTE*)NT_HEADERS + sizeof(IMAGE_NT_HEADERS)
  • 注意 NumberOfSections 是文件头字段,内存中依然有效;它决定后续要解析多少个 IMAGE_SECTION_HEADER
  • 每个 IMAGE_SECTION_HEADER 固定 40 字节(x86/x64 一致),不随架构扩展
// 示例:从 HMODULE 或基址 base 得到节表指针
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)base;
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((BYTE*)base + dos->e_lfanew);
PIMAGE_SECTION_HEADER sec = IMAGE_FIRST_SECTION(nt);
for (int i = 0; i FileHeader.NumberOfSections; ++i, ++sec) {
    printf("%s: %.8X %.8X\n", sec->Name, sec->VirtualAddress, sec->Misc.VirtualSize);
}

为什么 VirtualAddress 和 PointerToRawData 在内存中不能直接当指针用

这两个字段是 RVA(Relative Virtual Address)和文件偏移,不是绝对地址。在内存映像中,VirtualAddress 必须加上模块基址才能得到真实内存地址;而 PointerToRawData 属于文件布局概念,在纯内存映像中可能无效(例如资源被解压、节被重定位或丢弃)。

  • 如果模块是正常加载的(非手动 map),VirtualAddress + base 就是该节内容在内存中的起始地址
  • PointerToRawData 仅在原始文件上下文中有意义;若你手头只有内存 dump(无原始文件),这个字段基本不可信,尤其遇到 packed 或 patch 后的模块
  • SizeOfRawData 在内存中常与 Misc.VirtualSize 不等:前者是磁盘对齐后大小,后者是运行时实际占用的虚拟内存页数

常见误判:把 .reloc 节当成空节或忽略它

很多工具看到 Misc.VirtualSize == 0 或 VirtualAddress == 0 就跳过该节,但 Windows 加载器会为 ASLR 生成/填充 .reloc 节 —— 它可能在文件中为空,但在内存中真实存在且含有效重定位块。

C++14
C++14

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

下载
  • 检查 Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA 或 IMAGE_SCN_MEM_READ 才能判断节是否可读,不能只看大小
  • .reloc 的 VirtualAddress 通常非零,其内容是 IMAGE_BASE_RELOCATION 链表,每个块以 VirtualAddress + SizeOfBlock 描述一段需修复的地址范围
  • 若用 VirtualQuery 发现某节所在内存区域是 PAGE_READWRITE 且含大量小端 16 位数据,大概率就是重定位节

手动解析时容易崩的边界条件

节表本身没有校验和,也没有长度字段,全靠 NumberOfSections 驱动循环。一旦该字段被篡改(如加壳器故意写错)、或 NT 头被破坏,就会越界读取内存,触发 AV。

  • 解析前必须验证 dos->e_magic == IMAGE_DOS_SIGNATURE 且 nt->Signature == IMAGE_NT_SIGNATURE
  • 计算节表结束地址:(BYTE)sec + sizeof(IMAGE_SECTION_HEADER) nt->FileHeader.NumberOfSections,不能超过 VirtualQuery 返回的区域大小
  • sec->Name 是 8 字节数组,不一定以 \0 结尾;用 std::string_view(sec->Name, strnlen((char*)sec->Name, 8)) 安全取名

真正麻烦的从来不是结构体定义,而是你拿到的那块内存到底“算不算一个干净加载的 PE 映像”——加壳、补丁、DLL 注入、内存马都会让节的语义和布局变得模糊。别迷信字段值,多结合 VirtualQuery 和 ReadProcessMemory(如需跨进程)交叉验证。

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

相关文章

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

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

下载

相关标签:

c++

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

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

5434

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

5611

25

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

399

31

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

2025.09.05

730

5

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.16

343

7

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

2025.11.17

553

20

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

2025.11.27

323

6

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3479

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

3038

6

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习