Vectored Overloading PE Injection
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the š¬ Discord group or the telegram group or follow us on Twitter š¦ @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Technique overview
Vectored Overloading is a Windows PE injection primitive that fuses classic Module Overloading with Vectored Exception Handlers (VEHs) and hardware breakpoints. Instead of patching LoadLibrary or writing its own loader, the adversary:
- Creates a
SEC_IMAGEsection backed by a legitimate DLL (e.g.,wmp.dll). - Overwrites the mapped view with a fully relocated malicious PE but keeps the section object pointing to the benign image on disk.
- Registers a VEH and programs debug registers so every call to
NtOpenSection,NtMapViewOfSection, and optionallyNtCloseraises a user-mode breakpoint. - Calls
LoadLibrary("amsi.dll")(or any other benign target). When the Windows loader invokes those syscalls, the VEH skips the kernel transition and returns the handles and base addresses of the prepared malicious image.
Because the loader still believes it mapped the requested DLL, tooling that only looks at section backing files sees wmp.dll even though memory now contains the attackerās payload. Meanwhile, imports/TLS callbacks are still resolved by the genuine loader, significantly reducing the amount of custom PE-parsing logic the adversary must maintain.
Stage 1 ā Build the disguised section
- 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.
- If the payload is an EXE, set
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.
Stage 2 ā Hijack the loader with 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.
- Locate the stack slot for the
- 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.
- Overwrite the
- (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.
Stage 3 ā Execute the payload
- EXE payload: The injector simply jumps to the original entry point once relocations are done. When the loader thinks it would call
DllMain, the custom code instead executes the EXE-style entry. - DLL payload / Node.js addon: Resolve and call the intended export (Kidkadi exposes a named function to JavaScript). Because the module is already registered with
LdrpModuleBaseAddressIndex, subsequent lookups see it as the benign DLL.
When combined with a Node.js native addon (.node file), all of the Windows-internals heavy lifting stays outside the JavaScript layer, helping the threat actor ship the same loader with many different obfuscated Node wrappers.
References
- Check Point Research ā GachiLoader: Defeating Node.js Malware with API Tracing
- VectoredOverloading ā PoC implementation
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Check the subscription plans!
- Join the š¬ Discord group or the telegram group or follow us on Twitter š¦ @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
HackTricks

