Vectored Overloading PE Injection
Tip
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
Tip
想查找 Windows 11 LFH heap shaping 和 VMware Workstation PVSCSI (vmware-vmx) escape 技术吗?
{{#ref}} vmware-workstation-pvscsi-lfh-escape.md {{#endref}}
技术概述
Vectored Overloading 是一种将经典的 Module Overloading 与 Vectored Exception Handlers (VEHs) 和 hardware breakpoints 结合起来的 Windows PE 注入原语。与其修补 LoadLibrary 或编写自定义 loader,不如:
- 创建一个由合法 DLL(例如
wmp.dll)支撑的SEC_IMAGEsection。 - 用一个已完成重定位的恶意 PE 覆盖映射视图,但保留 section 对象指向磁盘上的良性映像。
- 注册 VEH 并编程调试寄存器,使每次调用
NtOpenSection、NtMapViewOfSection,以及可选的NtClose都触发用户模式断点。 - 调用
LoadLibrary("amsi.dll")(或任何其他良性目标)。当 Windows loader 调用这些 syscall 时,VEH 会跳过内核转换并返回已准备好的恶意映像的句柄和基址。
因为 loader 仍然认为它映射了请求的 DLL,只有检查 section backing 文件的工具会看到 wmp.dll,即便内存现在包含攻击者的 payload。与此同时,imports/TLS callbacks 仍由真实 loader 解析,显著减少了攻击者必须维护的自定义 PE 解析逻辑量。
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.
此时,进程拥有一个其 backing object 仍为 wmp.dll 的 RWX 能力视图,但内存中的字节已由攻击者控制。
Stage 2 – Hijack the loader with VEHs
- Register a VEH and arm hardware breakpoints:将
Dr0(或另一个调试寄存器)编程为指向ntdll!NtOpenSection的地址,并设置DR7,以便每次执行都会引发STATUS_SINGLE_STEP。随后对NtMapViewOfSection(以及可选的NtClose)重复相同操作。 - Trigger DLL loading:调用
LoadLibrary("amsi.dll")。LdrLoadDll最终会调用NtOpenSection来获取真实的 section handle。 - VEH hook for
NtOpenSection:
- 找到用于
[out] PHANDLE SectionHandle参数的栈槽。 - 将先前创建的
DecoySectionhandle 写入该槽。 - 将
RIP/EIP推进到ret指令处,从而避免内核被调用。 - 重新布置硬件断点以监视下一步的
NtMapViewOfSection。
- VEH hook for
NtMapViewOfSection:
- 覆盖
[out] PVOID *BaseAddress(以及 size/protection 输出)为已映射的恶意视图地址。 - 像之前一样跳过 syscall 的执行体。
- (Optional) VEH hook for
NtClose验证伪造的 section handle 被清理,防止资源泄漏并提供最终的完整性检查。
由于这些 syscall 从未执行,内核回调(如 ETWti、minifilter 等)不会观察到可疑的 NtOpenSection/NtMapViewOfSection 事件,从而大幅降低遥测。从 loader 的角度看,一切都成功,amsi.dll 在内存中因此继续执行 imports/TLS 的解析,使用的却是攻击者的视图内容。
PoC implementation notes (2025)
公开的 PoC 展示了一些在重新实现该技术时容易忽视的实际细节:
- HWBPs are per-thread。PoC 在调用
LoadLibrary之前对当前线程 设置CONTEXT_DEBUG_REGISTERS,因此 VEH 必须在触发 loader 的同一线程上运行。 - Syscall emulation:VEH 将
RAX = 0并将RIP推进到ntdllstub 内的ret(它扫描0xC3),使内核转换永远不会发生,然后用NtContinue恢复执行。 - Output parameters:对于
NtMapViewOfSection,VEH 会覆盖返回的BaseAddress、ViewSize和Win32Protect输出,让 loader 相信映射成功并继续使用攻击者的视图进行 imports/TLS。
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);
隐蔽变体
最近的 VEH 研究指出,可以通过手动操纵 VEH 列表来注册处理程序,而不是调用 AddVectoredExceptionHandler,这可以减少对可能被监视或挂钩的用户模式 API 的依赖。这对于 Vectored Overloading 并非必需,但可以与其结合以减少可观察到的 API 活动。
Stage 3 – Execute the payload
- EXE payload: 注入器在重定位完成后直接跳转到原始入口点。当加载器认为会调用
DllMain时,定制代码会改为执行 EXE 风格的入口。 - DLL payload / Node.js addon: 解析并调用目标导出(Kidkadi 向 JavaScript 导出一个命名函数)。因为该模块已经在
LdrpModuleBaseAddressIndex中注册,后续查找会将其视为良性 DLL。
当与 Node.js 本地 addon(.node 文件)结合时,所有 Windows 内部实现的繁重工作都留在 JavaScript 层之外,这有助于威胁行为者用多个不同的混淆 Node 包装器分发相同的 loader。
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
学习和实践 AWS 黑客技术:
HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。


