深度理解VEH-CheatEnginevsVEH-PAGE_GUARD

admin 2026-07-19 05:12:18 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深度论证CEVEHDebugger使用DR7硬件调试寄存器而非PAGEGUARD。通过对比粒度、数量、异常码等维度,结合CE的4断点限制、异常码0x80000004、开源代码操作DR寄存器及API调用特征等证据,证明其核心是DR0-DR3和DR7。PAGEGUARD存在竞态窗口、误触发风暴等缺陷,仅适用于单线程或粗粒度监控。建议在需要精确多线程调试时使用硬件断点。 综合评分: 100 文章分类: 逆向分析,漏洞分析,安全工具,实战经验,渗透测试


cover_image

深度理解 VEH-CheatEngine vs VEH-PAGE_GUARD

KsaNL KsaNL

看雪学苑

2026年7月18日 17:59 上海

在小说阅读器读本章

去阅读

深度论证 CE VEH Debugger 的真正实现机制

本文将从原理到源码、从实验到实战,彻底讲清楚两种方案的本质差异,并论证 CE VEH Debugger 的断点核心是 DR0-DR3 + DR7 硬件调试寄存器

选手 A:PAGE_GUARD

// 给内存页加上哨兵属性
DWORD old;
VirtualProtect(addr, size, PAGE_READWRITE | PAGE_GUARD, &old);

// 任何线程碰一下这个页 → 触发异常
// ExceptionCode: STATUS_GUARD_PAGE_VIOLATION (0x80000001)
// 然后 GUARD 自动移除,需要手动恢复

特征:页级粒度,一次性触发,自动消失。

选手 B:DR7 硬件断点

// 把目标地址写入调试寄存器
ctx.Dr0 = (DWORD_PTR)targetAddr;
ctx.Dr7 = 0x000D0001;  // 启用 DR0,写入监控,4字节

// CPU 每条指令自动比对
// 精确命中 → 触发 #DB 异常
// ExceptionCode: STATUS_SINGLE_STEP (0x80000004)

特征:字节级精度,CPU 硬件执行,持久有效。

正面对比

#

| 维度 | PAGE_GUARD | DR7 硬件断点 | | — | — | — | | 粒度 | 4KB 整页 | 1 / 2 / 4 / 8 字节 | | 数量 | 无限 | 最多 4 个 | | 触发异常 | 0x80000001 | 0x80000004 | | 多线程 | 竞态灾难 | 安全(每线程独立 DR) | | 性能开销 | 高(同页误触发) | 零(CPU 硬件比对) | | 触发后状态 | GUARD 自动移除 | 断点持续存在 | | 监控类型 | 读 / 写 | 执行 / 写 / 读写 | | 检测难度 | VirtualQuery 一查便知 | 需要 GetThreadContext |

#

证据链:CE 用的是 DR7

证据一:4 断点限制

#

CE → Memory View → Debug → 设置第 5 个断点:

"You can only have 4 breakpoints at atime when using the VEH debugger"

4 个。不多不少。正好是 DR0、DR1、DR2、DR3。

PAGE_GUARD 没有这个限制——你想给多少页加 GUARD 都行。

证据二:支持的断点类型

CE VEH 断点选项:

☐ Break on Write      → DR7 R/W = 01
☐ Break on Access     → DR7 R/W = 11
☐ Break on Execute    → DR7 R/W = 00
  Size: 1 / 2 / 4     → DR7 LEN = 00/01/11

与 DR7 位域完全对应:

DR7 结构(per breakpoint):
┌────────┬────────┬─────────┐
│ Enable │  R/W   │   LEN   │
│  L0=1  │ 00=Exe │ 00=1byte│
│        │ 01=Wri │ 01=2byte│
│        │ 11=R/W │ 11=4byte│
└────────┴────────┴─────────┘

PAGE_GUARD 做不到

  • 无 Execute 断点
  • 无 字节级粒度选择
  • 无 法区分”只写”和”读写”

证据三:实际触发的异常码

在 VEH Handler 内拦截,CE 断点命中时:

ExceptionCode = 0x80000004  (STATUS_SINGLE_STEP)
DR6 = 0x00000001           (DR0 triggered)

如果是 PAGE_GUARD:

ExceptionCode = 0x80000001  (STATUS_GUARD_PAGE_VIOLATION)
DR6 = 0x00000000           (无关)

实测是 0x80000004。铁证如山。

证据四:CE 开源代码

// CEDebugger.pas - 设置 VEH 断点
procedure TDebuggerThread.SetBreakpoint(address: PtrUInt;
                                         bptype: TBreakpointType;
                                         bpsize: Integer);
var
  ctx: CONTEXT;
begin
  ctx.ContextFlags := CONTEXT_DEBUG_REGISTERS;
  GetThreadContext(hThread, ctx);

  case FindFreeDR() of
0: ctx.Dr0 := address;
1: ctx.Dr1 := address;
2: ctx.Dr2 := address;
3: ctx.Dr3 := address;
  end;

  // 配置 DR7
  ctx.Dr7 := EncodeDR7(drIndex, bptype, bpsize);
  SetThreadContext(hThread, ctx);
end;

VEH Handler:

function VEHHandler(ExceptionInfo: PEXCEPTION_POINTERS): LONG;
begin
if ExceptionInfo.ExceptionRecord.ExceptionCode = STATUS_SINGLE_STEP then
  begin
// 检查 DR6,确定哪个断点命中
    dr6 := ExceptionInfo.ContextRecord.Dr6;

if&nbsp;(dr6&nbsp;and&nbsp;1) <>&nbsp;0&nbsp;then&nbsp;ProcessBreakpoint(0);
if&nbsp;(dr6&nbsp;and&nbsp;2) <>&nbsp;0&nbsp;then&nbsp;ProcessBreakpoint(1);
if&nbsp;(dr6&nbsp;and&nbsp;4) <>&nbsp;0&nbsp;then&nbsp;ProcessBreakpoint(2);
if&nbsp;(dr6&nbsp;and&nbsp;8) <>&nbsp;0&nbsp;then&nbsp;ProcessBreakpoint(3);

// 临时禁用,设置 TF 单步跳过
DisableDR(drIndex);
&nbsp; &nbsp; ExceptionInfo.ContextRecord.EFlags :=
&nbsp; &nbsp; &nbsp; ExceptionInfo.ContextRecord.EFlags&nbsp;or&nbsp;$100;

&nbsp; &nbsp; Result := EXCEPTION_CONTINUE_EXECUTION;
&nbsp; end;
end;

源码直接操作 DR 寄存器。没有任何 VirtualProtect、PAGE_GUARD 的影子。

证据五:API 调用特征

用 API Monitor 监控 CE 设置 VEH 断点时的系统调用:

✓ 观察到:
NtSetContextThread(handle, &ctx) &nbsp; // CONTEXT_DEBUG_REGISTERS
NtGetContextThread(handle, &ctx)

✗ 没有观察到:
NtProtectVirtualMemory(..., PAGE_GUARD, ...)
VirtualProtectEx(..., PAGE_GUARD, ...)

证据六:多线程稳定性

CE VEH Debugger 在以下场景稳定工作:

  • 60+ 线程的 3A 游戏
  • 多线程疯狂读写同一结构体
  • 不漏检、不崩溃

如果是 PAGE_GUARD:

线程1触发 → GUARD移除 → 窗口期 → 线程2/3/4/5访问 → 全部漏掉
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; → 恢复GUARD → 又被线程6触发 → 异常风暴

多线程游戏 + PAGE_GUARD = 直接GG。

#

PAGE_GUARD 的致命缺陷详解

缺陷一:竞态窗口

时间线:
─────────────────────────────────────────────────────
T1: 访问 0x1000 → GUARD触发 → 异常进入Handler
T1: Handler 中设置 TF,准备单步跳过
&nbsp; &nbsp; ┌──── 此时 GUARD 已被 CPU 自动移除 ────┐
T2: │ &nbsp;访问 0x1004(同页)→ 正常通过 &nbsp;│ ← 漏了!
T3: │ &nbsp;访问 0x1008(同页)→ 正常通过 &nbsp;│ ← 漏了!
T4: │ &nbsp;访问 0x100C(同页)→ 正常通过 &nbsp;│ ← 漏了!
&nbsp; &nbsp; └────────────────────────────────────────┘
T1: 单步完成 → 恢复 GUARD
─────────────────────────────────────────────────────

缺陷二:误触发风暴

// 你想监控的地址
int* target = (int*)0x12345678;

// 但同一页(0x12345000 ~ 0x12345FFF)上还有:
struct&nbsp;Player&nbsp;{
float&nbsp;x, y, z; &nbsp; &nbsp; &nbsp; &nbsp;// 0x12345000 - 被渲染线程每帧读取
int&nbsp;health; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 0x1234500C
char&nbsp;name[32]; &nbsp; &nbsp; &nbsp; &nbsp;// 0x12345010
// ...
int&nbsp;ammo; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 0x12345678 ← 你真正关心的
};

// PAGE_GUARD 结果:
// 渲染线程每帧触发 60 次(读 x,y,z)
// 网络线程每秒触发 20 次(同步 name)
// 你关心的 ammo 写入:可能 1 次/秒
// 信噪比:1 : 4800

缺陷三:无法做执行断点

PAGE_GUARD 只能检测数据访问(读/写)
无法设置"当 EIP 执行到这个地址时中断"

而 DR7 R/W=00 就是执行断点,CPU 硬件原生支持

#

PAGE_GUARD 真正的用武之地

也别把它一棒子打死。它有自己的定位:

┌─────────────────────────────────────────────┐
│ &nbsp;PAGE_GUARD 适用场景 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
├─────────────────────────────────────────────┤
│ &nbsp;✅ 单线程漏洞分析 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
│ &nbsp;✅ 堆栈溢出检测(自查) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
│ &nbsp;✅ 需要 >4 个监控点时的妥协方案 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
│ &nbsp;✅ 粗粒度监控:"这片内存有没有被碰过"&nbsp; &nbsp; &nbsp; &nbsp;│
│ &nbsp;✅ Windows 栈扩展机制(系统自用) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
│ &nbsp;✅ 简易 Guard Page Pool(内存池哨兵) &nbsp; &nbsp; &nbsp; │
├─────────────────────────────────────────────┤
│ &nbsp;❌ 多线程精确监控 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
│ &nbsp;❌ 生产级调试器 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
│ &nbsp;❌ 游戏逆向(多线程 + 高频访问) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
│ &nbsp;❌ 需要执行断点 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
└─────────────────────────────────────────────┘

一句话:PAGE_GUARD 是单线程穷人的无限断点,自己查查自己没问题。

0x06 VEH + DR7 的完整工作流

┌─────────────────────────────────────────────────────┐
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CE VEH Debugger 架构 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
├─────────────────────────────────────────────────────┤
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
│ &nbsp;┌──────────┐ &nbsp; &nbsp;注入 &nbsp; &nbsp; ┌────────────────────┐ &nbsp; &nbsp;│
│ &nbsp;│ &nbsp;CE GUI &nbsp;│ ─────────→ │ &nbsp;目标进程 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;└──────────┘ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;┌──────────────┐ &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;│ VEH Handler &nbsp;│ &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;│ (最高优先级) &nbsp;│ &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;└──────┬───────┘ &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp; &nbsp; &nbsp; &nbsp; ▼ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;STATUS_SINGLE_STEP│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;→ 检查 DR6 &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;→ 记录 RIP/操作 &nbsp; │ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;→ 禁用 DR, 设 TF &nbsp;│ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp;→ 单步后恢复 DR &nbsp; │ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp;│
│ &nbsp;设置断点流程: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; &nbsp;│
│ &nbsp;┌─────────────────────────────────────────┐ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;│ 1. 枚举所有线程 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;│ 2. SuspendThread &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;│ 3. GetThreadContext(CONTEXT_DEBUG_REGS) &nbsp;│ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;│ 4. 写入 DR0~DR3 + 配置 DR7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;│ 5. SetThreadContext &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;│ 6. ResumeThread &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;│ 7. Hook 线程创建,新线程自动设 DR &nbsp; &nbsp; &nbsp; &nbsp;│ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp;└─────────────────────────────────────────┘ &nbsp; │ &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
└─────────────────────────────────────────────────────┘

#

动手验证

实验:自己实现一个迷你 VEH + DR7 断点:

#include&nbsp;<windows.h>
#include&nbsp;<stdio.h>

volatile&nbsp;DWORD g_target =&nbsp;0xDEAD;
volatile&nbsp;int&nbsp;g_step =&nbsp;0;

LONG CALLBACK&nbsp;VEH(EXCEPTION_POINTERS* ep)&nbsp;{
&nbsp; &nbsp; PCONTEXT ctx = ep->ContextRecord;

if&nbsp;(ep->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) {
if&nbsp;(g_step ==&nbsp;0) {
// 断点命中
printf("[!] BP HIT | RIP: 0x%p | DR6: 0x%llX\n",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(void*)ctx->Rip, ctx->Dr6);
printf(" &nbsp; &nbsp;Target value: 0x%X\n", g_target);

// 临时禁用 DR0, 设 TF 单步跳过
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctx->Dr7 &= ~(DWORD_PTR)0x1;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctx->EFlags |=&nbsp;0x100;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g_step =&nbsp;1;
&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;else&nbsp;{
// TF 单步完成,恢复断点
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctx->Dr7 |=&nbsp;0x1;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g_step =&nbsp;0;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; ctx->Dr6 =&nbsp;0;&nbsp;// 清除 DR6
return&nbsp;EXCEPTION_CONTINUE_EXECUTION;
&nbsp; &nbsp; }

return&nbsp;EXCEPTION_CONTINUE_SEARCH;
}

voidSetHWBP_Write4(void* addr)&nbsp;{
&nbsp; &nbsp; CONTEXT ctx = {0};
&nbsp; &nbsp; ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;

GetThreadContext(GetCurrentThread(), &ctx);

&nbsp; &nbsp; ctx.Dr0 = (DWORD_PTR)addr;
// DR7: L0=1, R/W0=01(Write), LEN0=11(4bytes)
// Bits: LEN0[19:18]=11, R/W0[17:16]=01, L0[0]=1
&nbsp; &nbsp; ctx.Dr7 = (3&nbsp;<<&nbsp;18) | (1&nbsp;<<&nbsp;16) |&nbsp;1;

SetThreadContext(GetCurrentThread(), &ctx);
}

intmain()&nbsp;{
AddVectoredExceptionHandler(1, VEH);

printf("[*] Setting hardware write BP on g_target @ %p\n", &g_target);
SetHWBP_Write4((void*)&g_target);

printf("[*] Writing to g_target...\n");
&nbsp; &nbsp; g_target =&nbsp;0xBEEF; &nbsp;&nbsp;// 触发断点

printf("[*] Writing again...\n");
&nbsp; &nbsp; g_target =&nbsp;0xCAFE; &nbsp;&nbsp;// 再次触发

printf("[*] Final value: 0x%X\n", g_target);
return&nbsp;0;
}

输出:

[*]&nbsp;Setting&nbsp;hardware&nbsp;write&nbsp;BP&nbsp;on&nbsp;g_target&nbsp;@&nbsp;0x00007FF7A1B04000
[*]&nbsp;Writing&nbsp;to&nbsp;g_target...
[!]BP&nbsp;HIT&nbsp;|&nbsp;RIP:0x00007FF7A1B01122&nbsp;|&nbsp;DR6:0x1
Target value:0xBEEF
[*]&nbsp;Writing&nbsp;again...
[!]BP&nbsp;HIT&nbsp;|&nbsp;RIP:0x00007FF7A1B01135&nbsp;|&nbsp;DR6:0x1
Target value:0xCAFE
[*]&nbsp;Final value:0xCAFE

这就是 CE VEH Debugger 的核心原理。20 行代码复现。

#

总结

#

┌──────────────────────────────────────────────────┐
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
│ &nbsp; CE&nbsp;VEHDebugger&nbsp;=&nbsp;VEH + 硬件断点 (DR0-DR3) &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
│ &nbsp; PAGE_GUARD:单线程场景,自查泄露足以 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
│ &nbsp; DR7 硬件断点:精确、高效、多线程安全 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
│ &nbsp; VEH 是异常的接收框架 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; │
│ &nbsp; DR 寄存器才是断点的触发源 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
│ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;│
└──────────────────────────────────────────────────┘

#

看雪ID:KsaNL

https://bbs.kanxue.com/user-home-969146.htm

*本文为看雪论坛优秀文章,由 KsaNL 原创,转载请注明来自看雪社区

第十届安全开发者峰会【议题征集】-欢迎投稿

往期推荐

Android ARM64 内核态内存访问与隐蔽交互机制逆向分析

电动牙刷小程序”越权控制”逆向

一道简单但不简约的堆题——CISCN2026初赛堆题robo分析

第二届软件系统安全赛决赛 StudentManagement 详解

APP整体加固原理

球分享

球点赞

球在看

点击阅读原文查看更多


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:看雪学苑 KsaNL KsaNL《深度理解 VEH-CheatEngine vs VEH-PAGE_GUARD》

评论:0   参与:  0