- Status
- Offline
- Joined
- Mar 3, 2026
- Messages
- 125
- Reaction score
- 7
Had to dump this manually again: HyperGuard 0x18B breakdown
Spent the last few weeks knee-deep in IDA looking at securekernel.exe, ntoskrnl, and hvix64.exe because there is practically zero public documentation on how this thing actually ticks. If you are messing with Type-1 hypervisors, you know the drill.
My current setup is a Type-1 HV running as a parasite inside Hyper-V. Using a dual-CR3 EPT split: hyperv_cr3 uses shadow pages marked --X (execute only), while hook_cr3 is a deep copy with originals kept as RW-. Accessing this works against EAC, but HyperGuard hits me with the 0x18B bugcheck after a few hours of runtime.
The Technical Catch:
Traced the chain in securekernel. The failure happens during SkpgHyperguardRuntime → SkpgVerifyExtents → SkpgTranslateVaWorker. It makes a hypercall 0x52 (HvTranslateVirtualAddress). The flags are hardcoded to 0x71 (ValidateRead | SetPTBits | FlushInhibit | Supervisor).
The issue is that when it hits our --X pages, the hypercall returns 5 (GpaNoReadAccess), which triggers the 0x18B. Even if you dodge the read access check, there is a secondary firewall at 0x140064996. It validates the translation result access rights: it expects 5 (R-X) or 6 (RWX). Since my pages are --X, it returns 4, fails the check, and VTL1 triggers a self-destruct. Once it hits that path, it overwrites VTL0 RIP to KeBugCheckEx(0x18B) and kills the CPUs.
Found 4 scheduling vectors for VTL1:
The hypercall 135 crashdump is effectively a one-way gate; the VPs spin in a barrier and timeout, forcing a bugcheck with no recovery possible.
Discussion:
Has anyone else dealt with this from a nested position? I am considering hooking HvSetEptPointer in hvix64 as a potential choke point for all EPTP writes. Alternatively, we could attempt to manipulate the VTL0 scheduler, but that is high risk.
What are your thoughts on forcing a spoofed translation result during the 0x52 hypercall? Let me know if anyone has found a cleaner way to handle the GPA access rights check without triggering the VTL1 integrity heartbeat.
Spent the last few weeks knee-deep in IDA looking at securekernel.exe, ntoskrnl, and hvix64.exe because there is practically zero public documentation on how this thing actually ticks. If you are messing with Type-1 hypervisors, you know the drill.
My current setup is a Type-1 HV running as a parasite inside Hyper-V. Using a dual-CR3 EPT split: hyperv_cr3 uses shadow pages marked --X (execute only), while hook_cr3 is a deep copy with originals kept as RW-. Accessing this works against EAC, but HyperGuard hits me with the 0x18B bugcheck after a few hours of runtime.
The Technical Catch:
Traced the chain in securekernel. The failure happens during SkpgHyperguardRuntime → SkpgVerifyExtents → SkpgTranslateVaWorker. It makes a hypercall 0x52 (HvTranslateVirtualAddress). The flags are hardcoded to 0x71 (ValidateRead | SetPTBits | FlushInhibit | Supervisor).
The issue is that when it hits our --X pages, the hypercall returns 5 (GpaNoReadAccess), which triggers the 0x18B. Even if you dodge the read access check, there is a secondary firewall at 0x140064996. It validates the translation result access rights: it expects 5 (R-X) or 6 (RWX). Since my pages are --X, it returns 4, fails the check, and VTL1 triggers a self-destruct. Once it hits that path, it overwrites VTL0 RIP to KeBugCheckEx(0x18B) and kills the CPUs.
Found 4 scheduling vectors for VTL1:
- Explicit VTL call: Hypercall 0x11.
- Synthetic timers: Standard expiry.
- Secure interrupts: Delivery path.
- VMExit piggybacking: The dispatch loop at 0x2168BA checks pending VTL1 events after every single exit.
The hypercall 135 crashdump is effectively a one-way gate; the VPs spin in a barrier and timeout, forcing a bugcheck with no recovery possible.
Discussion:
Has anyone else dealt with this from a nested position? I am considering hooking HvSetEptPointer in hvix64 as a potential choke point for all EPTP writes. Alternatively, we could attempt to manipulate the VTL0 scheduler, but that is high risk.
What are your thoughts on forcing a spoofed translation result during the 0x52 hypercall? Let me know if anyone has found a cleaner way to handle the GPA access rights check without triggering the VTL1 integrity heartbeat.