The Question Everyone Gets Wrong
When ransomware groups started using BYOVD to kill EDR products at scale, a natural assumption followed: kernel-level access is the gold standard for evasion. Kill the detector, and you can do anything.
That assumption is partially correct — and partially a distraction.
There is a second class of evasion that operates on a completely different principle: not killing the detector, but becoming invisible to it. These two approaches are not variants of the same technique. They are different threat models, operating at different privilege levels, targeting different layers of the stack.
This post breaks down both approaches with technical precision — including where each actually lives in the privilege ring model.
Approach 1: BYOVD — Kill the Detector
What It Is
Bring Your Own Vulnerable Driver is a Windows kernel exploitation technique. The attacker loads a legitimately signed but vulnerable kernel driver onto the target system, exploits a flaw in that driver to reach Ring 0, and from kernel space terminates EDR processes, unregisters kernel callbacks, and operates without interference.
Why It Works
Windows requires all kernel drivers to carry a valid Authenticode signature from a trusted certificate authority. This is a security feature — but it creates a paradox. A driver signed by a legitimate vendor years ago that contains an arbitrary read/write vulnerability will load on a modern system unless it is explicitly blocklisted.
The attacker does not exploit the OS. They bring a known-vulnerable but trusted driver and exploit it. Windows sees a valid signature and allows the load.
The Attack Chain
User-space process (Ring 3)
↓
Load signed vulnerable driver (e.g., rwdrv.sys, hlpdrv.sys)
↓
Exploit driver vulnerability → arbitrary kernel R/W (Ring 0)
↓
Unregister EDR kernel callbacks
↓
Terminate EDR processes from kernel space
↓
EDR is dead — ransomware runs freely
What It Accomplishes
BYOVD’s goal is destruction of the detection layer. After a successful BYOVD attack, the EDR process is terminated or rendered non-functional. The attacker now operates in an environment where the primary detection tool no longer exists.
Active ransomware operations using BYOVD in 2026 include Qilin, Warlock, Akira, and Medusa — deploying tools like EDRKillShifter, AbyssKiller, and CardSpaceKiller. ESET Research currently tracks nearly 90 distinct EDR killer tools in active use.
Limitations
- Windows-only — the Windows driver trust model is the prerequisite
- Noisy at load time — driver load events (Event ID 12) are monitored
- Blocklists exist — Microsoft maintains a vulnerable driver blocklist; known drivers get blocked
- Attribution-friendly — specific drivers are associated with specific groups
- Requires admin/SYSTEM — you need elevated privileges before BYOVD can begin
Approach 2: User-Space Injection — Become Invisible
What It Is
A fundamentally different strategy. Rather than destroying the EDR, this approach injects code into a trusted host process from user-space (Ring 3) using ptrace, SROP, and process_vm_writev — and then operates inside that process’s identity.
The implemented example is the Phantom Evasion Loader — a pure x64 Linux Assembly injection engine.
The Threat Model
The question is not “how do I kill the EDR?” The question is: “how do I make the EDR’s detections irrelevant?”
If your implant runs inside /usr/sbin/cron, the EDR does not see a suspicious process — it sees cron. The raw socket belongs to cron. The memory allocations belong to cron. There is nothing to kill, because there is nothing foreign to find.
The Injection Chain
Loader process (Ring 3, user-space)
↓
/proc enumeration → locate target PID (e.g., cron)
↓
ptrace(PTRACE_ATTACH) — direct syscall (no libc)
↓
SROP chain: GETREGS → PEEKDATA → POKEDATA → remote mmap(RW)
↓
process_vm_writev (syscall 311) — single-pass payload write
↓
SROP chain: mprotect(RX) → SETREGS → RIP redirect
↓
ptrace(PTRACE_DETACH) — loader exits
↓
Implant runs inside cron's address space
Everything happens in Ring 3. The loader never touches the kernel in the sense BYOVD does — it uses standard Linux ptrace and cross-memory-attach interfaces. There is no driver, no kernel module, no Ring 0 access.
Why SROP Instead of Direct ptrace Calls?
Standard ptrace injection calls sys_ptrace directly with mov rax, 101; syscall. This sequence is a detectable pattern — EDRs and eBPF monitors look for it.
SROP (Sigreturn-Oriented Programming) changes the execution path. Instead of a direct ptrace syscall, we craft a fake sigcontext frame on the stack and invoke sys_rt_sigreturn (syscall 15). The kernel restores CPU state from our frame — including RAX, RDI, RSI — and the ptrace call fires through the kernel’s signal return path.
; SROP frame setup — ptrace fires via kernel signal return, not direct syscall
mov qword [rbp + 0x90], 101 ; RAX = sys_ptrace
mov qword [rbp + 0x68], 16 ; RDI = PTRACE_ATTACH
mov [rbp + 0x70], r13 ; RSI = target PID
lea rax, [rel x_syscall]
mov [rbp + 0xA8], rax ; RIP = landing address
mov rax, 15 ; sys_rt_sigreturn
syscall ; kernel restores state from frame
To a behavioral monitor watching syscall sequences, this looks like a signal return — not a ptrace call.
Why process_vm_writev Instead of PTRACE_POKEDATA?
Classic injection writes payload 8 bytes at a time via PTRACE_POKEDATA — one ptrace event per write. For a 1632-byte payload, that is 204 separate ptrace events.
process_vm_writev (syscall 311) writes the entire payload in a single cross-process memory operation. One syscall. No ptrace write loop. Most behavioral monitors do not flag process_vm_writev in the context of a process that already has ptrace attached.
What the Detection Results Show
| Platform | Result |
|---|---|
| VirusTotal (65 engines) | 0/65 |
| Hatching Triage | Score 8/10 — ptrace entry detected |
| Triage — SROP injection | Not detected |
| Triage — process_vm_writev | Not detected |
| Triage — post-injection activity | Not detected |
Triage saw the initial ptrace attach. It missed the entire injection mechanism and everything after.
Limitations
- Linux-only — ptrace and process_vm_writev are Linux interfaces
- Requires unconfined target — AppArmor/SELinux confined processes block mprotect
- Root required — ptrace against system services needs elevated privileges
- User-space boundary — cannot directly manipulate kernel structures or terminate EDR at kernel level
The Core Difference
This is the critical distinction that the “kill the EDR” framing obscures:
| BYOVD | User-Space Injection | |
|---|---|---|
| OS | Windows | Linux |
| Privilege ring | Ring 0 (Kernel) | Ring 3 (User-space) |
| Goal | Destroy the EDR | Become invisible to it |
| Mechanism | Vulnerable driver exploit | SROP + CMA injection |
| EDR relationship | EDR is terminated | EDR sees nothing suspicious |
| Detection surface | Driver load events | ptrace syscalls (entry only) |
| Persistence | Kernel-level | Inside host process identity |
| Noise level | High at load time | Low throughout |
Two Different Defensive Problems
These approaches require different defensive responses.
Against BYOVD:
- Vulnerable driver blocklists
- Kernel Integrity Policy enforcement
- Monitor Event ID 12 (driver load)
- Detect service termination patterns
Against user-space injection:
- eBPF-based syscall monitoring (ptrace sequence detection)
- Process memory baseline diffing (
/proc/PID/maps) process_vm_writevbehavioral correlationSOCK_RAWsocket attribution per service baseline
The problem with the second list is that most production environments do not implement it. cron holding a SOCK_RAW socket is unusual — but unless a security team maintains a strict baseline of expected socket types per service, it will not be flagged.
Which Is “Better”?
Neither. They solve different problems for different environments.
BYOVD is a Windows technique optimized for ransomware pre-encryption phases — you need to stop the EDR from interfering with mass file encryption. The noise at driver load time is acceptable because the ransomware’s encryption phase is far noisier anyway.
User-space injection is a Linux technique optimized for long-term stealth — C2 implants, persistent access, covert exfiltration. The goal is not a brief window of EDR blindness but permanent invisibility within a trusted process identity.
The assumption that “kernel = more powerful = better evasion” misses the actual objective. If your implant never appears as a separate process, the kernel layer is irrelevant. The EDR has nothing to kill.
Conclusion
BYOVD and user-space injection are not competing implementations of the same idea. They operate at different privilege levels, target different operating systems, and pursue fundamentally different evasion strategies.
BYOVD asks: how do I destroy the detector?
User-space injection asks: how do I make detection irrelevant?
Both questions have valid answers. The threat model determines which question matters.
Further Reading
- Source Code GitHub : Phantom Evasion Loader — SROP + process_vm_writev
- Blog : Phantom Evasion Loader — SROP + process_vm_writev
- Blog : ICMP-Ghost C2 — Pure Assembly C2 Framework
- Source Code Github : ICMP-Ghost C2 — Pure Assembly C2 Framework
- Blog : Evasion Techniques in Pure x64 Assembly
- Blog : Pure Assembly vs C/Rust: Detection Surface Analysis
⚠️ Legal Disclaimer
This article is written for educational purposes and authorized security research only. Understanding offensive evasion techniques is essential for engineering more resilient detection systems. Unauthorized access to computer systems is illegal.