Vectored Overloading PE Injection
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Tip
Шукаєте Windows 11 LFH heap shaping та VMware Workstation PVSCSI (vmware-vmx) escape techniques?
{{#ref}} vmware-workstation-pvscsi-lfh-escape.md {{#endref}}
Technique overview
Vectored Overloading — це Windows PE injection primitive, який поєднує класичний Module Overloading з Vectored Exception Handlers (VEHs) та hardware breakpoints. Замість патчу LoadLibrary або написання власного лоадера, противник:
- Створює секцію
SEC_IMAGE, підкріплену легітимною DLL (наприклад,wmp.dll). - Перезаписує mapped view повністю релокованим шкідливим PE, але залишає об’єкт секції, що вказує на безпечний образ на диску.
- Регіструє VEH і програмує debug registers так, щоб кожен виклик
NtOpenSection,NtMapViewOfSectionі, опціонально,NtCloseвикликав user-mode breakpoint. - Викликає
LoadLibrary("amsi.dll")(або будь-яку іншу benign ціль). Коли Windows loader викликає ці syscall-си, VEH пропускає перехід у kernel і повертає дескриптори та базові адреси підготовленого шкідливого образу.
Тому лоадер все ще вважає, що він замапив запитану DLL; інструменти, які дивляться лише на section backing files, бачать wmp.dll, хоча в пам’яті тепер міститься payload атакуючого. Тим часом імпорти/TLS callbacks все ще вирішуються справжнім лоадером, що значно знижує обсяг власної логіки парсингу 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.
На цьому етапі процес має RWX-здатний view, чиє backing object все ще wmp.dll, але байти в пам’яті контролює атакуючий.
Stage 2 – Hijack the loader with VEHs
- Register a VEH and arm hardware breakpoints: запрограмуйте
Dr0(або інший debug register) з адресою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. - Запишіть раніше створений дескриптор
DecoySectionу цей слот. - Просуньте
RIP/EIPдо інструкціїret, щоб виклик в ядро ніколи не відбувся. - Перепрограмуйте hardware breakpoint, щоб стежити за
NtMapViewOfSectionнаступним.
- VEH hook for
NtMapViewOfSection:
- Перезапишіть
[out] PVOID *BaseAddress(і виходи розміру/захисту) адресою вже замапленого шкідливого view. - Пропустіть тіло syscall так само, як раніше.
- (Optional) VEH hook for
NtCloseперевіряє, що фейковий section handle очищено, запобігаючи витіканню ресурсів та надаючи фінальну перевірку коректності.
Оскільки syscalls ніколи не виконуються, kernel callbacks (ETWti, minifilter тощо) не бачать підозрілих подій NtOpenSection/NtMapViewOfSection, що різко знижує телеметрію. З точки зору лоадера все пройшло успішно і amsi.dll знаходиться в пам’яті, тому він продовжує вирішувати імпорти/TLS проти view атакуючого.
PoC implementation notes (2025)
Публічний PoC показує кілька практичних деталей, які легко пропустити при повторній реалізації техніки:
- HWBPs are per-thread. PoC встановлює
CONTEXT_DEBUG_REGISTERSна поточному потоці перед викликомLoadLibrary, тож VEH має виконуватися на тому ж потоці, що й ініціює лоадер. - Syscall emulation: VEH встановлює
RAX = 0і просуваєRIPдоretвсередині ntdll-ового stub (сканує на0xC3), тож перехід у kernel ніколи не відбувається, після чого відновлює виконання черезNtContinue. - Output parameters: для
NtMapViewOfSectionVEH перезаписує повернені виходиBaseAddress,ViewSize, таWin32Protect, щоб лоадер вірив, що мапінг пройшов успішно і продовжив роботу з імпортами/TLS використовуючи 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);
Стелс-варіація
Нещодавні дослідження VEH показують, що обробники можна зареєструвати шляхом ручної маніпуляції списком VEH замість виклику AddVectoredExceptionHandler, що зменшує залежність від user-mode APIs, які можуть бути monitored or hooked. Це не є обов’язковим для Vectored Overloading, але може бути поєднано з ним, щоб зменшити помітну активність API.
Етап 3 – Виконання payload
- EXE payload: The injector просто переходить до початкової точки входу після завершення relocations. Коли loader вважає, що викличе
DllMain, кастомний код натомість виконує EXE-style entry. - DLL payload / Node.js addon: Resolve and call the intended export (Kidkadi exposes a named function to JavaScript). Оскільки модуль вже зареєстровано в
LdrpModuleBaseAddressIndex, наступні пошуки бачать його як benign DLL.
Коли поєднується з Node.js native addon (.node file), уся складна робота на рівні внутрішніх механізмів Windows залишається поза шаром JavaScript, що дозволяє threat actor постачати той самий loader з багатьма різними обфусцованими Node wrappers.
Посилання
- 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 Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.


