
HyperLoader is a C++ research framework that executes position independent shellcode inside a guest vCPU created with the Windows Hypervisor Platform, for authorized offensive-security research and EDR-evasion analysis.
| Tool | S12cybersecurity/HyperLoader — hypervisor-isolated shellcode execution environment built on the Windows Hypervisor Platform (WHvP) |
| Category | Offensive security research / hypervisor-based execution sandbox (C++) |
| Primary Use | Studying how userland EDR hooks (inline, IAT) behave when shellcode decision logic runs inside an isolated vCPU instead of the host process, using Stardust PIC shellcode as the test payload |
| Safe Use | Educational and research analysis for authorized professionals in controlled lab environments; the project itself states it is for educational and research purposes only |
| Telemetry Note | Kernel sensors still see WHvCreatePartition and WHvRunVirtualProcessor; proxied API calls traverse the normal kernel callback chain (image load notifications, minifilter, ETW-TI), making the technique observable to EDR kernel instrumentation |
HyperLoader, published at S12cybersecurity/HyperLoader, is a C++ research project that answers a specific architectural question: what happens to userland endpoint instrumentation when the code it is trying to watch never actually executes in the userland it monitors? The tool builds a tiny virtual machine on top of the Windows Hypervisor Platform API (WHvP), maps a curated slice of the host process into that guest, and runs position independent shellcode there — specifically shellcode built with the Stardust PIC template from Cracked5pider. The result is a genuinely interesting design in which the shellcode resolves APIs and makes control-flow decisions inside an isolated vCPU while the actual DLL function calls are executed by proxy back on the host.
The core insight the README articulates is about trust boundaries in address spaces. Userland EDR hooks — inline patches on ntdll functions, IAT hooks, and similar instrumentation — live in the host process's address space and only observe code that executes there. Because HyperLoader's guest vCPU runs in its own address space and never executes the shellcode in the host, those hooks are structurally irrelevant to the shellcode's own logic: the PEB walk, export-table resolution, and decision branches all run invisibly to userland instrumentation. The README is refreshingly honest about the limits, noting explicitly that kernel-level detection is not bypassed, and that WHvCreatePartition and WHvRunVirtualProcessor are visible to EDR kernel sensors.
Understanding the memory layout is the key to understanding the tool. A 2MB low-memory region is allocated and mapped into the guest at GPA 0, containing the guest page tables (PML4 at 0x1000, PDPT at 0x2000, a 2MB large-page PD at 0x3000), the Stardust shellcode at 0x4000, an output buffer at 0x5000 whose pointer is passed in RCX at entry, an LSTAR trampoline at 0x6000, and a syscall buffer at 0x7000. Above 0x8000 sits a pool of 4KB pages used for demand-driven VA-to-GPA mappings. This is a compact but complete bootstrapped virtual address space, hand-built rather than borrowed from a general-purpose VMM.
The host-to-guest mapping step uses WHvMapGpaRange with an identity VA-to-GPA scheme, and the choices here reveal the author's discipline. ntdll.dll, kernel32.dll, and kernelbase.dll are mapped read-only with the execute flag deliberately cleared, alongside the TEB, PEB, Ldr, ProcessParameters, the environment block, the InLoadOrderModuleList and InMemoryOrderModuleList entries with their DLL name buffers, SharedUserData at 0x7FFE0000, and the process heap. The guest can therefore read everything it needs to walk loader structures and resolve exports, but it cannot execute a single byte of the real DLLs — which is precisely what forces the interesting failure mode the tool is built around.
That failure mode is the DLL call proxy, and it is the heart of the architecture. When the shellcode calls a DLL function, execution faults because the target pages are non-executable, producing a WHvRunVpExitReasonMemoryAccess exit with access type 2. The host-side exit loop reads the guest RIP to identify the target function, confirms it falls within a known DLL range, collects the arguments from RCX/RDX/R8/R9 and the stack, translates low-memory pointers from GPA back to host VA, and then calls the function natively on the host. It writes the return value into the guest's RAX, advances RIP to the return address, pops the stack, and resumes the vCPU. The guest perceives a normal, completed call — but every actual DLL execution went through the real, potentially hooked, host functions, and through the full kernel callback chain including image load notifications, minifilter drivers, and ETW-TI.
The remaining two mechanisms round out the design. Demand paging handles any page the shellcode touches that was not mapped at startup: a #PF interception, enabled via WHvPartitionPropertyCodeExceptionExitBitmap, lets the host resolve the fault, map the missing page into the guest, and transparently resume execution. And as a fallback for raw syscall instructions that bypass the DLL proxy path entirely, LSTAR points at a trampoline at GPA 0x6000 that stashes the syscall number and arguments into the buffer at 0x7000 and executes HLT, handing control back to the host exit loop for processing. Together these cover both the indirect (DLL-mediated) and direct (syscall) calling conventions a PIC payload might use.
For defenders, this project is more valuable as a teaching artifact than as a threat. The README's own honesty maps the detection surface: hypervisor partition creation and virtual processor runs are kernel-observable events, and every proxied call still generates ordinary host-side telemetry. What the design genuinely removes is userland visibility into the shellcode's decision logic — the reconnaissance of which functions exist, the FNV1a-hashed export resolution over the EAT, and the sequencing of calls. A purple team studying this can enumerate exactly which of their sensors would still fire and which would see nothing, which is the productive way to consume a project like this.
The dependency footprint is modest and worth noting operationally. HyperLoader requires Windows 10 or 11 with Hyper-V enabled, because WHvP only works when the hypervisor is present, and it links against WinHvPlatform.dll/WinHvPlatform.lib. Payload compatibility is specifically with Stardust-compiled binaries, and the repo credits Cracked5pider/Stardust for the PIC shellcode template alongside the Windows Hypervisor Platform API headers. The project carries no license declaration at the time of this writing and sits at a modest star count for a repo of this technical depth, which suggests a specialist audience.
In terms of authorized workflow, the natural home for HyperLoader is a lab: clone git clone https://github.com/S12cybersecurity/HyperLoader on a Hyper-V-enabled analysis VM, study the exit loop in HyperLoader.cpp, and instrument both guest and host to compare visibility. The project's own closing statement — that it is for educational and research purposes — matches how it should be treated. It is a well-documented experiment in where the boundary of userland telemetry actually lies, written by someone who clearly understands both sides of it, and it deserves reading by EDR engineers as much as by offensive researchers.
S12cybersecurity/HyperLoader.Educational analysis for authorized security professionals. Use only in controlled, authorized environments.
Related coverage
0 comentários:
Post a Comment
Note: Only a member of this blog may post a comment.