EDR Evasion in 2025: What Still Works and Why
The antivirus landscape of 2019 is unrecognizable compared to today. Where signature-based engines once dominated, modern Endpoint Detection and Response (EDR) solutions now deploy kernel callbacks, behavioral analysis, memory scanning, and cloud-enriched telemetry. As a red teamer, this means the bar for evasion keeps rising — but so do the techniques.
This post covers what still works in 2025, what’s been burned, and why some techniques outlast others.
Why Traditional Evasion Is Dead
Custom packers, base64 encoding, and XOR obfuscation worked beautifully in 2018. In 2025, they’re burned immediately. Modern AV/EDR products:
- Emulate execution in a sandbox before allowing the file to run (static bypass isn’t enough)
- Hook userland API functions in NTDLL to intercept process/memory operations
- Scan memory regions periodically for shellcode or PE patterns
- Watch ETW (Event Tracing for Windows) for suspicious calls
- Monitor kernel callbacks for process creation, thread creation, and image loading
The shift is from file-based detection to behavior-based detection. You can change what your binary looks like on disk all you want — what matters is what it does at runtime.
What Still Works: A Technical Breakdown
1. Direct Syscalls (HellsGate / HalosGate)
EDRs hook userland NTDLL functions by inserting a jmp instruction at the function prologue, redirecting calls to their monitoring module. Direct syscalls bypass this entirely by calling the kernel directly.
// Traditional (hooking opportunity exists):
// call -> NtAllocateVirtualMemory (ntdll) -> [EDR jmp hook] -> EDR module -> kernel
// Direct syscall (no hook hit):
// call -> our_stub -> mov eax, SSN -> syscall -> kernel
Why it still works: EDRs can’t trivially hook kernel interrupt handlers. If you call syscall directly with the correct SSN, the EDR’s userland hook is bypassed entirely.
Limitation: Some EDRs now detect the pattern of syscall stubs appearing in non-ntdll memory regions via kernel callbacks on thread creation. Mitigation: spoof the syscall return address to look like it came from ntdll.
2. NTDLL Unhooking (Fresh Map)
Load a clean copy of NTDLL from \KnownDlls\ntdll.dll or directly from disk, then overwrite the hooked .text section in the process’s loaded NTDLL with the clean version.
Why it still works: Most EDRs don’t detect the NTDLL overwrite itself. They only hook on module load — once loaded, they don’t continuously re-verify their hooks.
Limitation: Some advanced EDRs (e.g., CrowdStrike Falcon) re-hook NTDLL from kernel space after noticing the userland hooks were removed. Counter: use direct syscalls after unhooking to minimize the detection window.
3. Sleep Obfuscation (Ekko / Foliage / Zilean)
Memory scanners run on a schedule. If your shellcode is encrypted during the scan window, it’s invisible.
Modern variants use:
- APC-based obfuscation (Ekko): Uses timer APCs and
RtlCreateTimer— noCreateThreadorNtCreateThreadExcalls. - Obfuscating the stack during sleep using
RopHookgadgets to make the thread appear to be sleeping in a legitimate function. - Encrypting with
SystemFunction032(a legitimate Windows export) instead of custom crypto routines, reducing behavioral anomalies.
4. Process Injection via Callback Functions
Creating threads (CreateThread, NtCreateThreadEx, RtlCreateUserThread) is a heavily monitored action. Instead, execute shellcode through Windows callback mechanisms:
// EnumSystemLocalesA callbacks are far less suspicious than CreateThread
EnumSystemLocalesA(cast[LOCALE_ENUMPROCA](pShellcode), 0);
// Other legitimate callback-based execution primitives:
// - EnumDesktopsA
// - EnumTimeFormatsA
// - SetTimer (WinProc callback)
// - CreateThreadpoolWait
These execute shellcode in the context of the current thread, bypassing thread-creation monitoring.
What’s Burned
- PowerShell AMSI bypasses using reflection: Widely signatured. Use compiled .NET, Go, or Nim instead.
- Metasploit/Cobalt Strike default shellcode: Detected by every major EDR. Always generate custom shellcode.
- VBA macros in Office: Heavily blocked in enterprise environments. The phishing delivery chain needs to change.
- Simple XOR/base64 packing: Emulated and detected within seconds.
The Meta-Lesson
EDR evasion is an arms race. Every technique documented publicly has a finite lifespan. The goal of a red teamer is not to find a magic bypass — it’s to understand the detection principles well enough to adapt.
Study how EDRs work at the kernel level. Read driver code. Understand ETW providers. The deeper your understanding, the longer your techniques remain viable.
The best evasion in 2025 is behavioral legitimacy — making your malicious actions look indistinguishable from normal administrative operations. That’s a much harder problem to solve than signature bypasses, and it’s where the craft truly lives.