HyperGuard 是一个基于 Intel VT-x 硬件虚拟化技术的生产级轻量型 Hypervisor 框架,专为内核安全研究、驱动开发人员和安全工程师设计。
| 特性 | 说明 |
|---|---|
| EPT Hook 引擎 | 影子页机制(双页映射),支持 Execute / Read / Write 三种拦截模式,MTF 单步恢复 |
| MSR Hook 引擎 | MSR Bitmap 精确控制,RDMSR / WRMSR 完整拦截,回调驱动架构 |
| 完整 VM-Exit 处理 | 覆盖所有标准 Exit Reason(50+ 种),含详细中文注释与 Intel SDM 参考 |
| 多处理器支持 | Per-CPU VIRTUAL_MACHINE_STATE 架构,DPC 广播,独立 VMXON/VMCS Region |
| 嵌套虚拟化兼容 | 支持 VMware / VirtualBox / Hyper-V 嵌套环境运行 |
| 生产级错误处理 | 每步操作均有错误检查与回滚,防止蓝屏;详细内核日志输出 |
| 用户态控制接口 | IOCTL 通信,支持运行时安装/卸载 Hook,查询运行状态 |
HyperGuard/
├── README.md # 项目说明(本文件)
├── LICENSE # MIT 许可证
│
├── Include/ # 公共头文件
│ ├── ia32.h # Intel IA-32/64 架构定义(CR/DR/MSR/CPUID/段描述符等)
│ ├── vmx.h # VMX 指令封装与 VMCS 字段完整定义
│ ├── ept.h # EPT 页表结构定义(PML4E/PDPTE/PDE/PTE)与 Hook 接口
│ ├── msr.h # MSR 寄存器定义与 Hook 引擎接口
│ ├── vmcall.h # VMCALL 超调用编号与接口定义
│ ├── exit_handler.h # VM-Exit 处理器声明及 GUEST_REGS 结构
│ ├── log.h # 内核日志系统接口(多级别:TRACE/DEBUG/INFO/WARN/ERROR)
│ └── common.h # 通用宏、类型定义、Per-CPU VIRTUAL_MACHINE_STATE 结构
│
├── Driver/ # 内核驱动核心模块
│ ├── entry.c # DriverEntry 入口,设备创建,IRP 分发,驱动卸载
│ ├── vmx_setup.c # VMX 初始化:特性检测、内存分配、VMXON/VMXOFF
│ ├── vmcs.c # VMCS 完整配置:Guest/Host State、所有 Execution Controls
│ ├── vmx_exit_handler.c # 【核心】VM-Exit 总调度器 - 完整处理所有 Exit Reason
│ ├── ept_manager.c # EPT 页表管理:4级页表构建、2MB大页分裂、MTRR兼容
│ ├── ept_hook.c # EPT Hook 引擎:影子页机制、三种拦截模式、MTF单步
│ ├── msr_hook.c # MSR Hook 引擎:MSR Bitmap管理、RDMSR/WRMSR拦截
│ ├── processor.c # 多处理器管理:Per-CPU架构、DPC广播、VMXON/VMXOFF
│ ├── memory.c # 内存管理工具:PA/VA转换、对齐分配、物理连续内存
│ ├── vmcall_handler.c # VMCALL 超调用分发处理
│ ├── log.c # 内核日志实现(基于 DbgPrint)
│ └── vmx_asm.asm # x64 汇编:VM-Exit入口、VMCALL封装、INVEPT指令
│
├── Shared/ # 用户态/内核态共享
│ └── ioctl_codes.h # IOCTL 控制码与通信数据结构定义
│
├── UserMode/ # 用户态控制程序
│ ├── main.cpp # 控制台入口(菜单交互)
│ ├── hyperguard_client.cpp # IOCTL 通信客户端实现
│ └── hyperguard_client.h # 客户端头文件
│
└── Docs/
├── ARCHITECTURE.md # 架构详细说明
└── EPT_HOOK_GUIDE.md # EPT Hook 原理与使用指南
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows 7 SP1 / Windows 10 / Windows 11(x64) |
| CPU | 支持 Intel VT-x(VMX)的 Intel 处理器 |
| 内核模式 | 需要内核驱动签名(测试阶段可使用测试签名模式) |
| 开发工具 | Visual Studio 2019/2022 + WDK(Windows Driver Kit)10 |
| 调试工具 | WinDbg(推荐)/ DebugView(查看 DbgPrint 输出) |
用户态 (User Mode)
┌─────────────────────────────────┐
│ hyperguard_client.cpp │ DeviceIoControl / IOCTL
│ main.cpp │
└────────────┬────────────────────┘
│ IOCTL
═════════════╪══════════════════════════════════════════ 内核边界
│
内核态 (Kernel Mode)
┌────────────▼────────────────────┐
│ entry.c (DriverEntry) │ 驱动加载 / 设备创建
│ processor.c (DPC 广播) │ 多核初始化
└────────────┬────────────────────┘
│
▼
┌─────────────────────────────────┐
│ vmx_setup.c │ VMX 特性检测 & VMXON
│ vmcs.c │ VMCS 配置(Guest/Host状态)
│ ept_manager.c │ EPT 4级页表构建
│ msr_hook.c (初始化) │ MSR Bitmap 配置
└────────────┬────────────────────┘
│ VMLAUNCH
▼
┌─────────────────────────────────────────────────────┐
│ VMX 运行时(VMX Root Mode) │
│ │
│ vmx_asm.asm (AsmVmexitHandler) │
│ vmx_exit_handler.c (VmxExitHandlerMain) │
│ ├─ EPT Violation → ept_hook.c │
│ ├─ RDMSR/WRMSR → msr_hook.c │
│ ├─ VMCALL → vmcall_handler.c │
│ ├─ CPUID → 虚拟化 Hypervisor 标志 │
│ ├─ MTF → ept_hook.c (单步恢复) │
│ └─ 其他 50+ 种 → 对应处理函数 │
└─────────────────────────────────────────────────────┘
│ VMRESUME
▼
┌─────────────────────────────────┐
│ Guest(原始 OS) │ 透明运行,无感知
└─────────────────────────────────┘
EPT Hook 利用 Intel EPT(Extended Page Tables,扩展页表)的内存访问权限控制,实现透明内存 Hook,绕过内核完整性检查(PatchGuard)。
物理内存
┌──────────────────┐ ┌──────────────────┐
│ 原始页(只读) │ ←── Read/Write ── │ Guest 读/写时 │
│ 含原始代码字节 │ │ EPT 映射到原始页│
└──────────────────┘ └──────────────────┘
┌──────────────────┐ ┌──────────────────┐
│ 影子页(只执行)│ ←── Execute ───── │ Guest 执行时 │
│ 含 JMP 跳板 │ │ EPT 映射到影子页│
└──────────────────┘ └──────────────────┘
1. 目标物理页是 2MB 大页?
└─ 是 → 分裂为 512 个 4KB 小页(保持内存语义不变)
2. 分配影子页(4KB),复制原始代码内容
3. 在影子页目标偏移处写入 JMP 跳板:
JMP [RIP+0] ; 5字节相对跳转
.qword HookFunc ; 回调地址
4. 修改 EPT PTE:
原始页 → Execute=0, Read=1, Write=1 (读/写 → 原始页)
影子页 → Execute=1, Read=0, Write=0 (执行 → 影子页)
5. INVEPT 使 EPT TLB 失效
Execute 违例(Guest 尝试执行原始页)
└─ 将 EPT PTE 切换到影子页(Execute-Only)
└─ 设置 MTF(Monitor Trap Flag)单步
└─ VMRESUME → Guest 在影子页执行 JMP → 触发 Hook 回调
Read/Write 违例(Guest 尝试读/写影子页)
└─ 将 EPT PTE 切换回原始页(Read/Write-Only)
└─ 设置 MTF 单步
└─ VMRESUME → Guest 读/写原始内容(1条指令后)
MTF 触发(单步完成)
└─ 恢复 EPT PTE 为 Hook 状态(原始页禁执行)
└─ 清除 MTF
└─ VMRESUME → 继续正常运行
MSR Hook 利用 VMX 的 MSR Bitmap 机制,对特定 MSR 的读(RDMSR)/写(WRMSR)操作进行精确拦截。
偏移 0x000 - 0x3FF (1024字节): RDMSR 低范围位图 (MSR 0x00000000 - 0x00001FFF)
偏移 0x400 - 0x7FF (1024字节): RDMSR 高范围位图 (MSR 0xC0000000 - 0xC0001FFF)
偏移 0x800 - 0xBFF (1024字节): WRMSR 低范围位图 (MSR 0x00000000 - 0x00001FFF)
偏移 0xC00 - 0xFFF (1024字节): WRMSR 高范围位图 (MSR 0xC0000000 - 0xC0001FFF)
对应位 = 1 → 触发 VM-Exit(拦截)
对应位 = 0 → 直接透传(不触发 VM-Exit)
| MSR 编号 | 名称 | 用途 |
|---|---|---|
0x176 |
IA32_SYSENTER_EIP |
Windows 32位系统调用入口(KiFastCallEntry) |
0xC0000082 |
IA32_LSTAR |
Windows 64位系统调用入口(KiSystemCall64) |
- 安装 Visual Studio 2019 或 2022(含 C++ 桌面开发组件)
- 安装 Windows Driver Kit (WDK) 对应版本
- 启用测试签名模式(仅开发/测试环境):
bcdedit /set testsigning on - 重启系统使测试签名生效
方式一:Visual Studio(推荐)
- 打开
HyperGuard.sln(需根据实际.inf和.vcxproj配置) - 选择
x64 Release配置 - 右键项目 →
Build
方式二:命令行(MSBuild)
msbuild HyperGuard.sln /p:Configuration=Release /p:Platform=x64方式三:nmake(WDK 环境)
cd Driver
nmake汇编模块使用 MASM(ml64.exe),需在 WDK 环境中编译:
ml64.exe /c /Fo vmx_asm.obj vmx_asm.asm# 使用 sc 命令安装驱动服务
sc create HyperGuard type= kernel start= demand binPath= "C:\Path\To\HyperGuard.sys"
# 启动驱动(加载并启动 Hypervisor)
sc start HyperGuard或使用 OSRLoader / DriverLoader 等工具加载。
HyperGuardCtrl.exe用户态程序菜单:
===== HyperGuard 控制台 =====
[1] 启动 Hypervisor
[2] 停止 Hypervisor
[3] 安装 EPT Hook
[4] 卸载 EPT Hook
[5] 安装 MSR Hook
[6] 卸载 MSR Hook
[7] 查询状态
[0] 退出
- 配置内核调试(串口/网络 KD)
- 查看 DbgPrint 输出(日志前缀
[HyperGuard]) - 设置断点在
VmxExitHandlerMain或具体的HandleXxx函数
- 以管理员身份运行 DebugView
- 菜单 →
Capture→ 勾选Capture Kernel - 过滤
[HyperGuard]前缀的输出
vmx_exit_handler.c 实现了以下所有 Exit Reason 的处理:
| Exit Reason | 编号 | 处理说明 |
|---|---|---|
EXCEPTION_NMI |
0 | 解析中断信息,区分 #BP/#DB/#PF/#GP,注入 NMI 到 Host |
EXTERNAL_INTERRUPT |
1 | 透传外部中断 |
TRIPLE_FAULT |
2 | 触发 KeBugCheck 进行安全转储 |
INTERRUPT_WINDOW |
7 | 清除中断窗口请求 |
NMI_WINDOW |
8 | 注入 NMI |
| Exit Reason | 编号 | 处理说明 |
|---|---|---|
CPUID |
10 | 虚拟化 Hypervisor 标志,隐藏 VMX 特性 |
GETSEC |
11 | 注入 #UD |
HLT |
12 | 透传 HLT |
INVD |
13 | 替换为 WBINVD(安全等价) |
INVLPG |
14 | 透传 TLB 刷新 |
RDPMC |
15 | 透传性能计数器读取 |
RDTSC |
16 | 透传时间戳读取 |
TASK_SWITCH |
9 | 记录并透传任务切换 |
XSETBV |
55 | 验证 XCR0 值后透传 |
RDTSCP |
51 | 透传 RDTSCP |
| Exit Reason | 编号 | 处理说明 |
|---|---|---|
CR_ACCESS |
28 | 解析 Exit Qualification,处理 CR0/CR3/CR4 MOV/LMSW/CLTS |
DR_ACCESS |
29 | 拦截 DR0-DR7 读写 |
| Exit Reason | 编号 | 处理说明 |
|---|---|---|
IO_INSTRUCTION |
30 | 解析端口号和操作方向,透传 IN/OUT |
RDMSR |
31 | 检查 Hook 回调 → 伪造值或透传真实 MSR |
WRMSR |
32 | 检查 Hook 回调 → 过滤或透传写入 |
| Exit Reason | 编号 | 处理说明 |
|---|---|---|
VMCALL |
18 | 验证魔数,分发到 vmcall_handler |
MTF |
37 | EPT Hook 单步恢复,还原 Hook 状态 |
EPT_VIOLATION |
48 | 区分 Execute/Read/Write 违例,切换影子页/原始页 |
EPT_MISCONFIGURATION |
49 | 记录详细错误,触发 KeBugCheck |
VMCLEAR ~ VMXON |
19-27 | 全部注入 #UD(阻止嵌套 VMX) |
用户态或内核模块通过 VMCALL 与 Hypervisor 通信:
| 编号 | 名称 | 功能 |
|---|---|---|
0x0001 |
VMCALL_TEST |
连通性测试 |
0x0002 |
VMCALL_EPT_HOOK |
安装 EPT Hook |
0x0003 |
VMCALL_EPT_UNHOOK |
卸载 EPT Hook |
0x0004 |
VMCALL_MSR_HOOK |
安装 MSR Hook |
0x0005 |
VMCALL_MSR_UNHOOK |
卸载 MSR Hook |
0x0006 |
VMCALL_QUERY_STATUS |
查询 Hypervisor 状态 |
0x00FF |
VMCALL_VMXOFF |
关闭 Hypervisor |
所有 VMCALL 调用时 RCX 必须携带魔数 0xDEADBEEF,否则视为无效调用。
⚠️ 警告:本框架操作内核内存和 CPU 硬件虚拟化功能,仅供安全研究和合法的内核开发使用。
- 仅在测试环境中使用:建议在虚拟机或专用物理机上进行测试
- 驱动签名:生产环境需要有效的内核驱动签名证书
- HVCI 兼容性:启用 Hypervisor-Protected Code Integrity 的系统需要额外处理
- 防火墙 / AV 软件:部分安全软件可能检测并阻止 VMX 操作
- 功能责任:使用者对使用本框架的合法性负责
- 架构设计说明 — 模块划分、数据流、设计决策
- EPT Hook 原理与指南 — EPT Hook 深度解析与使用示例
- Intel SDM(System Developer's Manual):
- Vol.3A Chapter 2-5:架构基础
- Vol.3C Chapter 23-33:VMX 完整规范
- Appendix C:VMX Basic Exit Reasons
- hyperplatform — Intel VT-x Hypervisor 参考实现
- SimpleVisor — 最简 Hypervisor 实现
本项目采用 MIT 许可证。
HyperGuard · Intel VT-x Virtualization Framework