ahossu/DWMShield
GitHub: ahossu/DWMShield
一个演示Windows DWM如何在内核级别执行屏幕捕获保护的内核研究工具,通过调用未公开的win32kfull!GreProtectSpriteContent函数揭示WDA_EXCLUDEFROMCAPTURE的底层实现机制。
Stars: 0 | Forks: 0
# DWMShield – Windows 窗口捕获保护的内核模式探索
## 概述
该项目演示了 Windows Desktop Window Manager (DWM) 如何在内核级别强制执行 `WDA_EXCLUDEFROMCAPTURE` 标志。它调用了一个未公开的内部函数 (`win32kfull!GreProtectSpriteContent`) 将任何窗口标记为排除在屏幕捕获之外,从而有效地使其对所有用户模式捕获 API 不可见。
该代码作为**研究概念验证**,旨在理解用户模式和内核模式窗口管理之间的边界。它旨在说明捕获排除机制在 Windows 图形堆栈中的嵌入深度,以及记录在案的用户模式 API (`SetWindowDisplayAffinity`) 如何与底层执行相关联。
## 工作原理
1. 驱动程序创建一个设备 `\Device\HideWindow` 和一个符号链接 `\DosDevices\HideWindow`(可从用户模式作为 `\\.\HideWindow` 访问)。
2. 一个用户模式应用程序 (`protect.exe`) 发送一个包含目标窗口 HWND 的 IOCTL。
3. 驱动程序定位内部的 `win32kfull!GreProtectSpriteContent` 函数(由于 KASLR,地址必须手动更新),并使用该 HWND 和标志 `0x11` (`WDA_EXCLUDEFROMCAPTURE`) 调用它。
4. 调用后,Desktop Window Manager 以一种与官方 `SetWindowDisplayAffinity` 路径行为镜像的方式应用相应的捕获排除状态。
## 构建驱动程序
- 在 Visual Studio 2022(带有 WDK)中,创建一个新的 **Empty WDM Driver** 项目。
- 将 `HideWindow.c` 添加到 Source Files 文件夹中。
- 将解决方案平台设置为 **x64**。
- Build → Build Solution。`.sys` 文件将位于 `x64\Release\` 中。
## 构建用户模式客户端
使用任何 C 编译器(GCC, MSVC 等)编译 `protect.c`:
```
gcc -o protect.exe protect.c
```
## 安装与测试
1. 启用测试签名并重启:
bcdedit /set testsigning on
Restart-Computer
2. 将 `HideWindow.sys` 和 `protect.exe` 复制到目标机器上的某个文件夹(例如 `C:\Drivers`)。
3. 安装并启动驱动程序(以管理员身份):
sc.exe create HideWindow type= kernel binPath= C:\Drivers\HideWindow.sys
sc.exe start HideWindow
4. 在任意控制台窗口(非管理员)中运行 `protect.exe`:
C:\Drivers\protect.exe
5. 该控制台窗口将不再出现在使用不同工具截取的屏幕捕获中。
6. 完成后,停止并删除驱动程序(以管理员身份):
sc.exe stop HideWindow
sc.exe delete HideWindow
## 重要说明
- 由于 KASLR,`GreProtectSpriteContent` 的地址在每次重启后都会更改。你需要使用 WinDbg 中找到的新地址更新 `HideWindow.c` 中的 `#define GRE_PROTECT_SPRITE_CONTENT_ADDR`:
lkd> x win32kfull!GreProtectSpriteContent *
然后重新构建驱动程序。
- 该驱动程序仅在 Windows 10 和 11 上有效(它依赖于这些版本中存在的内部函数)。
## 已知限制(研究背景)
- **地址硬编码**:每次重启后必须手动更新函数地址。这是 KASLR 以及 `GreProtectSpriteContent` 未被导出这一事实的直接后果。更稳健的研究实现需要一种更安全且更易于维护的方式来动态解析地址。
- **Windows 版本敏感性**:内部函数的签名和可用性可能会随 Windows 更新而变化。此代码在 build 19041 (Windows 10 2004) 上进行了测试。
- **最小验证**:驱动程序不验证它接收到的 HWND;格式错误的句柄可能导致不可预测的行为。在真实的驱动程序中,适当的验证是必不可少的。
- **仅限测试签名**:驱动程序使用测试证书签名,需要 `testsigning` 模式。要在锁定的系统上部署,需要有效的 EV 证书或禁用 DSE —— 这两者都不建议用于生产环境。
## 研究动机
这个项目源于一个技术问题:*“`WDA_EXCLUDEFROMCAPTURE` 标志在官方 API 之下实际上是如何工作的?”*
公共函数 `SetWindowDisplayAffinity` 可以通过 `GetWindowDisplayAffinity` 检测到,因此我们想看看排除是否真的在内核级别执行。
通过对 `win32kfull.sys` 进行逆向工程,我们定位到了内部函数 `GreProtectSpriteContent` —— 即最终实现该标志的例程。直接调用它绕过了用户模式 API,并确认保护是在 Desktop Window Manager 内部应用的,对任何用户模式进程完全不可见。
该实验表明,**任何仅依赖于用户模式合作的安全机制都可以从用户模式本身被观察或规避**。这是 Windows 的一个基本设计现实,而非漏洞 —— 它只是突显了用户空间和内核空间之间的界限,这是操作系统研究人员和内核开发者都很清楚的话题。
## 许可证
该项目根据 MIT 许可证授权 - 有关详细信息,请参阅 [LICENSE](LICENSE) 文件。
标签:DWM, IOCTL, KASLR, PoC, SetWindowDisplayAffinity, WDA_EXCLUDEFROMCAPTURE, WDM驱动, Win32k, Windows内核, Windows图形子系统, Windows安全机制, 云资产清单, 内核安全研究, 反截屏, 安全测试, 客户端加密, 屏幕截图防护, 攻击性安全, 暴力破解, 未文档化API, 白帽子, 网络安全监控, 视觉保护, 逆向工程, 驱动开发