Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
mora-hwbp — 基于硬件断点(DR0-DR7)的无补丁用户模式挂钩与遥测插桩引擎(AMSI、WLDP 和 ETW PoC)。 | Kitploit
工具/GitHubGitHub/dovughs/mora-hwbp
防御工具IDS/IPS规避调试器学习与教育红队对抗性攻击
GitHubdovughs/mora-hwbp

mora-hwbp

基于硬件断点(DR0-DR7)的无补丁用户模式挂钩与遥测插桩引擎(AMSI、WLDP 和 ETW PoC)。

查看仓库
1911022天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Mora-HWBP — 通过硬件断点实现 AMSI / WLDP / ETW 遥测挂钩

一个安全研究概念验证(POC),演示基于硬件断点(CPU 调试寄存器)的函数挂钩,作为传统内存代码补丁的替代方案。

目的与范围

本仓库的发布严格用于防御性安全研究、红队/紫队教育、检测工程以及 Windows 内部机制的学术研究。它演示了攻击者如何滥用处理器调试寄存器来使 user-mode 安全遥测失效——同样重要的是,防御者应监控什么以检测此类技术。作者不对任何滥用此代码的行为负责。在未经明确授权的情况下对系统使用此技术是非法的,并且在大多数司法管辖区违反相关的计算机欺诈和滥用法。请勿在您不拥有或未获得明确书面测试许可的任何环境中部署此代码。


目录

  1. 概述
  2. 背景 — 为什么使用硬件断点?
  3. 目标安全组件
  4. 架构
  5. 技术深入剖析
    • 5.1 x64 上的硬件断点
    • 5.2 调试寄存器布局(DR0–DR7)
    • 5.3 向量化异常处理器(VEH)
    • 5.4 各组件拦截逻辑
    • 5.5 线程管理与挂钩持久化
  6. 导出的 API
  7. 构建说明
  8. 注入与使用示例
  9. 检测与缓解(蓝队)
  10. 已知限制
  11. 参考资料

概述

mora_hwbp.c 实现了一个 DLL,一旦被加载/注入到目标进程(例如 PowerShell 宿主),便仅通过 CPU 硬件断点挂钩四个 user-mode 函数,这些断点存储于进程中每个线程的架构调试寄存器(DR0–DR7)中:

寄存器挂钩的函数模块目的
DR0AmsiScanBufferamsi.dll使 AMSI 内容扫描失效
DR1WldpQueryDynamicCodeTrustwldp.dll强制 WLDP 动态代码信任(Device Guard / WDAC)
DR2WldpIsClassInApprovedListwldp.dll强制 WLDP 类批准(Device Guard / WDAC)
DR3NtTraceEventntdll.dll切断整个 user-mode ETW 流

一个进程级的向量化异常处理器(VEH)接收由调试寄存器引发的 EXCEPTION_SINGLE_STEP(0x80000004)故障,通过重写异常上下文来模拟原函数的成功返回路径,并恢复执行——所有这些均未修改可执行内存的任何一个字节。

这使得该技术从攻击和防御两个角度来看都特别有趣:

  • 从攻击角度看,它绕过了 EDR/HIPS 对修改过的 .text 段的完整性检查(经典的内联挂钩、EAT/IAT 补丁或 Etwp* 桩替换)。
  • 从防御角度看,硬件断点会留下高度独特的取证痕迹(调试寄存器内容、单步异常密度、VEH 注册、GetThreadContext/SetThreadContext 系统调用模式),可用于检测。

背景 — 为什么使用硬件断点?

传统的 user-mode 挂钩方法——内联 detour(5–14 字节覆写)、导入地址表(IAT)挂钩和导出地址表(EAT)挂钩——都有一个共同的弱点:它们修改了完整性扫描器和 ETW 可以观察到的内存。

现代 AV/EDR 产品实现了:

  • 对 PowerShell 和 .NET CLR 缓冲区进行内存扫描 / AMSI 扫描;
  • 基于 ETW 的遥测(Microsoft-Windows-PowerShell、.NET ETW、威胁情报提供程序);
  • 内核回调与用户态完整性检查,用于检测 pageguard/guard-page 技巧、VirtualProtect 向 PAGE_EXECUTE_READWRITE 的转换,以及节区哈希不匹配。

硬件断点绕过了这一切:

  1. 它们是 CPU 寄存器,而非内存——在 .text 中没有任何可扫描的内容。
  2. 它们通过 Windows API SetThreadContext 以每线程为基础设置,这不会触发完整性扫描器所使用的经典“内存已修改”信号。
  3. 拦截点完全由处理器的异常分发处理,它在任何用户态目标函数执行之前经由进程 VEH 链进行路由。

本 POC 探讨了该技术针对 AMSI(反恶意软件扫描接口)、WLDP(Windows 锁定策略) 和 ETW(Windows 事件跟踪) 的有效性与可检测性——这三者是现代 Windows 安全栈中最广泛依赖的用户态安全原语。


目标安全组件

AMSI — 反恶意软件扫描接口

AMSI 是 Windows 平台集成点,允许应用程序(PowerShell、Office、VBScript、.NET 宿主等)向已注册的反恶意软件提供程序请求内容扫描。主要关注的入口点是:

  • AmsiScanBuffer(HANDLE hamsiContext, PVOID buffer, ULONG length, LPCWSTR contentName, HANDLE hamsiSession, AMSI_RESULT *pResult)

通过强制返回的 AMSI_RESULT 为 AMSI_RESULT_CLEAN (0),脚本引擎会认为内容已被检查并判定为良性,因此执行会不间断地继续。

WLDP — Windows 锁定策略

WLDP 为 Windows Defender 应用程序控制(WDAC / Device Guard)实现策略评估。本 POC 挂钩了两个 WLDP 入口点:

  • WldpIsClassInApprovedList 回答给定 COM 类(由 GUID 标识)在当前策略下是否被允许。AMSI 内部会咨询 WLDP,以决定某些脚本/内容类是否“受信任”(在批准列表中)。如果该函数报告该类已获批准,AMSI 可能会跳过对该内容类型的额外审查。
  • WldpQueryDynamicCodeTrust 回答给定的一段动态生成的代码(例如 .NET JIT 输出或其他生成的可执行内存)在当前锁定策略下是否受信任。

该 DLL 将 WldpIsClassInApprovedList 的输出参数 isApproved(RDX)设置为 TRUE 并返回 S_OK,同时强制 WldpQueryDynamicCodeTrust 返回 S_OK (0)——使被评估的内容类和被查询的动态代码都显得受信任。

ETW — Windows 事件跟踪

ntdll.dll 中的 NtTraceEvent 是进入 ETW 子系统的最低层用户态入口点——几乎所有 ETW 事件发出都经由它汇聚(包括 EtwEventWrite 和更高层的 Etw* API)。因此挂钩它会从用户态切断整个 ETW 流,并对安全监控产生广泛的副作用:

  • PowerShell 管道和脚本块日志记录事件
  • .NET 程序集加载事件(Microsoft-Windows-DotNETRuntime)
  • AMSI 扫描结果遥测
  • EDR 代理所消费的威胁情报提供程序事件

该 DLL 只是返回 STATUS_SUCCESS (0),而不执行真实函数。


架构

┌──────────────────────────────────────────────────────────────────────────┐
│                           Target Process (e.g. powershell.exe)           │
│                                                                          │
│  ┌──────────────────────────┐        ┌──────────────────────────────────┐│
│  │      mora_hwbp.dll       │        │           CPU / Windows          ││
│  │                          │        │                                  ││
│  │  DllMain / InstallHook   │        │   Thread A        Thread B       ││
│  │      │                   │        │   ┌────────┐     ┌────────┐      ││
│  │      ▼                   │        │   │ DR0..3 │     │ DR0..3 │      ││
│  │  Resolve exports         │        │   └────────┘     └────────┘      ││
│  │  (amsi/wldp/ntdll)       │        │                                  ││
│  │      │                   │        │   #DB (single-step)              ││
│  │      ▼                   │        │   exception ──► Windows Dispatch ││
│  │  AddVectoredException    │        │        │                         ││
│  │  Handler(VEH)            │        │        ▼                         ││
│  │      │                   │        │  ┌─────────────────────────────┐ ││
│  │      ▼                   │        │  │  VectoredHandler (ours)     │ ││
│  │  SetHwbpOnThread(ALL)    │        │  │  • match #DB address        │ ││
│  │      │                   │        │  │  • rewrite context (RIP/RSP)│ ││
│  │      ▼                   │        │  │  • spoof return value (RAX) │ ││
│  │  MonitorThread ◄──┐      │        │  │  • continue execution       │ ││
│  │  (re-hook every   │      │        │  └─────────────────────────────┘ ││
│  │   500ms)          └──────┘        │                                  ││
│  └──────────────────────────┘        └──────────────────────────────────┘│
└──────────────────────────────────────────────────────────────────────────┘

高层流程:

  1. DLL 被加载到目标进程中(通过任意注入技术——参见 Usage)。
  2. 在 DLL_PROCESS_ATTACH 时(或通过导出的 InstallHook),使用 GetProcAddress 解析目标导出函数(可选地通过 LoadLibraryW 强制加载模块)。
  3. 一个 向量化异常处理器 被注册为进程中的 第一个 处理器(AddVectoredExceptionHandler(1, ...))。
  4. 当前线程 立即被挂钩,然后通过 CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0) 枚举进程中的 所有现有线程 并对其进行挂钩。
  5. 一个 监控线程 每 500 毫秒唤醒一次,并将断点重新应用到每个线程——包括 新创建的线程——从而保证挂钩的持久性,即使在线程挂钩之后才创建线程,或者断点被外部清除。
  6. 当任何线程调用任何被挂钩的函数时,CPU 会引发 #DB 单步异常;Windows 将其分派给 VEH,VEH 模拟一个无害的返回并继续执行。

实验验证

注入之前——AMSI 阻止测试向量:

PS> "AmsiTestSample:7e72c3ce-861b-4339-8740-0ac1484c1386"
This script contains malicious content and has been blocked by your antivirus software.

[HWBP] DR0: AmsiScanBuffer      @ 0x... (16 hits)
[HWBP] DR1: WldpQueryDynamicCodeTrust @ 0x... (0 hits)
[HWBP] DR2: WldpIsClassInApprovedList @ 0x... (0 hits)
[HWBP] DR3: NtTraceEvent        @ 0x... (28 hits)
[HWBP] VEH: REGISTERED
[HWBP] Monitor: RUNNING
PS> "AmsiTestSample:7e72c3ce-861b-4339-8740-0ac1484c1386"
AmsiTestSample:7e72c3ce-861b-4339-8740-0ac1484c1386

DebugView 输出


技术深入解析

5.1 x64 上的硬件断点

在 x86/x64 上,每个 CPU 提供 四个硬件调试地址寄存器(DR0–DR3)和一个控制寄存器(DR7)。任何线程只要在 DR0–DR3 中设置了非零断点,当指令指针到达该地址(或数据访问匹配所配置的条件)时就会触发异常。状态寄存器 DR6 记录哪个断点被触发。

硬件断点是上下文相关的:它们存储在线程的 CONTEXT 结构中,并且仅对设置它们的线程生效。这就是为什么一个健壮的实现必须在进程的每个线程上设置断点(并持续为新线程重新应用这些断点)。

5.2 调试寄存器布局(DR0–DR7)

DR7 是一个位域,控制断点的启用和行为:

下载工具