Indistinguishable: What VAC Checks For, and Why Anti-Lag+ Never Stood a Chance
contents
Finale of the series. Part 1 found the hook, Part 2 the engine, Part 3 the switch. This part flips to the referee’s side of the table: what does VAC actually check, and how does each check line up against what we found?
A note on sources. VAC is closed, obfuscated, and deliberately opaque - nobody outside Valve knows its exact internals, and this post does not claim to. What follows is drawn from Valve’s own public statements, the documented behavior of CS2 Trusted Mode, and years of community reverse engineering. The goal here is defensive: to understand why a legitimate feature looked identical to a cheat, not to evade anything.
What VAC is known to look for
Strip away the mystique and an anti-cheat like VAC is doing a handful of well-understood things, mostly from inside the game process:
- Module integrity. The code (
.text) ofcs2.exeand its engine DLLs in memory should match what was loaded from disk. Hashing/comparing those bytes detects anything that rewrote them at runtime. - Inline-hook / detour detection. A function whose first bytes are now
E9 ...(jmp) orFF 25 ...(jmp[rip]) when the on-disk image says otherwise is a patched prologue - the signature of a detour. - IAT / export-table tampering. Redirected import or export entries - a classic interception point for input and rendering calls.
- Foreign modules in the process. Unsigned or unexpected DLLs mapped into the game, and threads/Windows-hooks originating from them.
- Known-cheat signatures. Byte-pattern scans of process memory for fingerprints of known tools.
- Delayed, batched enforcement. VAC famously bans in waves rather than instantly, to avoid revealing exactly what it detected.
And in CS2 specifically there’s a structural wall before any of that even matters:
- Trusted Mode. CS2 runs in Trusted Mode by default and blocks third-party DLLs from
loading into the game process unless it’s launched with
-allow_third_party_software(which itself flags the session as untrusted). It’s aimed at injected foreign DLLs - though, as we’ll see, a graphics usermode driver isn’t “third-party” in the way that wall means, and that distinction is the whole reason this one got through.
Lining it up against Anti-Lag+
Here’s the uncomfortable part. Go down that list with the findings from Parts 1-3:
| What VAC checks | What Anti-Lag+ did (this series) | Verdict |
|---|---|---|
.text integrity of engine modules | Overwrote a call site inside the game’s own engine code with an E9 detour - a runtime-resolved engine/render module, not the thin cs2.exe launcher (Part 1) | modified game code |
| Inline-hook / detour signatures | E9 prologue patch + FF 25 trampoline, via Microsoft Detours (Parts 1-2) | textbook detour |
| Hooks on input/render functions | Inline-hooked user32!GetRawInputData / GetRawInputBuffer (Part 2 - an AMD in-package hook; its tie to Anti-Lag+ is unproven) | aimbot-class hook |
| Detour markers in a module | Stamped the Detours “already-hooked” signature into the module header (Part 2) | literal detour tag |
| Foreign module behavior | Stack-walked the game with RtlCaptureStackBackTrace, then SuspendThread + SetThreadContext to patch hot code (Part 1) | injection behavior |
| Third-party code in the process (Trusted Mode) | The D3D usermode driver (amdxc64) ran and patched the game - but it loads through the legitimate graphics path, not as a third-party DLL | exempt from this wall; caught downstream by .text integrity instead |
There is not a single row where Anti-Lag+ looks different from a cheat. It modified protected
game code, it left detour signatures, it walked the stack and rewrote thread context to patch hot
code, and (whichever feature owns them) there were user32 input hooks in the same package too.
Every integrity signal fired - correctly.
That last row is the interesting one, because it’s the most counterintuitive: Trusted Mode
didn’t stop this. Trusted Mode keeps third-party DLLs out of the game - but the graphics
usermode driver isn’t third-party in that sense. It’s loaded by the Direct3D runtime through the
normal device-creation path, exactly as every game expects. So Anti-Lag+ walked straight past the
one wall built to block foreign code precisely because it was a sanctioned module - and then got
caught downstream by plain .text integrity anyway. The mechanism was privileged enough to bypass
the front door and still couldn’t survive a hash. (That also means the row above isn’t “blocked by
design” - if it had been, there’d have been no detour and no ban wave.)
Intent is invisible at the byte level
This is the whole lesson of the series in one sentence: an integrity check cannot read
intent. VAC sees an 0xE9 written over a game engine module’s prologue. It does not - cannot -
see a code comment that says // reduce input latency. AMD’s payload was benign (timestamp a
frame, sleep a few hundred microseconds, call the original). The mechanism delivering it was
identical, to the byte, to a malicious hook. Valve’s own statement drew the same line - that
detouring CS’s code would trigger a VAC ban (the full wording is in
Part 1). The through-line of this whole series is the
sharper version of it: a detour is indistinguishable from cheating to an integrity check - and
we just spent three posts proving that’s literally true at the instruction level.
The fix was never “evade better” - it was “stop hiding”
The reason Anti-Lag 2 (and NVIDIA Reflex) don’t trip anti-cheat is not a cleverer hook. It’s the opposite: there is no hook at all. The game integrates the vendor SDK and calls the latency-reduction code itself, at points the developer chose, with the developer’s consent.
Run that back through VAC’s checklist:
.textintegrity: untouched - the game’s own code calls the API.- Detour signatures: none - nothing is patched.
- Input-path hooks: none - the engine hands timing to the driver, the driver doesn’t reach in.
- Foreign module in the process: none required - it’s part of the sanctioned render path.
- Trusted Mode: satisfied - no third-party DLL is forced in.
Same end goal - shrink click-to-photon latency - and now zero signals fire, because there is nothing to detect. The work moved from behind the game’s back to inside the game, with permission. That single architectural change is the entire difference between a VAC ban wave and a shipped feature.
The series, closed
- Part 1 - the hook: patched CS2’s own code via a stack-walked Detours detour.
- Part 2 - the engine: a sibling Detours-based trampoline library in the same package - and the raw-input hooks it installs (Anti-Lag+’s, or another feature’s; I couldn’t conclusively tie them).
- Part 3 - the switch: the profile database whose one flipped byte disabled it all.
- Part 4 - the verdict: measured against everything VAC is known to check, Anti-Lag+ was indistinguishable from a cheat - because structurally, it was one.
None of this was malice. It was a latency optimization that happened to be built like an exploit. The takeaway for anyone shipping code into someone else’s process: if your feature is indistinguishable from an attack, it will be treated as one - and the only real fix is to be invited in.
End of series. All static analysis - 7-Zip, hex diffing, Ghidra over MCP. No code executed, no hooks built or modified, nothing aimed at evading anti-cheat. Defensive and educational throughout.