EDR-Injector-Driver-POC
A Windows kernel-mode driver that automatically injects a DLL into newly created processes using APC (Asynchronous Procedure Call) injection. This driver intelligently waits for essential system DLLs to load before injecting, ensuring a stable injection environment.
This proof-of-concept demonstrates techniques commonly used by EDR (Endpoint Detection and Response) solutions for process instrumentation and monitoring.
This driver implements DLL injection by monitoring both process creation and image (DLL) loading events. Rather than injecting immediately at process creation, the driver intelligently waits for critical system DLLs to be loaded:
ntdll.dll (native) - Required to obtain the LdrLoadDll function address
kernel32.dll - Required because most injected DLLs depend on kernel32 APIs
WOW64 DLLs (for 32-bit processes on 64-bit Windows) - wow64cpu.dll and the WOW64 ntdll.dll
Once these essential DLLs are loaded, the driver performs "thunkless" APC injection by directly calling
LdrLoadDll from ntdll.
Smart Injection Timing | Waits for essential system DLLs before injecting (ntdll, kernel32, WOW64 DLLs)
Image Load Monitoring | Uses PsSetLoadImageNotifyRoutine to track DLL loading per process |
Thunkless APC Injection | Directly invokes LdrLoadDll from ntdll without requiring shellcode |
WOW64 Support | Handles both native x64 and WOW64 (32-bit on 64-bit) processes |
Process State Tracking | Maintains a linked list of processes and their injection state |
Protected Process Detection | Automatically skips injection for protected processes (PPL) |
Export Table Walking | Resolves LdrLoadDll address by parsing ntdll's export directory |
The driver uses two kernel callbacks to implement its injection logic:
- Tracks new process creation and termination
- Maintains a linked list of
PROCESS_INFOstructures for each process
- Monitors every DLL that loads in each process
- Tracks specific system DLLs using bitflags:
SYSTEM32_NTDLL_LOADED(0x0001)SYSTEM32_KERNEL32_LOADED(0x0002)SYSWOW64_NTDLL_LOADED(0x0004)SYSTEM32_WOW64CPU_LOADED(0x0020)- When ntdll.dll loads, extracts the
LdrLoadDllfunction address from its export table - Once all required DLLs are loaded, queues an APC for injection
When all essential DLLs are loaded:
- Create shared memory - Uses
ZwCreateSectionandZwMapViewOfSection - Copy DLL path - Writes the target DLL path into the shared section
- Queue APC - Sets
LdrLoadDllas the APC routine - Execute - The APC runs in the target process context, calling
LdrLoadDllto load your DLL
Process Created → Track in List → Monitor DLL Loads → Wait for ntdll.dll + kernel32.dll ↓ DLL Loaded ← Execute APC ← Queue APC ← All DLLs Ready!
- OS: Windows 10/11 (x64)
- IDE: Visual Studio 2019 or later
- WDK: Windows Driver Kit (WDK) 10
- SDK: Windows SDK
- OS: Windows 10/11 (x64)
- Privileges: Administrator/System privileges
- Signing: Test signing enabled OR proper driver signing certificate
Step 1: Clone the repository
git clone https://github.com/yardenadi24/EDR-Injector-Driver-POC.git
cd EDR-Injector-Driver-POCStep 2: Open in Visual Studio
- Open
InjectionDriver.slnin Visual Studio Step 3: Select Configuration - Choose Debug or Release
- Select x64 platform Step 4: Build
- Press
F7or go to Build → Build Solution - The compiled driver (
.sysfile) will be in the output directory
bcdedit /set testsigning onThen reboot your system.
- Restart Windows
- Press
F8during boot - Select "Disable Driver Signature Enforcement"
# Create the service
sc create InjectionDriver type= kernel binPath= C:\path\to\InjectionDriver.sys
# Start the driver
sc start InjectionDriver- Download OSR Driver Loader
- Select the driver file
- Click "Register Service"
- Click "Start Service"
# Stop the driver
sc stop InjectionDriver
# Delete the service
sc delete InjectionDriverThe DLL paths are defined in InjDrv.cpp and InjDrv.h:
#define DLL_PATH64 L"C:\\Windows\\System32\\HookDllx64.dll"
#define DLL_PATH86 L"C:\\Windows\\System32\\HookDllx86.dll"- Place your 64-bit DLL at:
C:\Windows\System32\HookDllx64.dll
- Place your 32-bit DLL at (for WOW64 processes):
C:\Windows\System32\HookDllx86.dll
- The driver automatically selects the appropriate DLL based on target process architecture
- To use different paths, modify the
#definestatements before compilation
This is a proof-of-concept for educational purposes only.