Hi. I wanted to write about this long-form because this is a very interesting concept, and I think that others may also find it interesting. Over the past couple of years, I’ve been able to work with (and against) both Anti-Cheats (ACs) and Anti-Viruses (AVs)/Endpoint Detection and Response (EDR) and I have been quite impressed with how similar they both function with regards their structure and functionality. I wanted to write about this because not only are there glaring technical similarities, but there are opportunities for you on a professional level that involves working on things such as these.
To start, I will start with a confession. I am (was) a video game cheat developer. I wasn’t a very good one, but I was one. I learned how to reverse engineer, I learned how to write programs to manipulate other programs, and there was even a brief period where I learned how to bypass AC detections. Most of my work was actually mods, but some were in fact programs that you could call “cheats”. I’ve actually written an article about this where I instruct you how to write a very simple cheat on a game of pong.
It wasn’t until right before I was hired as a kernel developer and reverse engineer where I began to really understand how modern cheating actually worked, namely:
Why cheat devs even want to write a cheat
Why it is so “hard” to write a cheat for a AAA title
How ACs work
Why modern cheats need the kernel
After I was hired at my current job, I was put into a squad on the EDR team, where we are basically the rootkit detector squad. Here, I learned about, you guessed it, rootkits. Half of my job (I explain the other half here) is basically reverse engineering rootkits and figuring out how our EDR can detect them, then writing the code on how to detect those rootkits. I have learned how they actually work, namely:
Why maldevs even want to write a rootkit
Why it is so “hard” to write a rootkit that bypasses modern EDRs
How EDRs work
Why rootkits need the kernel
I definitely wrote these bullet points with a bias, but you can see the similarities already.
Before I finally get into the specifics, I need to establish a few more things.
I will focus more on EDRs rather than AVs as the latter focus more on preventing the infection in the first place. EDRs are more akin to ACs in that they actually monitor the system and detect the anomalies, more specifically in our case, in the kernel.
The “goals” of EDRs and ACs are of course different. As such, the leeway and abilities of each establish an incomparable difference on some points. I will elaborate on these when I get to them. A prime example is the fact that, when running a cheat, in most cases, you are exploiting and thus rootkitting your own machine and of course would have to disable your AV/EDR to do so as such a thing would most likely be prevented or quarantined by them.
I will have a bit of a bias when it comes to ACs. I am actually quite fond of the engineering behind the development of these. I find that anti-cheat engineers are at the forefront of kernel development and rootkit exploit defense. Until recently, it was malware that developed the kernel exploits, which cheat developers would copy and use for their AC bypasses some time later (~a year or so, depending on severity). Now, I would say it is roughly neck-and-neck between malware and cheat kernel privilege-escalation exploits. The reason for this change I am led to believe has to do with supply, demand, and stakeholders. Maldevs make their money either by selling their exploit or burning it themselves for some hacktivist/political whatever they would abuse it for. Cheat devs make their money by creating and selling a product to others (basically SAAS). There is a very, very high demand for cheats on AAA titles, and cheat devs are making thousands (some millions!) per year developing and selling cheats. All of this is illegal in most countries, but that doesn’t stop people.
I have hopefully contextualized a few things for you, and now I can finally start singling out and comparing things. I will sum up with some career paths as well.
I will focus more on cheats and anti-cheats, because I find it more interesting and so that I don’t end up repeating myself as I discuss EDRs.
I’ve briefly established the “why” behind cheats, but I’ll explain a little bit more. I just discussed how much money can be made if you are a cheat developer, but why do people want to cheat?
I believe that it is a cultural thing. Cheating is more frequently done in China, Russia, and South Korea, and I believe this falls in line with a more “win by any means” type of culture. This is more so true with Russia and China, but South Korea sees gaming as a national pastime, much like how Americans view football as theirs. There is a lot of money to be made with the frequent E-Sports tournaments in the country, so it’s understandable to see the demand there. Lastly there are of course Americans and Europeans who cheat, which are usually just degenerates that want to win without trying.
Anyways, there is a huge demand for cheats, and there aren’t very many cheat developers as 1: it is very illegal in most every country in the world, and 2: it is very hard to write a cheat that bypasses modern ACs.
Low supply + high demand = $$$
Why is it so hard? ACs defend a process (the game) from any sort of manipulation by other processes. That simple cheat I wrote in the article I linked earlier? It would not ever be able to write memory to the other process. And even if it could, a good anti-cheat would clearly detect the anomaly and then close the game and/or ban your account. The reason why is that any modern AC operates in the kernel.
I keep mentioning kernel, and the reason why is that the kernel (ring-0, whatever you want to call it) is a position in the operating system that has the highest privilege. It has the rights and privileges to read and write memory anywhere it pleases, unless if course that memory is invalid which would cause a Blue Screen of Death (BSOD). At the same time, the kernel also has the ability to revoke those rights and privileges from other processes/modules. Games/processes run in user mode (ring-3, lower ring = higher privilege), where they have a fixed privilege and can only operate under an “umbrella” of rights.
A simple example is that in the cheat article, I call OpenProcess
with PROCESS_ALL_ACCESS
. This function invokes a call to the kernel and returns a HANDLE
. All an AC has to do is remove (“strip”) the permissions supplied with the HANDLE
from the kernel. This in turn changes the access received by the cheat process, and thus calls to ReadProcessMemory
/WriteProcessMemory
would (presumably) fail. There is nothing (at least, very little) that the user-mode cheat process can do now, since it cannot read and write memory to the game process. A mitigation here is to instead make an internal cheat, but that is an explanation for another time; I digress. I could continue on with examples and explanations, but I would have a 5000 word article in no time, so I will assume you get the gist of the why re: usermode.
Therefore, finally, any cheat worth a damn is a kernel-mode cheat. It requires the author to write both a kernel driver and a usermode process/DLL to communicate with the driver. There are a few Windows security quirks in which you can’t just load an unsigned (cheat) driver, at least not normally. In most cases, a cheat (loader) will download a vulnerable driver that is signed and can be exploited to write/allocate kernel memory (“vuln driver”), and then the loader will then exploit the vuln driver to map its cheat driver into kernel space. There are lots of these vulnerable drivers, many of which are signed by popular companies like MSI, ASUS, etc. Now that the cheat driver is mapped into kernelspace, this is functionally a rootkit; malware, if you will. Yes, cheats are functionally malware. Lastly, all that is needed is a way to communicate with the cheat driver from usermode (and run that cheatsy kernel code with all of those permissions).
Due to the semantics of the kernel, it is not as cut-and-dry as “load the driver and magic cheat stuff happens”. Drivers do not “run” like processes, they “sit” in their “position of authority” and handle requests from usermode (which is everything you use on a computer on a daily basis). Therefore, a method of communicating with the cheat driver is required. There are thousands of ways to do this, but a simple one is to hook/detour a syscall somewhere in the kernel and redirect control flow to the cheat driver code. So, whenever the syscall is invoked from usermode, on that specific one, the cheat driver can run its code. So you can easily tell the cheat driver “do this, do that, do all these things for me that I can’t do from usermode”. And then, you would be able to successfully cheat in an AC-defended game.
Now, that took about 5 paragraphs to explain, and I left about 50 paragraphs of explanations out of it, like dealing with PatchGuard and checksums, and any other sort of detection specifics. This goes to show that there is a lot that goes into developing a modern cheat and it is not for the faint of heart.
So, the running of a modern cheat is like so:
(Drop and) load a vulnerable driver (or sign and load the cheat driver yourself)
Exploit the vuln driver to map the cheat driver
Do things to hide the driver, like remove the files
Harness some sort of communication method
Communicate with driver from usermode to cheat
Which is functionally a rootkit, a la malware.
Rootkits, in malware form, function almost exactly the same. I’m going to try to not repeat myself, but there is very little difference here. A problematic difference that I will expand on during comparisons is that ACs are running at a disadvantage. AVs and EDRs work together to prevent AND respond to malicious code. Running a cheat means that there are no preventative measures in place, as you most likely disabled your AV in order to run it. The only thing an AC can do is respond, which is very difficult to do if there is a good cleanup crew that removes all of the evidence of a rootkit infection.
The main differences between a rootkit and a cheat is that a rootkit targets the entire system instead of just a single program. It also may try to establish persistence and remain on the machine even after a reboot, whereas a cheat will usually be fully removed after a reboot. Cheats are of course obvious to the user and clearly show the user that they are present, whereas a rootkit may want to hide itself and not indicate that the machine is compromised. The scope of operation is different, but functionally, kernel cheats and rootkits are basically the same.
EDRs respond to rootkits by quarantining the process(es) that issues those kernel communications, and also by possible cutting off any C2 communication to outside of the machine. This was discussed already, but ACs usually just close the game. If the EDR is really good, it could even attempt to restore the machine to a clean state.
Now, finally, we can actually compare. I keep saying this but there is so much context that I need to supply so that you can fully understand why I find this so interesting.
I will opt to use ACs as my comparator.
An AC’s goal is to defend a process, the game. Given that there is only one process to defend, it has much more leeway and can be much more aggressive than an EDR. An EDR’s goal is to defend the machine, in its entirety. For example, if there is something that is hooked in the kernel, this could be something legitimately done by something like an EDR/AV, but the AC has every right to defend itself, and can choose to close the game and tell the user of an incompatible environment. Secondly, since there is only one process to defend, an AC can use more computational resources and aggression to issue defensive measures. It would be unwise for an EDR to strip handles from any process that opens any other process, but an with an AC it would make sense as it does not want any process to be able to open a handle to the game with full permissions. ACs issue hooks and detours on modules in the game (usually with their supplying anti-cheat module) and can detect detours that already exist or that overwrite their own. To put it simply, ACs defend one process better than EDRs defend all processes. The reason why is because they can. It is their process. It is their game. They have every right to.
ACs are basically rootkit detectors, which funnily enough is exactly what my job entails doing, so I resonate here. There are numerous measures that an AC can take to issue an enforcement, which could either be closing the game or banning your account. This once again gives the AC more leeway than an EDR. Your EDR can allow you to run a vulnerable driver, but an AC may not and it may close the game if one is found. This is different than an EDR shutting your computer down or quarantining the threat file(s), as this is loud and is not the same as a process closing. To summarize, ACs are able to be more aggressive as their enforcement actions are not as intrusive as an EDR’s.
Lastly, because of this aggression and also because of one other reason, I believe that ACs are better at detecting rootkits than many modern EDRs. The latter reason being that game companies have sunk millions of dollars building engineering teams to construct these ACs as cheats can completely decimate a game’s player base (see Team Fortress 2; exception to this statement: Counter-Strike 2). Valve incredibly contains a case-in-point example of this observation and also has the exception to it.
A few more things. This is a great paper that compares modern anti-cheats. Riot is of course on top because they are boot-time (ring- -1, lol) and have an even higher position of privilege than kernel-mode.
There is a stigma against the concept of kernel-level anti-cheats. This is apparently due to the fact that it is believed that they are being used as spyware. I believe that this is unfounded due to the fact that most of the people who complain about this are running Windows, and secondly, because you can run spyware in user-mode. I wrote a keylogger and showed it to everyone. It was pretty easy.
I mentioned the amount of money being sunk into anti-cheat development. You can get in on that, yaknow. There is still a massive amount of work to be done as all of the anti-cheat progress has been restricted to just Windows (this is the problem with anti-cheat on Steam Deck and AAA titles). Therefore, if you are a Linux kernel nerd, or want to be a Linux kernel nerd, you will be in high demand in the near future. Or if you are just a kernel nerd, you are in demand.
I hope this post was enlightening. I had a lot of fun writing it, and I could’ve written much more on examples of kernel exploitation. Perhaps another time I can share some cool things I’ve seen out in the wild.
Take care, and Merry Christmas!
Go!
-BowTiedCrawfish