Easy AntiCheat Driver Load Bypass

good morning! seb here. welcome back to the blog.

this one’s big. while playing around with windows internals and anti-cheat logic, i found a pretty serious flaw in how eac handles driver enforcement during runtime. this bypass isn’t about gdrv specifically, that’s just the tool i used to prove it. the real issue is that eac only checks driver signature enforcement once, and then never again. that opens the door for unsigned drivers to load while the game is running.

let me walk you through how i figured that out.

please note that anything listed in these articles has already been disclosed to the epic team before posting and patched.


how i noticed something was off

when testing kernel-level bypasses during live gameplay, i noticed that loading a known vulnerable signed driver (like the one from the gdrvloader repo) didn’t cause any issues with eac at all. no blocked launch, no kicked session, nothing.

this made me curious. if eac sees drivers being loaded at runtime (which i know it does through image load callbacks), why isn’t it doing anything about it?

so i kept digging.


what i tested

i grabbed GDRVLoader, which is a public project that uses gigabyte's old vulnerable driver. nothing new there. what makes this driver useful is that it’s signed and lets you write to arbitrary kernel memory, so you can flip system-level flags like DSE and CiValidateImageHeaders.

i ran eac, joined a game, then used GDRVLoader while everything was live to flip both the DSE and image header validation flags.

then i did this:

  • loaded an unsigned driver post-boot

  • used it to modify kernel memory directly

  • stayed in-game the whole time

and eac did nothing at all. it didnt block the driver(s) loading, it didnt kick me out, even after waiting 5 hours of constantly reading memory from the rootcomponent of players from that same driver, it did nothing.


why this works

the issue here isn’t gdrv itself, but it’s eac’s lack of action.

eac uses PsSetLoadImageNotifyRoutine to register callbacks for when new drivers or images get loaded into memory. that part works fine, it sees the unsigned driver load.

but the problem is: it doesn’t stop anything.

no prevention, no rollback, no blocking of entry points. once that unsigned driver gets through the door, it’s game over. the driver gets full kernel access and eac is left behind watching logs.

to make things worse, eac only checks if driver signature enforcement (DSE) is active once which is during startup. so if you disable it later, it won’t know unless it checks again. and it doesn’t.


mitigation thoughts

while researching this, i also noticed that eac’s DSE integrity is only verified once during initialization. if that one check passes, it assumes everything’s fine for the rest of the game. that assumption is dangerous.

some basic fixes that would help:

  • perform runtime integrity checks on DSE-related flags like g_CiEnabled, CiValidateImageHeaders, etc.

  • monitor and re-verify signatures of loaded drivers periodically

  • on detection of an unsigned post-boot driver, kill the game or initiate immediate unload

even something as simple as polling DSE flags every few seconds would’ve caught this.


final thoughts

this flaw isn’t about gdrv. that’s just one of many ways to write kernel memory. what matters is the lack of runtime verification from eac.

driver signature enforcement exists for a reason. skipping out on rechecking it is like locking the front door and leaving the back wide open. especially in kernel anti-cheat, you can't afford to assume the system stays safe after launch, you have to keep watching.

we’ll explore some ways to harden this further in future posts. runtime integrity monitoring is next.

thanks for reading.

Last updated