讲师中心 微信公众号
AI工具推荐 视频效率加速

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

酷浩君_3060

酷浩君_3060

发布时间:2026-03-30 17:39:26

|

924人浏览过

|

来源于php中文网

原创

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”处理。

立即学习“C++免费学习笔记(深入)”;

C++14
C++14

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

下载
  • 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 定义中根本不存在,是后来才加的。

不能硬写 *(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 < 0x50,直接认为无 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 头能表达的范围。

热门AI工具

更多
AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

相关专题

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

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

4754

2025.06.09

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

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

4891

2025.07.04

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

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

359

2026.04.23

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

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

5867

2023.07.18

堆和栈区别
堆和栈区别

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

2508

2023.08.10

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

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

5867

2023.07.18

堆和栈区别
堆和栈区别

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

2508

2023.08.10

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

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

3239

2023.07.26

Playwright 测试失败怎么办
Playwright 测试失败怎么办

Playwright测试失败专题汇集超时、定位器匹配、浏览器提前关闭、依赖与插件配置、文件上传、SSL及Docker启动等故障文章,并介绍通过截图、报告和Trace定位错误。

0

2026.10.21

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn