Reading protected game memory with no driver

I just wanted to share this little fun thing. I already did so on the UC forum a while back, but I also decided to write this blog post since some people might have missed it.

Most modern anti-cheats register a handle creation callback to strip any permissions that could allow user-mode processes to read/write the game's memory, and then they loop through the handle table to check that someone hasn't overwritten it back.

NtReadVirtualMemory uses MiReadWriteVirtualMemory which calls ObReferenceObjectByHandleWithTag to both get the target process and check the handle permissions.

Official documentation about this function has a little fun fact about it:

All you need to do to bypass those access checks is to set PreviousMode in ETHREAD struct to KernelMode. Doing that will allow any handle to have memory read/write access. You will still need a vulnerable driver to rewrite the structure, but you can unload it before starting the game/anti-cheat. I have written an example project that uses a vulnerable Intel driver to archive precisely that.

It has some side effects though, so you should run a dedicated thread just for memory read/write.