c++如何通过解析二进制PE文件头检测程序是否开启了DEP保护机制【进阶】

酷浩君_3060

酷浩君_3060

2026-03-30

924人浏览

原创

image_load_config_directory中sehandlercount非零才表示启用dep;需先检查datadirectory[10].size>0,再按结构size判断版本并读取对应偏移的sehandlercount字段。

c++如何通过解析二进制pe文件头检测程序是否开启了dep保护机制【进阶】

怎么看 IMAGE_LOAD_CONFIG_DIRECTORY 里有没有 SEHandlerCount

DEP(Data Execution Prevention)是否启用,关键不在于 PE 头本身,而在于加载配置目录(Load Configuration Directory)中是否包含有效的结构体,且其 SEHandlerCount 字段非零 —— 这表示启用了 Safe Exception Handlers,是 Windows 启用硬件级 DEP 的必要条件之一。

实际解析时容易直接跳去读 IMAGE_NT_HEADERS 或 IMAGE_OPTIONAL_HEADER,但这两者根本不存 DEP 相关标志;必须定位到可选头里的 DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG],再按 RVA 解析出 IMAGE_LOAD_CONFIG_DIRECTORY 结构。

  • 先检查 OptionalHeader.DataDirectory[10].Size 是否 > 0(10 是 IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 的索引)
  • 若 size > 0,用该 VirtualAddress 转为文件偏移,读取至少 sizeof(IMAGE_LOAD_CONFIG_DIRECTORY) 字节(注意:不同 Windows SDK 版本结构大小不同,Win10+ 常见为 144 字节)
  • 确认结构体中 SEHandlerCount 字段(偏移 0x4C,32 位下)或 SEHandlerCount(64 位下偏移 0x58)是否 > 0
  • 若 SEHandlerCount == 0,即使其他字段存在,也说明未启用 SafeSEH,大概率未开启 DEP(除非程序用 /NXCOMPAT:NO 显式禁用)

为什么 IMAGE_OPTIONAL_HEADER.DllCharacteristics 的 IMAGE_DLLCHARACTERISTICS_NX_COMPAT 不够可靠

这个标志只是告诉系统“我兼容 NX(即 DEP)”,不代表实际启用;它只影响加载器是否允许在 DEP 开启的系统上运行该模块,不决定 DEP 是否对当前模块生效。

常见误判场景:程序编译时加了 /NXCOMPAT,DllCharacteristics 里确实设置了 IMAGE_DLLCHARACTERISTICS_NX_COMPAT,但链接时没配 /SAFESEH 或没生成有效加载配置目录,结果运行时仍被当作“不支持 DEP”处理。

  • IMAGE_DLLCHARACTERISTICS_NX_COMPAT 是软声明,纯属“自我申报”
  • Windows 内核真正执行 DEP 策略时,会查 IMAGE_LOAD_CONFIG_DIRECTORY.SEHandlerCount 和 SEHandlerTable 的有效性
  • 32 位程序若缺失 IMAGE_LOAD_CONFIG_DIRECTORY,即使有 NX_COMPAT,也会被降级为无 DEP 保护(尤其在旧版 Windows 上)
  • 64 位程序强制要求 SEHandlerCount 有效,否则加载失败(报错 STATUS_INVALID_IMAGE_FORMAT),所以反而更可信

解析时怎么避开结构体版本混乱和字段偏移陷阱

Windows SDK 中 IMAGE_LOAD_CONFIG_DIRECTORY 在不同年代定义差异极大:VC2008、VC2015、WDK 10 都扩展了字段,导致固定偏移读取极易越界或错位。比如 SEHandlerCount 在 VS2008 定义中根本不存在,是后来才加的。

C++14
C++14

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

下载

不能硬写 *(DWORD*)((BYTE*)config + 0x4C) 就完事 —— 你得先知道这个 config 指向的是哪个版本的结构。

  • 优先读 Size 字段(结构体开头 4 字节),它标识了当前结构体的实际字节数(如 64、72、144)
  • 根据 Size 判断版本:Size == 64 → VS2003/2005;Size >= 144 → Win10+ WDK;中间值需查对应 SDK 文档
  • SEHandlerCount 在 Size >= 72 的结构中才存在,且 32/64 位偏移不同(32 位:0x4C;64 位:0x58)
  • 务必做边界检查:若 Size ,直接认为无 <code>SEHandlerCount,不尝试读取

用 dumpbin /headers 快速验证,但别全信输出

开发机上最省事的方式是用微软工具交叉验证:dumpbin /headers xxx.exe | findstr "NX",看到 application can run only on OS with SEH validation 就基本确定开了 DEP。

但它底层也是解析同一套数据,所以遇到混淆或手工构造的 PE(比如加壳后清空了 LoadConfig 目录),dumpbin 可能显示 “no load config” 却实际运行时受 DEP 保护(因为系统 fallback 到页表级策略)。

  • dumpbin 不显示 SEHandlerCount 数值,只给结论性描述,无法用于自动化判断
  • 某些加壳器会伪造 DataDirectory[10] 条目指向无效地址,dumpbin 可能静默忽略,但你的解析代码若没做指针校验就会崩
  • 真正上线的检测逻辑,必须自己做 RVA→FOA 转换、结构体 size 校验、字段存在性判断,不能依赖工具输出

最易被忽略的一点:PE 文件可能根本没有 IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 条目(Size == 0),此时无论编译选项如何,Windows 都不会对该模块启用基于异常处理程序校验的 DEP —— 但页级 DEP(如堆、栈不可执行)仍可能由系统策略全局开启,这已超出 PE 头能表达的范围。

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

相关文章

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

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

下载

相关标签:

c++

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

相关专题

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

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

2025.06.09

4734

18

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

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

2025.07.04

4871

25

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

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

2026.04.23

359

31

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5847

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2508

6

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5847

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2508

6

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

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

2023.07.26

3239

3

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

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

2023.07.27

2818

6

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习