首页
社区
课程
招聘
[原创]基于VT EPT的无痕断点无痕hook原理及其应用
发表于: 1天前 1000

[原创]基于VT EPT的无痕断点无痕hook原理及其应用

1天前
1000

Intel VT-x(Intel Virtualization Technology),是一组由 CPU 提供的硬件虚拟化能力。

它最初用于让一台物理计算机同时运行多个虚拟机。

Intel 对 VT 的定义是:通过处理器、芯片组和设备中的硬件辅助能力,让虚拟化软件更简单、可靠,并获得更好的性能。Intel 官方说明



VT 出现之前:虚拟机主要靠软件“骗过”操作系统

早期 x86 虚拟化主要依靠软件模拟和动态二进制翻译。Hypervisor需要扫描并改写 Guest的敏感指令,同时维护影子页表,存在实现复杂、兼容性差和性能开销大的问题。

操作系统内核默认自己运行在最高权限,并认为 CR3、中断、物理内存和设备都归自己管理。可是一台机器同时运行多个 Guest OS 时,真正的硬件只有一套,Hypervisor 必须在软件层拦截并模拟这些敏感操作。


VT-x:把“拦截与切换”交给 CPU

Intel VT-x 在处理器里加入 VMX Root 与 VMX Non-root 两种运行环境。Guest 内核仍可保持 Ring 0 语义,但处于 VMX Non-root;遇到被 VMCS 配置为受控的操作时,CPU 自动保存 Guest 状态并 VM-exit 到 Hypervisor。


VT 不是为了 Hook 而设计的。它首先解决的是软件模拟虚拟机太复杂、太慢、兼容性难的问题;而 VM-exit 提供的系统外控制能力,后来才被安全研究用于监控和对抗。

早期内核研究经常直接修改内核代码、SSDT 或 IDT。到了 x64 Windows,Kernel Patch Protection(通常称为 PatchGuard)开始保护内核代码和关键结构;驱动若进行不受支持的运行时修改,可能触发 CRITICAL_STRUCTURE_CORRUPTION。这不是说 Inline Hook 在物理上“绝对做不到”,而是它不再稳定、受支持,也更容易导致系统崩溃。


安全研究人员由此把观察位置继续下移:让 Windows 内核运行在 VMX Non-root,而监控逻辑运行于 VMX Root。Hypervisor 不必直接改动 Guest 的关键结构,也能通过 VM-exit、MSR Bitmap 和 EPT控制 Guest行为。

早期使用MSR hook,实现ssdt表的hoook,后来使用ept机制实现任意位置的inline hook


EPT(Extended Page Tables,扩展页表)是Intel VT-x提供的一套“第二级页表”。开启后多了一层转换,且可以对EPT子叶设置权限,例如只读,只执行。

核心初始化代码

EPT开启后,Guest通常仍按原样运行。只有Hypervisor主动修改某个EPT条目的PFN或R/W/X权限,才会出现访问拦截、读写保护或双视图Hook。

经典 EPT Hook 为同一个 GPA 准备两个 HPA:原始页与修改后的影子页。数据访问映射原始页,指令取指映射影子页。扫描器读取目标地址时得到干净字节;CPU 执行同一地址时,却获取补丁、跳转桩或用户自定义机器码。(本质是利用ept违规触发vmexit事件在vmexit里切换影子页)



代码


如果影子页上的指令又读取同页常量,会出现“取指需要影子页、数据读取需要原始页”的同指令冲突。常见做法是临时放开原始页执行并设置 Monitor Trap Flag(MTF),只运行一条指令;随后在 MTF VM-exit 中重新收紧权限。

MTF 不是 Guest 的 TF不需要修改 Guest RFLAGS.TF,也不占用 DR0–DR7

MTF(Monitor Trap Flag)是 Intel VMX 的一项 VM-execution control。Hypervisor 在 VMCS 中打开它并执行 VM-entry 后,处理器让 Guest 前进到下一个指令边界,再产生 Monitor Trap Flag VM-exit。它可以理解为“由 VMM 控制的单步执行”:临时放行一条 Guest 指令,指令完成后 CPU 自动把控制权交回 VMX Root。

CRC读取 → 原始页RW/NX → CRC得到原指令

CPU取指 → EPT Execute Violation → VM-exit

VT切换到影子页X-only → INVEPT → 执行影子代码

同页数据访问 → EPT Read/Write Violation

原始页临时RWX + 开启MTF → 完成一条指令


[招生]科锐逆向工程师培训(2026年7月3日实地,远程教学同时开班, 第56期)!

最后于 1天前 被只会逆一点点编辑 ,原因:
收藏
免费 0
打赏
分享
最新回复 (21)
雪    币: 0
活跃值: (4525)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
666
1天前
0
雪    币: 7
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
感谢分享
1天前
0
雪    币: 7
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
1
1天前
0
雪    币: 236
活跃值: (2735)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
666
1天前
0
雪    币: 5115
活跃值: (5867)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
感谢分享。
1天前
0
雪    币: 57
活跃值: (1498)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7

前两天玩EPT遇到一个神秘的事情 刚开始我是拿触发EPT VIOLATION的地址去在我链表里查询是否是我hook的那个页触发的,如果是就换回原始页 并设置可读可写 禁用执行并invept 但在我调试的时候 我发现一件怪事 当我用ark工具读取我hook的那个页时 触发了EPT VIOLATION 但触发的线性地址非常的诡异 这个地址既不是我的影子页 也不是原始页面 但页帧与原始页的页帧一致(可以确定就是同一个物理页) 后续我改成以页帧为查询链表的唯一凭证就好了 

让我感到困惑的是这个地址不一样是怎么回事 这个地址显然不属于任何一个内核模块 难道是我在vmware下进行测试 底层还有一层hypervisor的原因?

最后于 1天前 被Reverser07编辑 ,原因: 描述不准确
1天前
1
雪    币: 249
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
感谢分享。
1天前
0
雪    币: 5419
活跃值: (5358)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
666
1天前
0
雪    币: 330
活跃值: (492)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
研究研究
1天前
0
雪    币: 3152
活跃值: (2824)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
666
18小时前
0
雪    币: 97
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
mark
17小时前
0
雪    币: 210
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
学习
16小时前
0
雪    币: 98
活跃值: (495)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
666
14小时前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
666
14小时前
0
雪    币: 3724
活跃值: (6652)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
16
1
13小时前
0
雪    币: 0
活跃值: (308)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
不错
13小时前
0
雪    币: 380
活跃值: (481)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
666
10小时前
0
雪    币: 25
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
666
6小时前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
666
6小时前
0
雪    币: 206
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
nb
5小时前
0
雪    币: 481
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
学习学习
5小时前
0
游客
登录 | 注册 方可回帖
返回