- Status
- Offline
- Joined
- Mar 3, 2026
- Messages
- 381
- Reaction score
- 7
Has anyone else been dealing with the KVASCODE shadow pool layout changes on recent Windows builds? I am currently running into a wall while trying to resolve the ntoskrnl base directly from a custom hypervisor exit handler.
The Problem
The standard technique of reading LSTAR—which points to KiSystemCall64Shadow due to KPTI—and scanning backwards to find the MZ header is failing me on current builds. On these targets, the KVASCODE shadow pool allocation seems to reside in a completely different VA range than the primary ntoskrnl.exe image. I am seeing unmapped VA holes stretching over 8GB+, making the classic backwards-stride look more like a memory-scanning death trap than a reliable lookup.
Technical Observations
I am stuck between two theories: either the KVASCODE base is no longer constrained relative to the main kernel image in the VA space, or my assumption about LSTAR as a universal anchor is effectively dead for VMM-level resolution on modern patches.
Has anyone found a more reliable anchor point than LSTAR that survives KPTI mapping while executing from the VMM? I am trying to avoid any dependency on user-mode APIs like NtQuerySystemInformation, as I want this resolved entirely inside the hypervisor loop.
Anyone else mapping these kernel anomalies, or am I just chasing ghosts in the shadow pool?
The Problem
The standard technique of reading LSTAR—which points to KiSystemCall64Shadow due to KPTI—and scanning backwards to find the MZ header is failing me on current builds. On these targets, the KVASCODE shadow pool allocation seems to reside in a completely different VA range than the primary ntoskrnl.exe image. I am seeing unmapped VA holes stretching over 8GB+, making the classic backwards-stride look more like a memory-scanning death trap than a reliable lookup.
Technical Observations
- A 0x1000 stride loop is effectively useless and hits constant timeouts.
- Even 0x200000 (2MB PDE) strides are failing to land on the image base after 8000+ iterations.
- The scan often triggers page faults on unmapped ranges rather than gracefully scanning the kernel space.
I am stuck between two theories: either the KVASCODE base is no longer constrained relative to the main kernel image in the VA space, or my assumption about LSTAR as a universal anchor is effectively dead for VMM-level resolution on modern patches.
- Walking the IDTR to find the IDT base and resolving handlers from there (though this also feels fragile with modern PatchGuard/KPTI implementation).
- Leveraging MSRs that might still point into kernel-private ranges if not fully remapped by the shadow pool.
- Implementing a primitive system call that triggers a transition to ring 0 and recording the return address (highly non-trivial from a VMM context).
Has anyone found a more reliable anchor point than LSTAR that survives KPTI mapping while executing from the VMM? I am trying to avoid any dependency on user-mode APIs like NtQuerySystemInformation, as I want this resolved entirely inside the hypervisor loop.
Anyone else mapping these kernel anomalies, or am I just chasing ghosts in the shadow pool?