Vectored Overloading PE Injection
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Tip
Procurando técnicas de escape para Windows 11 LFH heap shaping e VMware Workstation PVSCSI (vmware-vmx)?
{{#ref}} vmware-workstation-pvscsi-lfh-escape.md {{#endref}}
Visão geral da técnica
Vectored Overloading é uma primitiva de injeção PE do Windows que funde o clássico Module Overloading com Vectored Exception Handlers (VEHs) e hardware breakpoints. Em vez de patchar LoadLibrary ou escrever seu próprio loader, o adversário:
- Cria uma seção
SEC_IMAGEreferenciada por uma DLL legítima (por exemplo,wmp.dll). - Sobrescreve a view mapeada com um PE malicioso totalmente realocado, mas mantém o objeto de seção apontando para a imagem benigna no disco.
- Registra um VEH e programa os registradores de debug para que cada chamada a
NtOpenSection,NtMapViewOfSectione, opcionalmente,NtClosegere um breakpoint em user-mode. - Chama
LoadLibrary("amsi.dll")(ou qualquer outro alvo benigno). Quando o Windows loader invoca esses syscalls, o VEH pula a transição para o kernel e retorna os handles e endereços base da imagem maliciosa preparada.
Como o loader ainda acredita ter mapeado a DLL solicitada, ferramentas que apenas verificam os arquivos de backing das sections vêem wmp.dll mesmo que a memória agora contenha o payload do atacante. Enquanto isso, imports/TLS callbacks ainda são resolvidos pelo loader genuíno, reduzindo significativamente a quantidade de lógica de parsing de PE personalizada que o adversário precisa manter.
Etapa 1 – Construir a seção disfarçada
- Create and map a section for the decoy DLL
NtCreateSection(&DecoySection, SECTION_ALL_ACCESS, NULL,
0, PAGE_READWRITE, SEC_IMAGE, L"\??\C:\\Windows\\System32\\wmp.dll");
NtMapViewOfSection(DecoySection, GetCurrentProcess(), &DecoyView, 0, 0,
NULL, &DecoySize, ViewShare, 0, PAGE_READWRITE);
- Copy the malicious PE into that view section by section, honouring
SizeOfRawData/VirtualSizeand updating protections afterwards (PAGE_EXECUTE_READ,PAGE_READWRITE, etc.). - Apply relocations and resolve imports exactly as a reflective loader would. Because the view is already mapped as
SEC_IMAGE, section alignments and guard pages match what the Windows loader expects later. - Normalize the PE header:
- If the payload is an EXE, set
IMAGE_FILE_HEADER.Characteristics |= IMAGE_FILE_DLLand zero the entry point to keepLdrpCallTlsInitializersfrom jumping into EXE-specific stubs. - DLL payloads can keep their headers unchanged.
At this point the process owns a RWX-capable view whose backing object is still wmp.dll, yet the bytes in memory are attacker-controlled.
Etapa 2 – Sequestrar o loader com VEHs
- Register a VEH and arm hardware breakpoints: program
Dr0(or another debug register) with the address ofntdll!NtOpenSectionand setDR7so every execution raisesSTATUS_SINGLE_STEP. Repeat later forNtMapViewOfSectionand optionallyNtClose. - Trigger DLL loading with
LoadLibrary("amsi.dll").LdrLoadDllwill eventually callNtOpenSectionto obtain the real section handle. - VEH hook for
NtOpenSection:
- Locate the stack slot for the
[out] PHANDLE SectionHandleargument. - Write the previously created
DecoySectionhandle into that slot. - Advance
RIP/EIPto theretinstruction so the kernel is never called. - Re-arm the hardware breakpoint to watch
NtMapViewOfSectionnext.
- VEH hook for
NtMapViewOfSection:
- Overwrite the
[out] PVOID *BaseAddress(and size/protection outputs) with the address of the already mapped malicious view. - Skip the syscall body just like before.
- (Optional) VEH hook for
NtCloseverifies that the fake section handle is cleaned up, preventing resource leaks and providing a final sanity check.
Because the syscalls are never executed, kernel callbacks (ETWti, minifilter, etc.) do not observe the suspicious NtOpenSection/NtMapViewOfSection events, drastically lowering telemetry. From the loader’s point of view everything succeeded and amsi.dll is in memory, so it proceeds with import/TLS resolution against the attacker’s bytes.
PoC implementation notes (2025)
The public PoC shows a few practical details that are easy to miss when re-implementing the technique:
- HWBPs are per-thread. The PoC sets
CONTEXT_DEBUG_REGISTERSon the current thread before callingLoadLibrary, so the VEH must run on the same thread that triggers the loader. - Syscall emulation: the VEH sets
RAX = 0and advancesRIPto theretinside thentdllstub (it scans for0xC3) so the kernel transition never happens, then resumes withNtContinue. - Output parameters: for
NtMapViewOfSection, the VEH overwrites the returnedBaseAddress,ViewSize, andWin32Protectoutputs so the loader believes the mapping succeeded and continues with imports/TLS using the attacker’s view.
Minimal HWBP setup used by the PoC (x64):
CONTEXT ctx = {0};
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
GetThreadContext(GetCurrentThread(), &ctx);
ctx.Dr0 = (DWORD64)NtOpenSection;
ctx.Dr7 = 1;
SetThreadContext(GetCurrentThread(), &ctx);
AddVectoredExceptionHandler(1, VehHandler);
Variação Stealth
Pesquisas recentes sobre VEH destacam que handlers podem ser registrados por meio de manipulação manual da lista VEH em vez de chamar AddVectoredExceptionHandler, o que reduz a dependência de user-mode APIs que podem ser monitoradas ou hooked. Isso não é necessário para Vectored Overloading, mas pode ser combinado com ele para reduzir a atividade de API observável.
Etapa 3 – Executar o payload
- EXE payload: O injector simplesmente salta para o ponto de entrada original assim que as relocations são concluídas. Quando o loader acha que chamaria
DllMain, o código customizado, em vez disso, executa a entrada no estilo EXE. - DLL payload / Node.js addon: Resolve e chama o export pretendido (Kidkadi expõe uma função nomeada para JavaScript). Como o módulo já está registrado em
LdrpModuleBaseAddressIndex, buscas subsequentes o tratam como a DLL benigna.
Quando combinado com um Node.js native addon (.node file), todo o trabalho pesado dos internals do Windows permanece fora da camada JavaScript, ajudando o agente de ameaça a distribuir o mesmo loader com muitos wrappers Node ofuscados diferentes.
Referências
- Check Point Research – GachiLoader: Defeating Node.js Malware with API Tracing
- VectoredOverloading – PoC implementation
- IBM X-Force – You just got vectored: Using VEH for defense evasion and process injection
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


