API Unhooking — Restoring ntdll to a Clean State
What EDR Hooks Are
┌──────────────────────────────────────────────────────────────────────┐
│ EDR Hooking Process │
│ │
│ 1. Process created (suspended) │
│ 2. EDR driver receives PsSetLoadImageNotifyRoutine callback │
│ 3. EDR injects its DLL via section mapping │
│ 4. EDR DLL walks ntdll.dll exports in memory │
│ 5. For each target function: │
│ │
│ BEFORE hook: │
│ ntdll!NtCreateFile: │
│ 4C 8B D1 mov r10, rcx │
│ B8 55 00 00 mov eax, 0x55 │
│ 0F 05 syscall │
│ C3 ret │
│ │
│ AFTER hook (EDR installed): │
│ ntdll!NtCreateFile: │
│ E9 XX XX XX jmp <EDR_DLL+offset> ← 5 bytes overwritten │
│ XX 00 00 00 │
│ 0F 05 syscall ← rest intact │
│ C3 ret │
└──────────────────────────────────────────────────────────────────────┘Technique 1: Overwrite ntdll with a Copy from Disk
Why Disk is Trustworthy
Technique 2: Mapping via NtMapViewOfSection (without CreateFileMapping)
Technique 3: Selective Unhooking per Function
Technique 4: Unhooking via Duplicate Module (Loading a Second ntdll)
Unhooking Detection
Combined Approach in Real Engagements
References
PreviousIndirect Syscalls — Preserving a Legitimate Stack TraceNextProcess Hollowing — Gutting Legitimate Processes
Last updated