Thumbnail for How to Bypass Anti-Cheat Like a Pro Game Hacker by Guided Hacking

How to Bypass Anti-Cheat Like a Pro Game Hacker

Guided Hacking

35m 22s5,284 words~27 min read
Auto-Generated

[0:00]In this talk, I'll be sharing some of my game hacking experience and some of the ways or some of the techniques that these hackers might be using to out hack you all. And it's up to you what you want to do with this knowledge. Maybe you want to make a private cheat for yourself because you know you just suck at gaming. Or maybe you want to earn a lot of money because you can make these cheats and sell these cheats as well, and it's a multi-million dollar industry and also, uh, the things that you learn in this game hacking can also be used in other stuff like malware analysis. And if you're wondering what hardcore or rage hacking looks like, uh, so this is an example.

[0:46]So, so basically it's a nightmare. So these hackers won't even let you spawn and as soon as you spawn, uh, boom, it's a headshot. So on the left we have Valorant, which is very popular for its strongest anti-cheat in the market. And on the right we have Counter-Strike, which is also popular, but for the worst anti-cheat in the market. So, so it doesn't really matter how good or bad the anti-cheat is, the hackers are still gonna hack. So, a little bit intro about myself. I'm Rohan Agarwal. I go by the handle Nahoragg, and I do bug bounties, and I'm founder at Defcore Security. I've also participated in live hacking events and I also love playing games, of course, without cheats. So, this is what we're going to cover. Uh, first we'll see briefly some history about cheats versus anti-cheats, some basics. And I'll, I'll do, I'll show you kernel cheats, uh, some external hardware cheats and then demo of both of them. So, so the very first game was launched is launched in 1957, and it was a tennis game, and it was only available in a laboratory. So it the gaming at that time wasn't very popular. But it became popular in 1970s and 1980s when gaming console and desktop was started getting available for general public. And in 1980s, modding of games started happening using command style hex editors. And the first aimbot was made in 1995 for a game called Doom 2. But, uh, the things started to heat up when multiplayer games were starting introduced in early 2000. And with them came the multiplayer cheats. So you see when cheating was done in a single player game, uh, other people were not getting affected by that. But, uh, when the cheats were, uh, used in a multiplayer games, that's when real impact is, other user has impacted, uh, in a negative manner. And since the success of a game depends on its large and active user base, uh, the developers can't let go of this. So in early 2000 came the first anti-cheat called Punkbuster, and in 2002 came Valve anti-cheat. So these two initially were very successful, but, uh, they were basically user mode anti-cheats. So hackers found a way using kernel drivers to bypass them and, this is where we are currently today. So these are very popular, uh, kernel anti-cheat who keeps on, which keeps on monitoring your system, your user mode kernel mode space, uh, and prevents hackers from, uh, hacking. So next we are going to cover some basics. So when I started to learn game hacking, I had two choices: I can I can go with internal cheat or I can make an external cheat. So internal cheats are basically DLLs which are injected directly into the game's memory, and since they have direct access to the memory, uh, they have great performance and they offer enough flexibility for making different kind of functionality in in terms of cheats. But on the downside, they are very complex to make because you need to be aware of the game code, in which language it's made and in which engine it used, whether it's Unity Engine or Unreal Engine. Also, internal cheats, uh, are usually preferred for games with, uh, which have weaker anti-cheats. And in terms of external, they are they are separate process and they, uh, manipulate the game's memory externally. And therefore, since they are external, their performance and the flexibility in comparison to internal is low, but it's enough to do basic hacking like wallhacks or aimbot. But on the good side, these are very easy to make in terms of internal, because you don't need to be aware of, uh, the game engine, whether it's made on something. And, uh, and these are very preferred for, uh, games with, uh, stronger anti-cheats. So that's why I went, uh, with external cheats. So what's the methodology of bypassing a kernel level anti-cheat? So, as you can see in this diagram, we have a game, and in kernel we have anti-cheat which is trying to protect it from our user mode. And when we try to read write the game's memory, so first we create the handle to it, and as soon as we create a handle, uh, the anti-cheat will be detecting it, and it will simply block it using object register callback. So, in order to bypass that, we also need to go into the kernel level. So we create the driver and, uh, we load it into inside the kernel and, uh, through that, uh, we are able to bypass this kernel anti-cheat. So, just having a driver inside the kernel, uh, doesn't mean that you won't be detected. If you don't know what you are doing inside the kernel, uh, there is a chance that you can still be detected. So what are the challenges that you will face if you are making a kernel driver? First is how you can create your own driver and how you can load the driver itself. And how you can communicate with the driver from user mode, and after that, uh, how you can make sure that your driver is undetected. So, uh, right now we can move it to kernel cheat development. So I've divided the whole cheat development process in five steps. So if you're able to crack all these, you can probably make any cheat for a game. So first is reversing just like in Pentesting we do reconnaissance for gathering information about the target, here we do reversing for finding the game offsets. Uh, the second is the hooking which is the communication part. So before we develop the driver itself, we need to know how you are going to communicate with the driver. So here we will be using hooking for communicating. Third is creating the driver itself. Uh, the fourth, fourth part is how you will be loading the driver, and fifth is creating the user mode.

[7:29]So, the main point of reverse engineering in game is to find the game offsets. And what are these offsets? I will be telling you in coming slides. So for, uh, reversing, there are usually two ways you can do. Uh, first is using a debugger, uh, for example, Cheat Engine or using a disassembler like IDA or Ghidra. So I prefer to use Cheat Engine because for me it was easy and easy and convenient. Uh, in in disassembling, I have to first, uh, de obfuscate the game's binary because the binary itself have heavily obfuscated. And, uh, for doing that, I have to create my own driver and dump the binary. Also in terms of disassembling, I have to, uh, be well aware of the game engine whether it's made on Unreal or Unity. So all these restrictions weren't in Cheat Engine, so that's why I prefer to use Cheat Engine. So, as I said, the main point of reversing is to find offsets. So what are these? So, offset, as the name suggests itself is how far something with respect to another. So we have here point A and point B, B is 12 kilometers away. So we can say that B offset is 12. So, what why is this important in game hacking? So, uh, let's say we launch our game and it's loaded at this 123 address and, uh, we want to find the health variable address. So we do reverse engineering, we find that it's at 126, and we close the game, we launch it again. And again, if we try to access that same address 123 for finding the variable, uh, we won't be able to do that. The reason is because every time we launch the game, uh, it it will be launched at different addresses. So if I need to find that address, health address again, I need to again first reverse, uh, it itself. So instead of reversing this again and again again, what we will do is find the how far is health address from the game base address. So as you can see in the first, uh, first launch, we'll see that, uh, health variable is three bytes away, and in the second also health variable is three bytes away. So, and and the game address we can find that easily using an Windows API. You just give it the process name, and it will, uh, it will fetch you the game address.

[10:00]So, using offsets, we don't have to reverse engineer the variable which you want to target. And, and if we if we can find the offset, we can simply just add that to the game address itself. So here we can see that, uh, the offset of, uh, health is three. And usually in, uh, these modern games, uh, it's it isn't that easy, like it's not like one pointer for health, usually it's because there are structure and classes. So it's four, five pointers deep. So, reverse engineering takes a lot of time in that. So if you are, uh, lazy guy, if you're lazy like me, you can use these services, uh, which, uh, which, uh, you don't have to reverse the game, and these services have the latest offsets for almost all games. Even if the game is launched tomorrow, it will day after tomorrow, you will find these offsets. So, uh, the next part is the communication part. So before we make the actual driver, uh, we need to first, uh, figure out how we will be communicating with it.

[11:06]Because our driver is not officially signed, it's not an official an official driver. So, we can't actually communicate with that. So, we will be using hooking for finding a communication path to our driver. So, how we'll be doing that is, we basically we will be, uh, hijacking the system call itself. So, since the system call are official and they are inside the kernel, so we can easily call them and use them to pass our instruction to the driver. So, let's say, uh, I want to pass some read instruction, uh, uh, to our driver. So, we will contact our system call, and it and we will say like, hey, can you pass this read instruction to our driver? But the system call will say like, I don't have any functionality to do that. So in hooking we are also providing that functionality. So we will be injecting a shell code, uh, like this, mov rax, uh, the our cheat driver address and jump rax. So, here's an example to let you understand this. So we have, uh, in user mode we have our, uh, we are trying to call the function in our driver. As you can see, we are calling our function with the instruction and, uh, we are unable to. So what we'll do next is we'll find a suitable Windows driver, any official signed driver. So let's say we target DXG kernel, which is a direct X driver.

[12:47]So next thing we'll do is injecting a shell code inside it which will transfer our instruction to our driver. So, as you can see in user mode instead of calling our function which is inside a driver itself, we will be calling the system call and passing them passing it the instruction, uh, which will be passing our instruction to the driver. So, till now we have covered the offsets in reverse engineering. We have seen the communication part, how we will be communicating. So what else our driver needs to do? So, uh, a driver basically needs to do four things. The first it it should be able to find the system call address. So like I showed you here, the anti-open composition, so it should be able to find the address itself and call it. The second it should be able to do the hook part, which is injecting the shell code, the move rax, jump rax. And the third is hook handler. So like we we will be spending sending read read instruction, write. So it should have a logic for that, whether the user mode needs to do read, so it should handle all these instruction. And the fourth is, uh, clearing the traces. So we will be making a lot of noise inside the kernel, so we need to clear those traces as well.

[14:30]So, I have here a video for which demonstrate this hooking part. Actually before that video, let me show you their uh, briefly like uh, the code of the driver. So, just like uh, normal in C++ we have void main for the entry, uh, we have here driver entry. So whenever we launch a driver, it will go here, and here we are calling the function. So, in this function first, as I said, we need to find the address of the system call. So in this example we are targeting the Direct X driver, and this is the system call. And here we are, uh, preparing the shell code instruction. Here we are, uh, injecting our shell code into the system call. And this is the logic for, uh, hook handler for whether the instruction are read or write. So I have here the kernel which I have already made, and, uh, this, uh, this yellow is a KD mapper which you can which will be I'll be sharing in coming slide. Uh, basically you can use this to load any unset driver into into your system. So first we'll open a Windows debugger, we'll do local kernel debugging. So as we are targeting uh, Direct X driver, so first we need to reload it so that we can see the disassembling part of it. Now we can see the disassembly of this.

[16:06]So this is the system call which we are targeting and I wanted you to notice the first two operations here like this is mov and mov. And we will be changing these two mov rax and jmp rax. So we will use the KD mapper for injecting our driver. And if we just refresh by deleting and entering the same character, we can see that our mov rax and jmp rax is being injected. And whenever we will this is the address of our driver which is inside the kernel. Whenever we will call this system call, it will redirect our instruction to the driver. And if we search this address, our driver address, we can see our assembly code of the driver. So, uh, next thing whenever you will be using hooking for your, like if you want to hack in this game, so you need to take care of two things in terms of detection. The first is the hook function, the system call, so like I showed you here, anti-open composition inside Direct X. So you need to make sure that you use a different one because this one if you use it, you'll get banned.

[17:26]So you need to find your own system call, maybe you can find it in this Direct X driver or maybe some other other driver. Also the second thing is you need to change your shell code, like here we are using mov rax jmp rax. And this is also well known by anti-cheat developer, so basically you need to create a new shell code that basically does the same thing, but it it should be something like they don't have a signature of it. So the next thing is loading the driver. So as I told you, our driver is not official, it's not signed by Microsoft, so we can't like simply load this. So one of the ways is using test mode. So Windows has a test mode in which we can debug a driver, we can test our driver. So we can use that to load it, but the thing is anti-cheat doesn't allow you to play games if you are inside a test mode. So this method doesn't work. Second is you can pay Microsoft money to get your signed uh, to get your driver officially signed by them. And, but the thing is if your driver gets revoked uh, detected, uh, or it gets reported, it will be revoked and your money will be wasted. So, uh, the next thing that hackers use is, they exploit a vulnerability in an officially signed drivers, so that you can load your own unofficial driver. So like I showed you in that video, KD mapper. So this is a tool which exploits a vulnerability in an Intel driver. So, and it will be it will be basically manually mapping your non-signed driver. So by manual mapping, I mean like it allocates some memory and throws your driver into that. And it also take cares of, uh, clearing some of these, uh, tables or buckets which anti-cheats usually use to detect whether some driver is being loaded inside the kernel. And for some reason, like if you don't want to use this, there are some other resources which you can use and here you will find some more vulnerable drivers which you can actually use to load your own unofficial driver. And also like if you want to, uh, make sure that this thing doesn't get detected, you can also exploit drivers on your own, so that you can load your own driver. So this is the most easy part for, uh, for the whole process, which is basically creating user mode. So user mode you need to do is call the hook function, prepare the instruction whether you want to read or write, and handle the cheat logic part, which is aimbot and ESP. So, uh, let I have here a video for Wallhack that I made for Apex Legends. So here basically what I've done is, I found the game offset for which enables the glow on enemy. So there is a character in this which is called Bloodhound and it has the ability to reveal enemies. So if we can find that offset, we can continuously set it so that it continuously keeps your enemy visible. So I have already loaded the driver. I'm just running the user mode here, which will set the glow offset. And now we can we will be able to see enemies.

[20:51]So, thank you. So whatever I showed you till now is works for almost all games, but there is one game called Valorant, which is an exception. Because its anti-cheat loads whenever your system boots. So, like we were like we were loading our driver before anti-cheat was running. But in this game anti-cheat was already already running, so we can't load the driver. So I try to research and find ways to load my driver before anti-cheat boots. But I wasn't able to, but still I wanted to hack in this game, so I tried to find some other means. So one of the ways I found was pixel bots, which are basically color-based aim bots. So if you play games like Overwatch, Valorant, they have this feature for, uh, you can use enemy outlines. Like here we can see there is red, violet and yellow. So this is a feature which allows you to, uh, differentiate enemies in the environment. So, turns out we can use this feature to identify the enemies, track those and move our mouse to them so that we can make an aimbot. So, how do these pixel bot work is? They have three things. First, they keep on capturing the screen. Basically, they capture the pixels. Second is, they do, uh, color filtering to find the enemies. And the third thing is moving the mouse to the enemy itself. So, as you can see, we have here Valorant and it's, uh, projecting on the monitor. And the pixel bot is reading the monitor. It's not even in any way contacting Valorant's memory. So it's not even touching that. And that is one of the benefits of using a pixel bot is it's very hard to detect. Because it's not interacting with its memory and also these pixel bots are very easy to make. Uh, like you don't need to reverse engineer, you know, you don't need to make complex driver, uh, and they works on almost all games. And also if your aimbot logic, the code for aimbot is good, it is optimized, it is efficient, these thing actually work, and this is one of the thing which Valorant is currently struggling against. So what are the tools that will be required for this? Uh, these are basically Arduino and USB host shield. So you might be wondering why do we need any external hardware for this? So, like I showed you, we need to do three things. Capturing pixel, we can do with any, uh, screen recording like OBS, or you can use any program related libraries. Finding enemy is simply another logic. Movement mouse also you can do with some drivers or some program related libraries. But the thing here is anti-cheat have problem with with one of these things. It doesn't have problem with capturing pixels because streamers already used it for streaming, you know, they capture the screen. It doesn't have problem with the color filtering, again, it's some logic running. And, but they have problem with movement of mouse. So like, you're not actually moving the mouse, but still some movement mouse command is coming to the Valorant or the system. So they have a problem with that. So, let me show you how these pixel bot evolved to this stage where we have to use external hardware. So initially, uh, let's, uh, I've named this Gen-1 mouse movement in pixel bot. So initially people used to use these, uh, like on the right, we can see these are some libraries in different languages like Python, C++, C#. So people initially started to use this for moving the mouse, but they got, uh, Valorant got to know about this. They simply blocked it. And in Valorant these won't work, but maybe in some other game like Overwatch, some of them will work. So the next game, Gen-2, in which people started using external driver. So one of the very famous driver was interception driver, which is used to simulate keyboard and mouse movement. Again, this got detected and they blocked it. Second is, uh, they used people started using the mouse driver. So like in Razer, Logitech, they have Razer in Razer, we have Synapse, Logitech have G-Hub. So they have macros using which we can move the mouse. So people starting using those API's for using for moving the mouse. Again, these got blocked. And the third, like this is also this Chinese driver is also very famous, uh, which again got blocked. So next game, in using external hardware, like Arduino for moving the mouse. So the good thing about this is all the mouse movement instead of coming from your own system, it's coming from some external hardware. So for Valorant, it's very difficult to know whether these movement are actually from a real mouse or a simulated simulated hardware. So if you notice there is one thing using which Valorant was able to counter this, and it's because if you see we have our system is using two mouse. One is on the like, the real mouse, which is connected to the system, and the second is Arduino itself. So the Valorant sees like why do you need two mouses for playing the game. Like, as you can see, one is our own mouse and second is the Arduino mouse. So it doesn't make sense why you are using it. So again Valorant's blocked second mouse. So if you have two mouses connected to your system, they will block the second mouse to counter this. So, turns out that, uh, they blocked the mouse on the higher level, uh, like on physical level, but they didn't block it on lower level itself like on a virtualized level. So people started using Hyper-V, Hyper-V technology virtualization Windows. So using that they were able to bypass it, but again Valorant got to know and this thing got passed in August 22. So, this is what currently is working for Valorant. So as you can see in in Gen-3 we had two mouses. So here we have one mouse itself. So our mouse will be connected to the Arduino, but in Arduino we don't have any port for USB. So we will be using USB host shield so that we can connect our mouse to it. And if we are able to spoof our Arduino, so this whole thing looks like our mouse itself has some aimbot code inside it. And this is how it will look like if you're able to perfectly spoof your Arduino. So only one mouse is connected. So it's very difficult for Valorant to know whether it's a real mouse or a fake mouse. So the pixel bot code needs to do four things. It capture the pixel. It does the color filtering part. And it it calculates the coordinates like how much far the enemy is to the nearest enemy from your, uh, field of view and it sends the coordinates to the Arduino. So let me show you its, uh, pixelbot code. This is a very basic pixelbot code which I made in Python. These are some of the libraries. And we are using, uh, serial comport for communicating with Arduino. These are, uh, the color filtering part, the HSV value of a suppose our enemy is of have purple outline. So these numbers are for that. And here basically we are finding a way to detect where the enemy is. And we are finding here like how far is it from the cross hair, and here this function we are sending the coordinates. And when we are sending these data to Arduino, we actually can't send any unsigned integer like negative values. So we need to convert them to unsigned integer. So that's why we are doing that, and here we will be sending these coordinates.

[29:26]So, one of the challenges in this is, uh, let's say our enemy is purple and in in the environment of game, there is also some like purple tree, like here we have purple trees. So if enemy is standing in front of it, our aimbot might actually target the tree and not the enemy itself. So for that, we need to do, uh, proper color filtering for that you can use OpenCV. So, as you can see, we have here some purple background. Like it's a character Astra, so we have created the wall of purple and the enemy is also purple. And here using OpenCV, we are able to filter out the enemy. And this is a very basic code using Python, using OpenCV for for filtering, for color filtering. So Arduino codes need to do three things. It takes the coordinate from pixel bot. And it simulates the mouse movement. And it also need to simulate our real mouse movement itself. So I have here the code. These are some of the libraries. And these are global variable which will be used for, uh, our controlling the real mouse. This is the mouse parser class, again for controlling our real mouse. And this is the main function which needs to be in every Arduino code. This only run one time. Here we are declaring all the objects. This loop function, again, this needs to be in every Arduino code. Uh, so this, this whole function will loop every time whenever your Arduino is connected. So this is all logic for the real mouse movement, and this is the logic for, uh, simulating the mouse movement.

[31:29]So, uh, as I showed you in this code, we are using serial comport for communicating. And this is the fastest way to sending the coordinates, but there are other ways also which you can use like web server and wireless transmitters. But why am you telling you this is because Valorant is actually monitoring this serial comport. But that doesn't mean that you can't use it. Basically, you need to make sure that you can't you aren't simply sending your plane coordinates there. You need to like encode those or add some prefix, post fix to that, so that it doesn't seems like a coordinate to them. Also, one of the ways you can make sure it doesn't get detected is spoof your Arduino. So this is a very basic spoofing you can do, like if you go to this, uh, this file, and if you change all these red lines like name of like you can change to a Razer Viper. And the vendor ID product ID, you can get through this URL. And this is a very basic spoofing part. And, uh, I won't tell you whether this is enough for Valorant, that is something you have to experiment on your own. So I have here two videos for Valorant. One simply recorded using OBS. So I'm just playing, uh, pressing left mouse button and it it is automatically targeting to the nearest enemy.

[33:25]So, I have a second video which shows the setup as well. Here I'm simply just holding my mouse and my mouse is connected to the USB host shield, which is connected to Arduino, and which is connected to the PC. So I'm just simply press my mouse. I have to adjust it because it it goes out of field of view.

[34:00]So what Valorant can do in this is recently they made a patch, uh, where they may they they gave the ability to the user so that, uh, they can disable the enemy outlines.

[34:20]So I'm I'm suspecting that in future they might simply just remove these outlines, so so that we won't be able to track those enemies using pixel bot. So, uh, this is a some project which is going on on unknown cheat. So even if Valorant remove these, uh, we can use AI to actually detect these enemies. So like we can give it if you have enough data sets for it, uh, you can provide that, and using AI we can find that enemy. And for moving the mouse, again, we can use Arduino and USB host shield. So this is where you can find the kernel driver code and Arduino code. And these are some of the references which personally helped me in learning game hacking and and for making of this presentation. So this is the conclusion. And we're done. Thank you.

Need another transcript?

Paste any YouTube URL to get a clean transcript in seconds.

Get a Transcript