Manual VEH Injection - Full Demo (C++)
#include <windows.h>
#include <iostream>
#pragma comment(lib, "ntdll.lib")
// Fake VEH node matching Windows' internal structure
struct VEH_NODE {
LIST_ENTRY ListEntry; // Flink, Blink
PVOID Handler; // Our function
};
// Our custom VEH handler
LONG WINAPI MyVEH(EXCEPTION_POINTERS* ExceptionInfo) {
MessageBoxA(NULL, "Manual VEH Hook Triggered!", "Ghost Mode", MB_OK);
return EXCEPTION_CONTINUE_EXECUTION;
}
int main() {
std::cout << "[*] Setting up manual VEH...\n";
// Step 1: Allocate memory for our node
VEH_NODE* vehNode = (VEH_NODE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VEH_NODE));
if (!vehNode) {
std::cout << "HeapAlloc failed.\n";
return 1;
}
vehNode->Handler = (PVOID)MyVEH; // Set handler
// Step 2: Find the internal LdrpVectoredExceptionList
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
if (!ntdll) {
std::cout << "Cannot find ntdll!\n";
return 1;
}
LIST_ENTRY* pLdrpList = (LIST_ENTRY*)((BYTE*)ntdll + 0x18E370); // WARNING: hardcoded offset for demo!!
// Step 3: Insert into the doubly-linked list
vehNode->ListEntry.Flink = pLdrpList->Flink;
vehNode->ListEntry.Blink = pLdrpList;
pLdrpList->Flink->Blink = &vehNode->ListEntry;
pLdrpList->Flink = &vehNode->ListEntry;
std::cout << "[*] Manual VEH successfully linked!\n";
// Step 4: Trigger exception to test
__debugbreak(); // Triggers an exception -> our manually inserted VEH will catch it!
return 0;
}
Comments
Post a Comment