Vectored Overloading PE Injection
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Tip
Cerchi tecniche di Windows 11 LFH heap shaping e escape per VMware Workstation PVSCSI (vmware-vmx)?
{{#ref}} vmware-workstation-pvscsi-lfh-escape.md {{#endref}}
Panoramica della tecnica
Vectored Overloading è una Windows PE injection primitive che fonde il classico Module Overloading con Vectored Exception Handlers (VEHs) e hardware breakpoints. Invece di patchare LoadLibrary o scrivere un proprio loader, l’avversario:
- Crea una sezione
SEC_IMAGEappoggiata da una DLL legittima (es.wmp.dll). - Sovrascrive la view mappata con un PE maligno completamente relocato ma mantiene l’oggetto section puntato all’immagine benevola su disco.
- Registra un VEH e programma i debug registers in modo che ogni chiamata a
NtOpenSection,NtMapViewOfSectione opzionalmenteNtClosesollevi un breakpoint in user-mode. - Chiama
LoadLibrary("amsi.dll")(o qualsiasi altro target benigno). Quando il loader di Windows invoca quei syscall, il VEH salta la transizione al kernel e ritorna gli handle e gli indirizzi base dell’immagine malevola preparata.
Poiché il loader crede di aver mappato la DLL richiesta, gli strumenti che guardano solo al file di backing della section vedono wmp.dll anche se la memoria contiene il payload dell’attaccante. Nel frattempo, gli imports/TLS callbacks sono ancora risolti dal loader genuino, riducendo significativamente la quantità di logica di parsing PE custom che l’avversario deve mantenere.
Fase 1 – Costruire la sezione camuffata
- 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);
- Copiare il PE maligno in quella view sezione per sezione, rispettando
SizeOfRawData/VirtualSizee aggiornando le protezioni in seguito (PAGE_EXECUTE_READ,PAGE_READWRITE, ecc.). - Applicare le relocations e risolvere gli imports esattamente come farebbe un reflective loader. Poiché la view è già mappata come
SEC_IMAGE, gli allineamenti di section e le guard pages corrispondono a ciò che il loader di Windows si aspetta in seguito. - Normalizzare l’header PE:
- Se il payload è un EXE, impostare
IMAGE_FILE_HEADER.Characteristics |= IMAGE_FILE_DLLe azzerare l’entry point per impedire aLdrpCallTlsInitializersdi saltare in stub specifici per EXE. - I payload DLL possono mantenere gli header invariati.
A questo punto il processo possiede una view con permessi RWX il cui oggetto di backing è ancora wmp.dll, ma i byte in memoria sono controllati dall’attaccante.
Fase 2 – Dirottare il loader con i VEH
- Registrare un VEH e armare gli hardware breakpoints: programmare
Dr0(o un altro debug register) con l’indirizzo dintdll!NtOpenSectione impostareDR7in modo che ogni esecuzione solleviSTATUS_SINGLE_STEP. Ripetere poi perNtMapViewOfSectione opzionalmenteNtClose. - Triggerare il caricamento della DLL con
LoadLibrary("amsi.dll").LdrLoadDllchiamerà infineNtOpenSectionper ottenere il reale section handle. - VEH hook per
NtOpenSection:
- Localizzare lo slot nello stack per l’argomento
[out] PHANDLE SectionHandle. - Scrivere in quello slot l’handle
DecoySectioncreato precedentemente. - Avanzare
RIP/EIPfino all’istruzioneretcosì il kernel non viene mai chiamato. - Ri-armare l’hardware breakpoint per monitorare poi
NtMapViewOfSection.
- VEH hook per
NtMapViewOfSection:
- Sovrascrivere l’
[out] PVOID *BaseAddress(e gli output di size/protection) con l’indirizzo della view malevola già mappata. - Saltare il corpo del syscall come prima.
- (Opzionale) VEH hook per
NtCloseverifica che l’handle fittizio della section venga pulito, prevenendo resource leaks e fornendo un controllo di sanity finale.
Poiché i syscall non vengono eseguiti, i callback del kernel (ETWti, minifilter, ecc.) non osservano gli eventi sospetti di NtOpenSection/NtMapViewOfSection, abbassando drasticamente la telemetry. Dal punto di vista del loader tutto è andato a buon fine e amsi.dll è in memoria, quindi procede con la risoluzione di imports/TLS contro la view dell’attaccante.
Note sull’implementazione PoC (2025)
Il PoC pubblico mostra alcuni dettagli pratici facili da perdere quando si re-implementa la tecnica:
- HWBPs are per-thread. Il PoC imposta
CONTEXT_DEBUG_REGISTERSsul thread corrente prima di chiamareLoadLibrary, quindi il VEH deve girare sullo stesso thread che innesca il loader. - Syscall emulation: il VEH imposta
RAX = 0e avanzaRIPfino alretdentro lo stub dintdll(scansiona per0xC3) così la transizione al kernel non avviene mai, poi riprende conNtContinue. - Output parameters: per
NtMapViewOfSection, il VEH sovrascrive gli outputBaseAddress,ViewSizeeWin32Protectcosì il loader crede che la mappatura sia riuscita e continua con imports/TLS usando la view dell’attaccante.
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);
Variante stealth
Ricerche recenti su VEH evidenziano che i handler possono essere registrati manualmente manipolando la VEH list invece di chiamare AddVectoredExceptionHandler, riducendo così la dipendenza dalle user-mode APIs che potrebbero essere monitorate o hooked. Questo non è richiesto per Vectored Overloading ma può essere combinato con esso per ridurre l’attività API osservabile.
Fase 3 – Eseguire il payload
- EXE payload: L’injector salta semplicemente all’original entry point una volta completate le relocations. Quando il loader pensa che chiamerà
DllMain, il codice custom esegue invece l’entry in stile EXE. - DLL payload / Node.js addon: Risolve e chiama l’export previsto (Kidkadi espone una funzione nominata a JavaScript). Poiché il modulo è già registrato in
LdrpModuleBaseAddressIndex, le ricerche successive lo vedono come la DLL benigna.
Quando combinato con un Node.js native addon (.node file), tutta la parte pesante degli internals di Windows rimane al di fuori dello strato JavaScript, aiutando il threat actor a distribuire lo stesso loader con molti diversi wrapper Node offuscati.
References
- 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
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


