Ambiente de execução de shellcode isolado por hypervisor. Mapeia a memória do processo host para uma vCPU guest, intercepta falhas de execução de DLL e faz proxy de chamadas de API para o host, compatível com shellcode PIC Stardust
Ambiente de execução de shellcode isolado por hypervisor. Mapeia a memória do processo host para uma vCPU guest, intercepta falhas de execução de DLL e faz proxy de chamadas de API para o host, compatível com shellcode PIC do Stardust.
O HyperLoader executa shellcode independente de posição dentro de uma CPU virtual isolada criada com a Windows Hypervisor Platform API (WHvP). A vCPU é executada em seu próprio espaço de endereçamento.
Hooks de EDR em userland (hooks inline, hooks de IAT) são contornados por design, pois residem no espaço de endereçamento do processo host, e o shellcode nunca é executado ali. A resolução de API do shellcode, o PEB walk e a lógica de decisão são executados inteiramente dentro da vCPU, invisíveis para qualquer instrumentação em userland.
A técnica não contorna algumas detecções em nível de kernel. WHvCreatePartition e WHvRunVirtualProcessor são visíveis para sensores de kernel de EDR, e quaisquer chamadas de API que o proxy do host executa em nome do guest passam pela cadeia normal de callbacks do kernel (notificações de carregamento de imagem, 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
Uma região de memória baixa de 2MB é alocada e mapeada no guest em GPA 0. As tabelas de páginas do guest (PML4/PDPT/PD) residem aqui, juntamente com o shellcode, a pilha, o trampolim LSTAR e o buffer de syscall.
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)
Antes de iniciar a vCPU, o HyperLoader mapeia as estruturas do processo host no guest usando WHvMapGpaRange:
ntdll.dll, kernel32.dll, kernelbase.dll: somente leitura, sem execução0x7FFE0000)As páginas das DLLs são intencionalmente mapeadas sem o flag de execução. O guest pode lê-las (percurso da EAT, resolução de imports), mas não pode executá-las.
Quando o Stardust chama uma função de DLL, a vCPU gera uma falha de execução (WHvRunVpExitReasonMemoryAccess, tipo de acesso 2). O loop de saída:
O shellcode continua como se a chamada tivesse sido concluída normalmente. Toda a execução de DLL ocorre no host, através das funções reais (potencialmente hookeadas), mas a decisão de o que chamar e quando foi tomada dentro da vCPU isolada.
As páginas não mapeadas na inicialização são tratadas sob demanda via interceptação de #PF (WHvPartitionPropertyCodeExceptionExitBitmap). Quando o shellcode acessa uma página não mapeada, o host a resolve, mapeia-a no guest e retoma a execução de forma transparente.
O LSTAR é definido para um pequeno trampolim no GPA 0x6000 que salva o número da syscall e os argumentos no buffer no GPA 0x7000 e executa HLT. Isso trata quaisquer instruções syscall diretas que cheguem ao trampolim em vez de passarem pelo caminho do proxy de DLL.
WinHvPlatform.dll / WinHvPlatform.libSubstitua sc_stardust[] em HyperLoader.cpp pelo seu binário Stardust:
xxd -i bin/stardust.x64.bin
Cole o array de bytes e recompile. O shellcode recebe um ponteiro para o buffer de saída em RCX na entrada.
Este projeto destina-se a fins educacionais e de pesquisa.