Hypervisor-isolierte Shellcode-Ausführungsumgebung. Bildet Host-Prozessspeicher in eine Gast-vCPU ab, fängt DLL-Ausführungsfehler ab und leitet API-Aufrufe an den Host weiter, kompatibel mit Stardust-PIC-Shellcode
Hypervisor-isolierte Shellcode-Ausführungsumgebung. Bildet Host-Prozessspeicher in eine Gast-vCPU ab, fängt DLL-Ausführungsfehler ab und leitet API-Aufrufe an den Host weiter, kompatibel mit Stardust PIC-Shellcode.
HyperLoader führt positionsunabhängigen Shellcode innerhalb einer isolierten virtuellen CPU aus, die mit der Windows Hypervisor Platform API (WHvP) erstellt wurde. Die vCPU läuft in ihrem eigenen Adressraum.
Userland-EDR-Hooks (Inline-Hooks, IAT-Hooks) werden konstruktionsbedingt umgangen, sie befinden sich im Adressraum des Host-Prozesses, und der Shellcode wird dort niemals ausgeführt. Die API-Auflösung, der PEB-Walk und die Entscheidungslogik des Shellcodes laufen vollständig innerhalb der vCPU, unsichtbar für jede Userland-Instrumentierung.
Die Technik umgeht keine Kernel-Level-Erkennung. WHvCreatePartition und WHvRunVirtualProcessor sind für EDR-Kernel-Sensoren sichtbar, und alle API-Aufrufe, die der Host-Proxy im Auftrag des Gasts ausführt, durchlaufen die normale Kernel-Callback-Kette (Image-Load-Benachrichtigungen, Minifilter, ETW-TI).
Host process
├── WHvCreatePartition / WHvMapGpaRange
│ └── identity VA -> GPA map: ntdll, kernel32, PEB, TEB (read only, noexec)
├── Exception interception (#PF + execute faults)
└── Exit loop: DLL call proxy
└── executes DLL functions natively on the host
vCPU guest (isolated)
└── Stardust PIC shellcode
├── PEB walk -> resolves ntdll / kernel32 (read only view)
├── API resolution via FNV1a hash over EAT
└── DLL call -> execute fault -> host proxies -> result returned
Ein 2 MB großer Niedrigspeicherbereich wird zugewiesen und im Gast bei GPA 0 eingeblendet. Die Gast-Seitentabellen (PML4/PDPT/PD) befinden sich hier, zusammen mit dem Shellcode, dem Stack, der LSTAR-Trampoline und dem Syscall-Puffer.
GPA 0x0000 Stack / page tables (identity mapped 2MB, RWX)
GPA 0x1000 PML4
GPA 0x2000 PDPT
GPA 0x3000 PD (2MB large page)
GPA 0x4000 Shellcode (Stardust binary)
GPA 0x5000 Output buffer (RCX arg on entry)
GPA 0x6000 LSTAR trampoline
GPA 0x7000 Syscall buffer (SSN + args + retval)
GPA 0x8000+ PT pool (4KB pages for VA→GPA mappings)
Vor dem Start der vCPU ordnet HyperLoader die Host-Prozessstrukturen über WHvMapGpaRange in den Gast ein:
ntdll.dll, kernel32.dll, kernelbase.dll: schreibgeschützt, nicht ausführbar0x7FFE0000)DLL-Seiten werden absichtlich ohne das Ausführungsflag zugeordnet. Der Gast kann sie lesen (EAT-Durchlauf, Import-Auflösung), aber nicht ausführen.
Wenn Stardust eine DLL-Funktion aufruft, löst die vCPU einen Ausführungsfehler aus (WHvRunVpExitReasonMemoryAccess, Zugriffstyp 2). Die Exit-Schleife:
Der Shellcode wird fortgesetzt, als wäre der Aufruf normal abgeschlossen worden. Die gesamte DLL-Ausführung erfolgt auf dem Host über die echten (möglicherweise gehackten) Funktionen, aber die Entscheidung, was aufgerufen wird und wann, wurde innerhalb der isolierten vCPU getroffen.
Seiten, die beim Start nicht zugeordnet wurden, werden bei Bedarf über #PF-Abfangung (WHvPartitionPropertyCodeExceptionExitBitmap) behandelt. Wenn der Shellcode auf eine nicht zugeordnete Seite zugreift, löst der Host sie auf, ordnet sie dem Gast zu und setzt die Ausführung transparent fort.
LSTAR wird auf ein kleines Trampolin an GPA 0x6000 gesetzt, das die Syscall-Nummer und die Argumente im Puffer an GPA 0x7000 speichert und HLT ausführt. Dies behandelt alle direkten syscall-Instruktionen, die das Trampolin erreichen, anstatt über den DLL-Proxy-Pfad zu laufen.
WinHvPlatform.dll / WinHvPlatform.libErsetzen Sie sc_stardust[] in HyperLoader.cpp durch Ihr Stardust-Binary:
xxd -i bin/stardust.x64.bin
Fügen Sie das Byte-Array ein und kompilieren Sie neu. Der Shellcode erhält beim Eintritt einen Zeiger auf den Ausgabepuffer in RCX.
Dieses Projekt dient Bildungs- und Forschungszwecken.