[AntiCheat] Game Security: About Hardening...

@codewiz · November 21, 2013 · 8 min read

I thought articles like this on the internet were someone else's problem…

I thought articles like this on the internet were someone else's problem…

I woke up one morning and something felt off. I tried to speak but no sound came out—a bizarre phenomenon. It wasn't rare to feel a bit of pain when swallowing, but to completely lose my voice was unprecedented and took me by surprise. I assumed it would pass soon, but it lingered longer than expected. When Larry Page secluded himself after losing his voice, I considered it as just a distant story. However, facing the ordeal myself, I realized it's no ordinary matter. I never thought of speaking as anything special, but without my voice, everyday life felt nearly impossible. From A to Z, nothing was doable. Complete mental breakdown ㅠㅜ~

#0

The start of all this chaos came from a peculiar hacking tool. It revealed itself last week. A hacking tool for a game with our security product applied popped up on a site known for hosting numerous hacking tools. I had always wondered why other companies didn't stop such hacking tools—it seemed all too easy to block them using patterns since the files were so readily available. I even thought these sites might be in some neglect due to the sheer number of them.

As usual, I attempted pattern blocking first, but the aftermath was appalling. The hacking tool returned in a completely different form within just two hours. That's when the truth hit me. Other companies weren't ignoring the issue; they were unable to block it. We patched it again. Another two hours passed. Another patch. Yet another two hours. By then, I realized this thing wasn't going down without a fight.

The hacking tool's diligent updates. Tiring for you too, isn't it? Having a hard time? ㅋㅋㅋ

The hacking tool's diligent updates. Tiring for you too, isn't it? Having a hard time? ㅋㅋㅋ

Since then, the development team engaged in continuous analysis, fiery coding, all-nighters, and the support team had to deal with daily updates. Thankfully, the client was also committed to eliminating the hacking tool and was very cooperative with our updates. After more than a week of effort, we've seen considerable success. Today marks the 10th day since we began, and we have already performed seven updates. Essentially, we've been updating almost every day, excluding the weekends.

#1

The person who contributed significantly to blocking this hacking tool was the rookie on the team. During our 2-hour tug-of-war with the hacking tool, the rookie—well-versed in immune system theories—suggested a new strategy inspired by how our bodies fight HIV. I've always believed we should seek answers in living systems, so I listened closely, and the strategy was better than expected. We implemented the rookie's idea immediately. The concept was simple enough to program by the next day and apply in the patch.

Both the rookie and I were hopeful. I wished for at least 6 hours of resistance, but we lasted 10 hours that day. The real jackpot wasn’t the duration, though—it was the error caused by the hacker, likely fatigued by our relentless patching, who mistakenly exposed one of their key modules in raw form. The rookie made the discovery. Even though I was occupied with other tasks and hadn’t analyzed the module yet, the rookie had decrypted most of its critical functions and informed me. We sat down together to dissect what the rookie hadn’t already done, and after an all-nighter, we exposed all of the hacker's tactics. While there were some novel techniques, the hacker was ultimately a stereotype: good at reversing but poor at coding.

"Know the enemy and know yourself; in a hundred battles, you will never be defeated," they say. We restructured our whole system to evade the techniques we identified, a task more challenging than anticipated. And over that weekend, we unleashed one of the most powerful features of XIGNCODE3—it had been four years in the making. Neo, who reached this point, was the second hacker to do so. We deployed the patch on the 14th. The hacker still seems lost in what might be the 47.5th dimension.

#2

The hacker's main attack strategy is code tampering—altering our code to disrupt its normal functionalities. Such operations usually hinge on how many target addresses can be patched at once. Since we've suffered such attacks over the years, there's a considerable number of wires to cut to disarm the bombs. But the adept hacker managed to find and sever all those wires. You might as well think of parts operating VM code or CRC checks being wholly and easily patched together like a set menu. Until we analyzed the exposed module, it felt like we were stark naked in combat with the hacker—their reverse-engineering skills were that formidable. To block these skills, we brainstormed various hardening strategies. Here are about ten of them:

  1. Only load the code when it’s needed. Most programs load all necessary code at startup, which poses a problem as it allows for capturing all patch targets simultaneously. Essential code should only exist when absolutely necessary.

  1. Code should be able to reset at any time. Our bodies' cells renew daily, even bones regenerate completely over a decade. Similarly, all components should be ready to restart at a moment's notice to invalidate continuous patching.

  1. Code should perform different operations while appearing the same to the hacker. Like cells that differentiate into different organs such as eyes, nose, ears, and mouth, the codes should appear identical but behave differently in actuality.

  1. Code should be able to detect tampering. Isolating CRC check codes or similar processes is futile. They need to be as integral to the code's routine as possible.

  1. A lax random seed can be effective. Despite people championing high entropy, making hackers believe that something does not change and then suddenly does can be far more effective.

  1. Utilize thread boundaries, exception boundaries, IPC boundaries, and OS callback boundaries. Code typically proceeds in a serialized order, making tracing and analysis easy. These mechanisms help break that flow.

  1. It’s problematic if all code concentrates in a specific memory area. Spread it out to slow down scans and make detection harder.

  1. More effective than making reversing difficult is making programming difficult even after analysis. Designs based on evasion are more effective than those based on detection.

  1. The further apart detection and reporting are, the more effective they are. If they are close, the routine is useless.

  1. Avoid global pointer variables. Data must be hidden very discreetly. Global variables are like handing a fish to a cat. Data storage needs to be as secretive and widespread as code.

#3

Working in practice, it's easy to let theoretical knowledge lapse. The strategies we considered above are based on experiential reasoning rather than mathematically sound methods for countering code manipulation. As you might know, the most effective protection derives from mathematical principles that remain challenging to attack even with full knowledge of the code. During this fight, I became interested in techniques like anti-tampering and tamper-proofing. I found a significant book published in 2009, "Surreptitious Software," which focuses exclusively on prevention of tampering and leans towards the theoretical side.

This year's honey pot: Surreptitious Software

This year's honey pot: Surreptitious Software

I was thrilled to find a brief mention of Arxan in the middle of the book. I discovered several algorithms with a mathematical foundation that, like most mathematically based codes, look simple but are nightmarish for hackers. For those curious about the algorithms, it’d be best to buy and read the book—the space here isn’t sufficient to cover them all. Needless to say, if you're working in an area where code security is crucial, this book is worth every penny, even a million won. Too cheap, you say? ㅋ~

Building a company out of a single algorithm. Good to see you, Arxan

Building a company out of a single algorithm. Good to see you, Arxan

It looks serious, but it's essentially saying "I'll check everywhere"<br><br>Sometimes, presentation matters too ㅋㅋㅋ~

It looks serious, but it's essentially saying "I'll check everywhere"

Sometimes, presentation matters too ㅋㅋㅋ~

#4

Like all security codes, ours is increasingly filled with meta code—those that function as macros, inserting dummy codes, transforming code structures, performing CRC checks, and more. As meta code proliferates, the readability of the original code declines and bugs hide even more effectively. I'm currently contemplating methods other than macros to achieve this, potentially with code weaving techniques. It seems challenging to apply these techniques during compile-time or to compiled results of lower-level languages like C/C++. Is manual labor the answer? ㅠㅜ~

#5

Thanks to that hacker, we've been able to add many more robust features. Though grateful, it's time for us to part ways. It seems like you’re deep in debugging—don't you think you should consider the Return on Effort (ROE)? I guarantee that debugging other games would be much more straightforward for you. So now, goodbye, zaijian, and sayonara ㅋㅋㅋ~

It's rare for an anti-cheat solution to hear such words from a hacker. ㅋ~<br><br>I'll fight with all my might because I know the feeling~

It's rare for an anti-cheat solution to hear such words from a hacker. ㅋ~

I'll fight with all my might because I know the feeling~

We will always strive to provide a more delightful gaming experience.

We will always strive to provide a more delightful gaming experience.

@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일째 운영 중