Research note N.11 · 2026-10-16

What each bypass still costs you.

The industry sells bypass techniques like passes: learn the trick, beat the sensor. Anyone who has run an implant past a modern EDR knows the truer shape — every technique is a rental. It buys you one layer and the meter runs in another. This is our field guide to the shelf: direct syscalls, unhooking, stack spoofing, sleep obfuscation, ETW tampering. What each one buys, what it still costs, how we run it in the C agent — and why an implant built on a single trick is a signature waiting for its correlation.

READ ≈ 8 MIN AUTHOR THE AXIS TEAM

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.

USERLAND KERNEL A — DOCUMENTED PATH · HOOKED your call kernel32 ntdll · syscall stub HOOK SET HERE syscall gate kernel meter: arguments + call stack read before entry B — THE INDIRECT PATH · ROUTED AROUND your call agent stub SSN read from ntdll bytes jmp ntdll · syscall instruction RIP + return address live here kernel user-mode hooks remain in place — simply never on the path
Fig. A — two paths, one kernelThe documented path is read; the indirect path is routed around

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.

Fig. B — the dwell, armoredContents safe; shape visible — priced accordingly

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.

TechniqueBuysMeter reading
Direct syscallsPast user-mode hooksSSN lottery; kernel telemetry; RIP in the wrong module
Indirect syscalls+ return address in ntdllThe stack above the stub still narrates
UnhookingOriginal bytes restoredFresh mapping tell; tamper checks; self-timestamped fear
Stack spoofingBoring stack walksUnwind-table disagreement; fatal on exception
Sleep obfuscationEncrypted, untouched dwellNOACCESS silhouette; enumerable timer queues
ETW tamperingQuiet event streamSilence-as-signal correlation
Fig. C — the price listEvery row a rental, not a pass

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.