Vectored Overloading PE Injection
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Tip
Szukasz technik kształtowania heap LFH w Windows 11 oraz ucieczki z VMware Workstation PVSCSI (vmware-vmx)?
{{#ref}} vmware-workstation-pvscsi-lfh-escape.md {{#endref}}
Technique overview
Vectored Overloading to podstawowy prymityw wstrzykiwania PE dla Windows, który łączy klasyczny Module Overloading z Vectored Exception Handlers (VEHs) oraz hardware breakpoints. Zamiast patchować LoadLibrary lub pisać własny loader, przeciwnik:
- Tworzy sekcję
SEC_IMAGEpowiązaną z legalnym DLL (np.wmp.dll). - Nadpisuje mapped view kompletnie zrelokowanym złośliwym PE, ale pozostawia obiekt sekcji wskazujący na benign obraz na dysku.
- Rejestruje VEH i programuje rejestry debugowania tak, żeby każde wywołanie
NtOpenSection,NtMapViewOfSection, i opcjonalnieNtClosegenerowało user-mode breakpoint. - Wywołuje
LoadLibrary("amsi.dll")(lub inny benign cel). Kiedy loader Windows wywołuje te syscallsy, VEH pomija przejście do kernela i zwraca uchwyty oraz base address przygotowanego złośliwego obrazu.
Ponieważ loader nadal wierzy, że zmapował żądany DLL, narzędzia które patrzą tylko na pliki backing section widzą wmp.dll, mimo że pamięć zawiera teraz payload atakującego. Tymczasem importy/TLS callbacks są nadal rozwiązywane przez prawdziwy loader, co znacząco zmniejsza ilość własnej logiki parsowania PE, którą musi utrzymywać przeciwnik.
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);
- Kopiuj złośliwy PE do tego view sekcja po sekcji, respektując
SizeOfRawData/VirtualSizei aktualizując ochrony po tym (PAGE_EXECUTE_READ,PAGE_READWRITE, itd.). - Zastosuj relocacje i rozwiąż importy dokładnie tak jak zrobiłby to reflective loader. Ponieważ view jest już zmapowane jako
SEC_IMAGE, alignmenty sekcji i guard pages pasują do tego, czego później spodziewa się Windows loader. - Znormalizuj nagłówek PE:
- Jeśli payload jest EXE, ustaw
IMAGE_FILE_HEADER.Characteristics |= IMAGE_FILE_DLLi wyzeruj entry point, aby zapobiec skokowiLdrpCallTlsInitializersdo stubów specyficznych dla EXE. - DLL payloady mogą pozostawić nagłówki bez zmian.
W tym momencie proces posiada view z możliwością RWX, którego backing object nadal wskazuje na wmp.dll, podczas gdy bajty w pamięci są kontrolowane przez atakującego.
Stage 2 – Hijack the loader with VEHs
- Zarejestruj VEH i ustaw hardware breakpoints: zaprogramuj
Dr0(lub inny rejestr debugowania) na adresntdll!NtOpenSectioni ustawDR7tak, żeby każde wykonanie generowałoSTATUS_SINGLE_STEP. Powtórz później dlaNtMapViewOfSectioni opcjonalnieNtClose. - Wywołaj ładowanie DLL z
LoadLibrary("amsi.dll").LdrLoadDllostatecznie wywołaNtOpenSection, aby uzyskać prawdziwy handle sekcji. - VEH hook dla
NtOpenSection:
- Znajdź slot na stosie dla
[out] PHANDLE SectionHandleargumentu. - Zapisz wcześniej utworzony uchwyt
DecoySectiondo tego slotu. - Przesuń
RIP/EIPdo instrukcjiret, tak żeby kernel nigdy nie został wywołany. - Ponownie ustaw hardware breakpoint, aby obserwować
NtMapViewOfSectionnastępnie.
- VEH hook dla
NtMapViewOfSection:
- Nadpisz
[out] PVOID *BaseAddress(i wyjścia dotyczące rozmiaru/ochrony) adresem już zmapowanego złośliwego view. - Pomiń ciało syscalla tak jak wcześniej.
- (Opcjonalne) VEH hook dla
NtCloseweryfikuje, że fałszywy handle sekcji jest posprzątany, zapobiegając wyciekom zasobów i dostarczając końcową kontrolę sanityzacji.
Ponieważ syscallsy nigdy nie są wykonane, callbacky jądra (ETWti, minifilter, itd.) nie obserwują podejrzanych zdarzeń NtOpenSection/NtMapViewOfSection, co drastycznie obniża telemetrię. Z punktu widzenia loadera wszystko się powiodło i amsi.dll jest w pamięci, więc kontynuuje rozwiązywanie importów/TLS używając view atakującego.
PoC implementation notes (2025)
Publiczny PoC pokazuje kilka praktycznych detali, które łatwo przeoczyć podczas ponownej implementacji techniki:
- HWBPs są per-thread. PoC ustawia
CONTEXT_DEBUG_REGISTERSna aktualnym wątku przed wywołaniemLoadLibrary, więc VEH musi uruchomić się na tym samym wątku, który wyzwala loader. - Emulacja syscalli: VEH ustawia
RAX = 0i przesuwaRIPdoretwewnątrz stubuntdll(skanuje w poszukiwaniu0xC3), tak że przejście do kernela nigdy nie następuje, a następnie wznawia wykonanie zNtContinue. - Parametry wyjściowe: dla
NtMapViewOfSection, VEH nadpisuje zwracaneBaseAddress,ViewSizeiWin32Protect, tak aby loader uwierzył, że mapowanie powiodło się i kontynuował z importami/TLS używając view atakującego.
Minimalna konfiguracja HWBP użyta w 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);
Wariant stealth
Najnowsze badania związane z VEH pokazują, że handlery można zarejestrować poprzez ręczną manipulację listą VEH zamiast wywoływać AddVectoredExceptionHandler, co ogranicza poleganie na user-mode APIs, które mogą być monitorowane lub hooked. Nie jest to wymagane dla Vectored Overloading, ale można to połączyć, aby zmniejszyć obserwowalną aktywność API.
Etap 3 – Uruchom payload
- EXE payload: Injector po prostu skacze do oryginalnego entry point, gdy relocations zostaną wykonane. Gdy loader zakłada, że wywoła
DllMain, niestandardowy kod zamiast tego wykonuje EXE-style entry. - DLL payload / Node.js addon: Rozwiąż i wywołaj docelowy eksport (Kidkadi udostępnia nazwaną funkcję dla JavaScript). Ponieważ moduł jest już zarejestrowany w
LdrpModuleBaseAddressIndex, kolejne wyszukiwania traktują go jako nieszkodliwy DLL.
W połączeniu z natywnym addonem Node.js (.node file), cała praca związana z Windows-internals pozostaje poza warstwą JavaScript, co pomaga threat actorowi dostarczać ten sam loader z wieloma różnymi obfuskowanymi wrapperami Node.
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
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


