[AntiCheat] Game Security: Misconceptions About Coupling

@codewiz · April 24, 2012 · 9 min read

One common occurrence during game company meetings is misconceptions about coupling.

No, we're not talking about rings! We're discussing the coupling of security code with the game, which is often a topic of discussion.

In software engineering, the term "coupling" is used as a measure of the degree of dependence or association between modules. Low coupling is referred to as loose coupling, while high coupling signifies strong coupling. So, what's preferable in this context? Naturally, in software engineering, low coupling is the goal. High coupling means less modularization, making it harder to make changes, more prone to errors during modifications, and difficult to maintain. So, it's generally considered something to be avoided.

However, these days, there's an argument being made in various contexts that suggests that a high level of coupling between game security products and games may be inevitable. So, let's organize our thoughts by looking at some examples and ponder whether the claim that higher coupling leads to better detection of hacking tools holds true.

#0

Sometime in the past, it became commonplace for game security companies to integrate game security code into the game servers. In the early days of developing our product called XIGNCODE, many game server developers had strong reservations about integrating code on the server side. However, nowadays, most consider it a standard practice, and it's heartening to see this shift in mindset. Things have certainly changed. Along with this practice came one peculiar tradition: uploading client hash data to the server every time a client is built. This feature was developed with the goal of comparing the server and client, with the intention of disconnecting if they don't match, representing a form of very strong coupling.

In this scenario, the potential for mistakes is quite significant. There are often opportunities for human error, such as administrators forgetting to upload hash data on the server side or cases where a different client gets patched than the one with the uploaded hash data. But even if we set aside human error, the main reason why this method isn't particularly good is that it's unnecessary in most games. It's akin to maintaining the main entrance when all the thieves are jumping in through the windows. People might ask, "Does that mean you don't need to protect the main entrance?" In the real world, resources are always limited. So, it's wiser to allocate resources to protect other vulnerable areas instead of focusing on guarding the main entrance.

So, what should the code integrated into the game server actually do? It should ensure execution, above all else. Game security products are provided as external libraries, and if their interfaces are exposed, they can be bypassed effortlessly. This is done to verify such cases. In other words, even if everything is removed, circumvented, or altered, there should be at least one thing that can be guaranteed to execute. That's precisely the role the code applied to the server should fulfill. Once execution is ensured, it becomes possible to find the altered sections at any time. However, if execution is not guaranteed, putting code to find the altered sections will be ineffective. After all, the code tasked with finding the altered sections will also be altered.

Furthermore, the notion of making changes itself is quite outdated. The current trend is non-modification. It involves achieving the same effect as making changes without actually altering anything. This is because hackers have also caught on. Making changes is too easily detectable nowadays.

#1

Auto, macro programs, and hacks that enable the unlimited use of specific techniques within games are often implemented by illicitly invoking specific game functions. For instance, in a racing game, you might consider the function responsible for boosting acceleration. External hacking tools continually and unlawfully call such functions, giving rise to hacks like the infinite booster hack. With the prevalence of this technique among game developers these days, one common question that arises is whether security programs provide the capability to protect specific functions. The idea is to let game developers pass on the addresses of functions they consider risky to prevent illegal invocations.

Is this an effective strategy, though? To be honest, it's virtually useless. It primarily serves to increase in-game lag.

Firstly, the return address check method is easily neutralized by a technique called "return address morphing." To defend against such methods, you would need to trace the code, but deep runtime checks like this add significant overhead. Consequently, checks can only be conducted within a certain range. So, if we're tracing N depth, and the adversary employs N+1 depth, they can easily bypass it. It's worth noting that security products that recognize and inspect N depth are quite scarce. It's an unfortunate reality.

What's even more disheartening is that such checks rely on a hooking mechanism, and from the creator's perspective, even invoking a function beyond that hooking point is relatively easy. Of course, you can attempt to defend against this by conducting dynamic code analysis and placing traps in ambiguous locations, but this only weakens the software's robustness and isn't significantly effective.

The truly frustrating fact is that if you block a specific function address, hackers will find another one. Without a doubt. So, it's not effective. Even if you manage to find the function again at a speed matching or surpassing the hacker, it won't make a difference. It merely creates a cycle of competition. Beyond mutual patching, there's hardly any progress to be made.

We applied this technique several times to paid hacking tools in China, but it didn't provide much amusement. Why didn't it? Well, it took us a whole week just to locate that function. So, we thought blocking it would put an end to it once and for all. However, after we blocked it, they started invoking a different function within a day. Instead of spending another week analyzing, we concluded that this approach was futile. We chose a different method, and that hacking tool went into eternal slumber as of March 2nd. 😄 This case further reinforced my belief that many methods from the textbooks are far less useful in real-world scenarios than one might think.

The ill-fated hacking tool that met its end on March 2nd due to XINGCODE.

The ill-fated hacking tool that met its end on March 2nd due to XINGCODE.

The reason we don't recommend high-coupling interfaces to game developers is as follows. Firstly, it's because we believe game developers shouldn't have to study to create security products. Would you buy a car that you can't even start because you don't understand the engine's structure? Personally, I wouldn't go for something like that. Another reason is that these techniques, if not used carefully or understood in terms of their internal workings, can increase in-game lag and offer no real help in blocking hacking tools. Ultimately, the high coupling that may be seen as fun, even at the cost of tolerating the bleeding, doesn't provide any real value.

Of course, as you probably know, there are many places where you can use techniques like this in ways you might not be aware of. Naturally, I won't disclose such places here. I'll share them in the textbooks when they become common knowledge, just as if I had discovered them for the first time. 😄

#2

Lastly, let's take a look at something currently one of the hottest topics - DirectX interface addresses. To check for DirectX virtual function hooking, it seems like receiving the pointer of this interface is the backbone of this high-coupling method. Unfortunately, even this doesn't hold much significance. First of all, you can obtain the address without receiving it, and there's one way to block it only if you do receive it, but that method is hardly used in practice due to speed reasons. Moreover, even if it is used, it can still be detected through other routes.

I'd like to ask companies that have tried this method whether they had any fun, almost like Fermi's paradox in reverse. Did teaching you the DirectX interface addresses you were asking for bring any enjoyment? Most likely, it didn't. Hacking techniques that manipulate interfaces are rather old-fashioned, except for cases like the one I mentioned earlier, where you spend a week learning Visual C++, download the DirectX Hook Toolkit from the game community, and code along with a monthly hack sample. It's quite an old-fashioned technique. Nowadays, even professional hackers hardly use such methods. Of course, if there are hackers who use them, they would probably be considered B-class hackers. And solutions that can block what these B-class hackers manipulate can do so without receiving the interface in the first place. Isn't that why you spend a lot of money to buy and use such solutions? 😄

#3

Why do we use game security products? It's probably to block hacking tools, right? However, recently, during meetings with some game companies, I've noticed that they seem to be using security products not for their intended purpose of blocking hacking tools but rather for consulting with these products. And not just any consulting, but often it's misguided security consulting. Every time I come across this, it really leaves me feeling uncomfortable.

There are thousands of ways to block hacking tools. In my opinion, the ultimate solution is one where neither the game developer nor the operator needs to be concerned at all. The intermediate solution involves the game developer providing information in some way, and the lowest solution is reporting game updates to the security company. Whenever possible, work with companies that opt for the ultimate solution. It benefits both you and the security company's mental well-being. Of course, we also have had experiences in the past where we heavily leaned on the lowest solution while proclaiming, "I am security." The result? A mutual state of confusion. That's when I realized, "Unless it's a situation where there's absolutely no other choice, we should never rely heavily on the lowest solution."

Remember once again. The solution you're using is for blocking hacking tools, not for finding and listing security flaws in the game. Furthermore, it's not a solution for writing hacking tool analysis reports that look plausible or for listing patents. Just choose a solution that will automatically and effectively block those pesky hacking tools. Then you won't need to worry about finding game security flaws, writing hacking tool analysis reports, or listing patents. That's right. As long as you hold the cards, you're the one in control. Now is the time to reclaim your position of power. 😄

Do you know that 'right now' can be omitted? 😄

Do you know that 'right now' can be omitted? 😄

@codewiz
Looking back, there were good days and bad days. I record all of my little everyday experiences and learnings here. Everything written here is from my personal perspective and opinion, and it has absolutely nothing to do with the organization I am a part of.
(C) 2001 YoungJin Shin, 0일째 운영 중