Direct and indirect syscalls
What it buys: a door around the user-mode hooks. EDRs instrument the documented API in kernel32/ntdll; calling the kernel directly — resolving the syscall number from ntdll's own bytes at runtime — walks past the instrumentation entirely. The meter: three readings. The SSN lottery: syscall numbers shift between Windows builds, so any technique that assumes instead of extracts is a time bomb; sorting tricks break the moment a hook reorders the table. The kernel keeps the receipt: the call still happens — thread-telemetry providers see it no matter who issued it. And the address problem: a syscall instruction executed from your own module leaves an instruction pointer in memory no legitimate call path uses. That last reading is why the C agent's stubs are indirect: the stub loads the number, then jumps into ntdll's own syscall instruction, so the pointer and the return address both live where the kernel expects them. The layer above the stub still tells a story — which is the next rental.
Unhooking
What it buys: the original bytes back — restoring ntdll.text from disk so the sensor's patches vanish. The meter: the restoration is the loudest gesture on this list. A fresh private mapping of ntdll is the oldest tell in the genre; engines that verified their hooks on a schedule notice them missing; and the moment you repair, you've timestamped your own fear for anyone correlating. Our doctrine is to route around rather than repair — indirect syscalls never need the hooks gone — and to treat patching as a gated decision: when the fingerprint says a kernel-level EDR is present (six of the sixteen families we track), the remote-patch path is skipped entirely rather than attempted and explained.
Call-stack spoofing
What it buys: the stack walk reads a boring story. Thread-start audits and ETW stack walks that chase frame pointers see returns into signed system libraries — ntdll, kernel32, kernelbase — instead of a chain ending in anonymous memory. How we run it: single-byte ret gadgets found about two-thirds deep into each library's executable section — deep enough to look like a return from a real function's middle, not its prologue — woven into a synthetic frame chain around the call. The meter: the camouflage fools frame-pointer chasers, not exception-table unwinds — .pdata walks don't follow your painted chain, and an exception raised through a fabricated frame has no real handler to find; the process dies holding its own story. So we spend it where the dwell is long — the sleep wait — not on every call. A spoof you can't afford to crash through is a spoof you use once, deliberately.
Sleep obfuscation
What it buys: the dwell is the scanner's window — a beacon spends most of its life asleep, and asleep is when memory scanners come. Ours sleeps encrypted and untouchable: registered regions (config secrets, session keys — up to 64) get XORed with an 8-byte key derived from tick count and stack entropy, then flipped to PAGE_NOACCESS; the wait itself is a one-shot timer-queue timer, and on x64 the blocking wait runs under the spoofed stack from the previous section; on wake, everything is restored and the key is zeroed. The meter: a PAGE_NOACCESS region inside a process is precisely the shape memory scanners hunt — the scanner reads what the page was, so the VAD audit catches the silhouette even when the bytes are safe. Timer queues are enumerable; a thread parked on a private event has a visible wait chain. The encryption protects the contents. It cannot make the shape of a hidden secret invisible — that layer rents to the defender too.
ETW tampering
What it buys: the event stream goes quiet — covered in full in note N.09: transient return-clean stubs on the write path, per command, with the policy cache cleared below the engine. The meter: silence is itself a signal. A host that stops emitting events it always emitted is a correlation rule with a pulse; the tamper is only as good as everything else happening on the wire at the same time. This is the recurring lesson of the whole shelf: the layer you blinded is covered, and the layer watching for blindness is not.
| Technique | Buys | Meter reading |
|---|---|---|
| Direct syscalls | Past user-mode hooks | SSN lottery; kernel telemetry; RIP in the wrong module |
| Indirect syscalls | + return address in ntdll | The stack above the stub still narrates |
| Unhooking | Original bytes restored | Fresh mapping tell; tamper checks; self-timestamped fear |
| Stack spoofing | Boring stack walks | Unwind-table disagreement; fatal on exception |
| Sleep obfuscation | Encrypted, untouched dwell | NOACCESS silhouette; enumerable timer queues |
| ETW tampering | Quiet event stream | Silence-as-signal correlation |
Why single-trick implants age badly
Detection engineering doesn't grade tricks; it correlates layers. The implant that only does direct syscalls hands the defender a stack-walk rule. The one that only unhooks hands them a mapping-integrity rule. Each single trick covers one layer and, by existing, advertises which layers its author forgot. This is why our lab grades compositions, not techniques: a revision ships because the whole stack — fingerprinted gating, indirect calls, painted stacks for the long dwells, encrypted sleeps, per-command gates — survives the matrix together, not because any member of it is clever. The trick is a line item. The composition is the product.
A bypass is not a pass. It's a rental — and the meter runs in the layer you forgot.
The defender's angle
Every row of the price list is a rule waiting for you. Audit instruction pointers on syscall entry — a syscall executed outside ntdll is a conviction. Watch for fresh private mappings of ntdll.dll and for hooks that vanish on schedule. Compare frame-pointer chains against .pdata unwinds where your telemetry allows it; the disagreement is the detection. Hunt PAGE_NOACCESS private regions and enumerate timer queues on hosts that matter. And correlate silence: the event stream that stops is the event. We'd rather be caught by these rules than believed on adjectives — build them.
Next note: How we would hunt ourselves. Detection engineering against in-memory C2, from the other side — memory by shape, periodicity by statistics, the pipe table everyone forgets, and the telemetry gaps we leave on purpose.