This blog post is about VAC signature detection. NOTHING else. A lot of people are having panic attacks about other technical features that this does not cover. Also, Assualt Cube is used as a demonstration with VAMemory which was the memory c# class used while doing CS:GO research. My reason for posting is why easy, old and simple memory modification cheats using known memory modifications DLLs are not being detected after months of use. I have not and will not reverse Warden, VAC or care about other anti-cheat technics being used in them. I simply don’t care and it’s out of scope for this post.

TL;DR The Counter-Strike [VAC] anti-cheat engine is signature based (among common other things) and people selling cheats know this. They could flood the community with so many different signatures that Valve could never keep up with detection. They need to evolve by either monitoring kernel system calls, hooking ReadProcessMemory/WriteProcessMemory or preventing processes from attaching to their games or ASLR. (Address space layout randomization) One last thing before we get started. Stop calling people who download or buy cheats “hackers”. The correct term is “script kiddie”. Now, if the person using said cheats wrote them then the term “hacker” is acceptable. Nonetheless, in the case of VAC, it never is acceptable because it’s too easy and you’ll learn why by reading more :P

For those of you who don’t know what Counter-Strike is, it’s a very popular online FPS (first-person shooter) by Valve software. So popular that yearly completions are held and prize money in the millions is awarded to the victors. But guess what? It’s totally and hilariously fucking broken.

Now, most players of the game are not skilled enough to join these professional teams or obtain the “Global Elite” rank. Counter-Strike like chess uses the Glicko-2 rating system (https://en.wikipedia.org/wiki/Glicko_rating_system). A player’s Glicko-2 score then correlates to a Counter-Strike rank (see image below).

Again, like with Chess, the fun part of Counter-Strike is playing against people from all over the world and continuing to climb and better your Glicko-2 rating. It’s a competition-driven game where practice, skill, and teamwork pay off. I’m not a psychologist but cheating in games like Counter-Strike, Chess and others are likely… well. w/e just watch this. https://www.youtube.com/watch?v=CwzL61SpTM4

A few weeks ago I decided to sit down and research wall-hacks for counter-strike. Wall-hacks allow a player to see everyone through any wall in the game. It’s one of the most common and popular cheats people use daily in Counter-Strike.

My experiment mostly started as a fun way to learn c# but quickly turned into a fascination with how incredibly awful and amateur the Valve anti-cheat engine is (VAC). It’s important to note that getting a VAC ban is permanent and every game you have purchased using VAC via Steam (http://store.steampowered.com/) will also be permanently banned from online play.

Now, I may be biased because my entire career has focused on computer security but I would put VAC, in regards to its effectiveness, right next to Norton Anti-Virus from the early 90’s. It’s a signature, community report, cat and mouse design (among other things). https://en.wikipedia.org/wiki/Valve_Anti-Cheat#Design

All of the lessons learned from malware detection tools over the last few decades seems to have been ignored by Valve. Now, to be fair they build games, not detection systems but like Windows/Defender users don’t care and will expect them to solve it. Blizzard Entertainment is a great example of this and their Warden Client (https://en.wikipedia.org/wiki/Blizzard_Entertainment#Technology) which is incredibly advanced compared to VAC.

Basically, take the oldest cheat source code you can find for Counter-Strike that has been “detected” for years and pack (https://github.com/yck1509/ConfuserEx) it and it’s now undetectable. Done. You just defeated Valve’s amazing anti-cheat engine.

The fun part is that the Counter-Strike “private” cheap market is huge. A lot of people sell their cheats for monthly subscription fees ranging from $20.00 USD to $45.00 USD. The authors are well aware that they could pack each binary uniquely at download but how do you continue a subscription model when everyone’s cheats are undetectable with different signatures. The authors want the cheats to be detected and even offer discounts and/or reimbursements for purchasing Counter-Strike if/when you do get VAC banned. The game’s price as fallen to a point that having to repurchase it is not really a deterrent. One possible thing Valve could do to prevent this is to track credit card usage and also ban credit cards from accounts that have a history of cheating.

Well, as it turns out, incredibly easy. Unfortunately, due to the terms of service and past lawsuits in this area, I’m not going to post source code or explain how to reverse engineer the static addresses for game manipulation for Counter-Strike. However, I will for an open source game called Assault Cube. You can download Assault Cube for free at http://assault.cubers.net/

If you’re not familiar with how computer memory works this may be a little extreme, but I’ll try to keep it high level. To make this easier we will be using a program called Cheat Engine (http://www.cheatengine.org/).

Once you have Assault Cube and Cheat Engine installed, open Assault Cube and create a single player game with no bots. I like to use the ac_aqueous map because you spawn next to grenades that make it easier to damage yourself so you can track your health change.

Now we can open the Cheat Engine application and attach to the Assault Cube process (click the computer icon at the top left of the application under the menu). You will see a lot of processes but just keep scrolling until you see “ac_client.exe”.

Click “Open” and we can now search for values in memory for this process. This is where things get interesting because we can simply search for the health value and return all address in memory that holds this value. Go ahead and type 100 to the “Value:” search box at the top of the right sidebar. You should see something like this:

What you see on the screen now hold memory address that leads to a value of 100 running in memory for Assault Cube. One of these addresses is the place in memory that holds our player’s health count. Now, this list is huge, so like I said before we are going to hurt ourselves to get the list to change. By doing this we are filtering the list so it will become smaller and smaller so it’s easier to work with. Pick up some grenades and throw them next to you so we can lower our health. Be sure to now get too close because if you die you will need to start the whole process over.

It’s important to note that the green address signifies static addresses. So, in the case the value you want to change is green, you have way less work to do because you can use that address directly to change values.

After damaging myself with the grenade, my health is now 54. So, going back to the Cheat Engine application I will now enter 54 as the value and search again.

With any luck, your screen will look like mine and only have two address. Now, neither of these address are green, so they are dynamic – which means we can modify the game’s health as it’s running, but this address won’t be the same next time you start the game. It’s easy to trace a pointer for its static location and apply offsets using Cheat Engine, but we will save that for another time.

Right click both of the addresses (or as many as you have) and they will be added to the Memory View section of the application as seen below.

Now, by double clicking the value of one of the rows in the memory view section, a window will open that allows you to change the value in memory for this address. Select the first one and change the value to 1000000.

Now if you go back to Assault Cube, with any luck your health should be 1000000. Pretty easy, right? This concept can also be applied to armor and ammunition.

It’s important to note that changing values like this for online multiplayer games is fruitless. The server you connect to will store state so every time your client changes your health, the server will sync back its last recorded value. However, this is very effective for single-player games.

The blow code is a hack for Assault Cube to keep your ammo and health at 10000 at all times. Remember this won’t work for online play but will for single player mode. The below code uses the VAMemory class to make the process of reading and writing to memory easier.

So now that we have our cheat put together, let’s make it unique, compressed and obfuscated (among other things i.e preventing attachment). ConfuserEx (https://github.com/yck1509/ConfuserEx) is a great little open source packer that supports:

Now that Counter-Strike is cross-platform I’m sure this adds a lot of other issues into the mix. In Windows, you can only attach to a process once. A lot of malware authors will attach to themselves to prevent detection tools from debugging. My best guess to why they don’t do this is for debugging and crash reporting. This could also cause issues with Address space layout randomization, PIE and other methods when debugging remotely or sending crash reports. (Speculation but I’m guessing there is some reason they don’t use it.)