首页
社区
课程
招聘
[原创]深度理解 VMX root vs VMX non-root
发表于: 1天前 431

[原创]深度理解 VMX root vs VMX non-root

1天前
431

一、两个世界:VMX root vs VMX non-root 的本质隔离

Intel VT-x 把处理器分成两种运行态:

关键约束是:non-root 的代码无法直接调用 VMX root 的函数,两者地址空间上是连续的,但执行权限完全隔离。要从 non-root 进入 root,只有一条合法路径 —— 触发 VM-exit。

!epthook 为例:

EPT hook 的核心是把目标页的内容复制到一个新位置,在新页上写入 0xcc 断点,然后清除原 EPT 页表项的 Read/Write 位,只保留 Execute 位,并把该 PTE 指向新页的物理地址。

这意味着你需要直接操作 EPT 页表(二级页表结构)。如果在 VMX non-root 里做这件事,会有几个严重问题:

因此架构上规定:EPT 表结构的写入操作,必须在 VMX root 中完成

从 VMX non-root 进入 VMX root 的唯一主动方式是执行 VMCALL 指令。它在 non-root 中执行时**无条件触发 EXIT_REASON_VMCALL(exit reason 18)**的 VM-exit,处理器切到 VMX root,HyperDbg 的 VM-exit handler 接管。

HyperDbg 的调用约定是:

这本质上是一套用户自定义超级调用(hypercall)系统,类比 Linux 的 syscall 表:non-root 把"我要做什么"编码进寄存器,VMX root 的 handler 里做 switch(VmcallNumber) 分发到对应的操作。

为什么要 CALL_ID 而不是直接函数指针?

当调试器需要暂停 debuggee 时,用户态应用发 IOCTL 到内核,从 IOCTL 中执行 VMCALL 进入所有核心的 VMX root 模式。在 root 模式中,IF 标志被清零,不允许中断,所有核心就这样被暂停,以轮询模式等待来自调试器的命令。

对于其他核心的通知,HyperDbg 通过 XAPIC/X2APIC 向它们发送 NMI。由于配置了 NMI exiting,这些 NMI 触发 VM-exit,其他核进入 root 后在 spinlock 上自旋等待,实现了全核暂停。

!epthook2 等命令不在 vmx root 触发,保持在 vmx non-root 运行,这样省去了 VM-exit/VM-entry 的切换开销,速度更快。但脚本引擎中访问 @rip@rsp@cs 等寄存器依赖 VMREAD/VMWRITE,这两条指令在 non-root 不可用,因此 non-root 模式下脚本访问这些寄存器会导致 BSOD。

一句话总结这个架构的本质:HyperDbg 利用 VMCALL+CALL_ID 构造了一套从 ring 0(VMX non-root)向 ring -1(VMX root)的受控超级调用系统,目的是把所有需要原子性、需要操作 EPT 硬件结构的操作安全地转移到 hypervisor 层执行,同时把内存分配、参数构造等高级操作留在 non-root 完成,两侧各司其职。


[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

最后于 1天前 被4seaynl编辑 ,原因:
收藏
免费 4
打赏
分享
最新回复 (2)
雪    币: 2790
活跃值: (6386)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
感谢分享!
13小时前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
看看
3小时前
0
游客
登录 | 注册 方可回帖
返回