[AntiCheat] Game Security: Is Obfuscation a Panacea?

@codewiz · July 15, 2013 · 9 min read

The term "obfuscation" is spreading like wildfire throughout the security industry. I'm not sure who first introduced it, but lately, it seems there's an atmosphere in which you can't discuss security without mentioning it, which is truly disheartening. Among the contributing factors are the countless snake oil salesmen out there. It seems to me there's no fundamental difference between those selling remedies to naive grandmothers and those exploiting the pervasive fears across the computer industry.

There are too many snake oil salesmen. Isn't it shameful to offer UPX claiming it's obfuscation?

There are too many snake oil salesmen. Isn't it shameful to offer UPX claiming it's obfuscation?

As always with these charlatans, they have a myopic view. What do I mean? They only see one side of the story. They fail to grasp the issue holistically, focusing only on peripheral parts. Then they equate solving this minor part with resolving the entire problem. Ultimately, they come claiming they have a cure-all solution for a complex issue. But, as you well know in security, there is no such thing as perfection. Hence, there's no universal remedy either. If someone comes to you claiming it blocks everything, it is perfect, it is the ultimate solution that can fend off all threats – you should be skeptical.

#0

Obfuscation techniques largely rely on polymorphic and metamorphic tactics. The differences between these two techniques are detailed in the article below. To truly understand the reality of obfuscation, it's essential for you to grasp the distinctions between these two methods.

Mutation has long been a topic of interest for virus creators. They have studied ways to modify various aspects of viruses to evade antivirus programs. They've changed names and altered strings used internally. More recently, to avoid detection, virus writers are employing techniques to change the actual code of the virus. Mutation is both the most fundamental and potent technique in virus development, existing from the inception of viruses to the present day. This 'mutation' technique, developed in secrecy, is now being utilized under the label of 'obfuscation' to protect legitimate programs, not just viruses, which reminds us that extremes do meet.

When describing program transformation techniques, the terms 'metamorphic' and 'polymorphic' are commonly mentioned. Both include the root 'morphic', indicating they transform the original program into new 'variants'. The resemblance of the terms often leads to ambiguity in their use. Let's briefly examine the difference between the two.

The fundamental difference between these two transformation techniques lies in the original recoverability. If we define the transformation function as M, the original binary as S, and the transformed binary as D, we have a relationship D = M(S). Here, both metamorphic and polymorphic techniques are the same. However, the difference lies in the generated D. If there exists an inverse function M-1 that allows tracing back from the transformed D to the original S, then transformation function M is called polymorphic; if not, it’s metamorphic. This implies that if you can recover the original from the transformed binary, it's polymorphic; if it's impossible, then it's metamorphic. From this, we can see that metamorphic is a higher level of transformation technique.

– The core of metamorphic engines, the principle of code exchange, Shin Youngjin

As stated in the article, metamorphic is a higher level of transformation. However, most of what's sold as obfuscation solutions are based on polymorphic mechanisms. In reality, there's little difference from UPX; it's a packer. The original code becomes visible in memory. Of course, there are plenty of even more rudimentary programs that simply hide symbols and market them as obfuscation solutions.

On the other hand, true metamorphic solutions are a challenge for hackers who think they can crack the code by tracking down a few arrays. Yet, among the obfuscation solutions released for PC platforms, few are truly based on metamorphic technology. They might label their products as metamorphic, but often that isn't the case. Surely, there's a deeper story behind this, which we’ll explore later on.

#1

Understanding history is essential since knowing the past helps us predict the future. In the PC-based platform's realm, the technique of obfuscation was researched among virus creators but later was adopted by regular programs, primarily to combat cracking. Cracking typically involves reversing the executable file to alter key codes and running it. Obfuscation was introduced to make static analysis of executable files more challenging. Sounds familiar to the current situation in other fields, right?

So, what happened? Did cracks disappear with the introduction of basic obfuscation? Far from it. It turned out to be a piece of cake. Crackers quickly found a way. They realized you could achieve the same result by applying patches directly to code in memory, given that previous-generation obfuscation techniques, based on the polymorphic mechanism, revealed the original code in memory. This sets the stage for what's to come: arrays, referred to as "arrays," will circulate. With access to just a few such arrays, even elementary school students in Busan can start cracking.

As obfuscation became futile against memory patching, individuals in the security industry diverged into three groups. The first one further researched obfuscation, reaching the level of metamorphic transformation, which rendered the original code unrecognizable and variably altered with each execution, complicating the hacker's job to patch. The second approach involved static checks, embedding code that verifies any alterations in the memory code. Lastly, some adopted dynamic defense mechanisms, known as memory security. This involves patching the operating system to prevent illegal manipulation or debugging of the program's memory.

Who came out on top? Naturally, there's no ultimate answer and no superior method. A judicious mix of all methods is ideally required. But since today we focus on obfuscation, let's look more closely at those who pivoted to metamorphism.

#2

How did those who switched to metamorphic techniques fare? Did hackers fail to decode their programs as they had hoped? Unfortunately not. They encountered a colossal hurdle even before hackers could attack—they faced the Halting Problem, which Turing proved unsolvable in 1936. The Halting Problem briefly implies that it's impossible to write a program that determines whether another program, given any input, will halt or compute indefinitely.

The halting problem in computational complexity theory is a type of decision problem summarized as follows:

Given a description of a program and an initial input, determine whether the program, when given this input, will finish computation and stop or continue computing indefinitely.

Alan Turing proved in 1936 that a general algorithm to solve the halting problem for all possible inputs does not exist. Hence, “the halting problem is undecidable on a Turing machine.”

http://ko.wikipedia.org/wiki/%EC%A0%95%EC%A7%80_%EB%AC%B8%EC%A0%9C

You might wonder how this relates to metamorphic. The challenge is the multitude of metamorphic 'faces'—every execution results in completely unpredictable rearrangements and restructurings of the code. It is impossible to ensure that every variant functions correctly. Should a metamorphic program stall on a customer's PC, it is not at all surprising, since nobody verified that particular variant. By its very nature, it's impossible to validate the safety of a metamorphic engine.

JIT compilation might come to mind as a counterargument, but it's entirely different from metamorphism. JIT only produces various compile results for different CPU types, not new code for the same CPU on each run. Ultimately, even the most advanced metamorphic engine cannot have its stability verified by anyone, as Turing proved.

But that's not the only problem. Another issue is that with so many 'faces', the program can't determine whether it is altered or original. Since metamorphic code varies in every execution, a true metamorphic engine cannot predict its transformations. Therefore, it's impossible to discern if the currently running code is the authentic one or if it has been tampered with by a hacker. It is a paradox—a program shielded by the most advanced metamorphic engine potentially becomes unable to detect the slightest code modification. Imagine a woman so obsessed with plastic surgery that she forgets her original face; the situation is somewhat similar.

#3

The advent of HTML5 has ushered in an era where JavaScript can now create games like Doom. However, as well known, JavaScript is downloaded directly to the browser with the source code exposed. For games, this is a nightmare as their core codes lie exposed. Thus far, browser games have been limited to those with server-side processes capable of all calculations, minimizing client-side computations to avoid easy hacking.

How do I protect my content from pirates?

The “modern” open-source-based answer is, of course, that you shouldn’t: instead, you should design your application or business model in such a way that value lies in the service you offer, not in the content delivered to the browser. However, that may be overly idealistic in some scenarios. Under those circumstances, your best option is to look into JavaScript obfuscators.

http://learningwebgl.com/cookbook/index.php/WebGL:_Frequently_Asked_Questions#How_do_I_protect_my_content_from_pirates.3F

This excerpt from the WebGL FAQ page highlights a question about content protection, with the ironic answer of relying on obfuscation as the practical approach. This scene shows why obfuscation is prevalently brought up recently. While tools to facilitate faster and easier development have vastly improved productivity, they have simultaneously carved a path for hackers to reverse their output more conveniently. Even though obfuscation can revert JavaScript to its pre-obfuscated state, and yes, variable and function names become harder to read, hackers are skilled enough to treat assembly code as if reading C code. Thinking that muddled strings deter decoding is overly naïve.

So what's to be done? Yes, that's right. We must engage in the absurd task of taking something designed for easy understanding and rendering it incomprehensible again. A new interpretive layer must be constructed atop JavaScript. Naturally, this interpreter must decipher code that hackers find difficult to comprehend—essentially, a VM-like structure arises. This interpreter, then, becomes harder for hackers to grasp, on par or potentially even more challenging to analyze depending on its complexity. And the code system running on JavaScript should require the interpreter to function.

You might wonder what I'm getting at or deem it untenable. Well, it seems we're due for a showcase. Prepare for a laugh when you see the masterpiece by Fabrice Bellard, the cosmic genius of France's computer science scene. Let's aspire to create solutions of that caliber before peddling any 'medicine'.

Welcome, you've never seen a solution like this before.<br><br>Do not entrust your security to a one-eyed salesman. Instead, engage someone well-versed in adeptly mixing a variety of strategies.

Welcome, you've never seen a solution like this before.

Do not entrust your security to a one-eyed salesman. Instead, engage someone well-versed in adeptly mixing a variety of strategies.

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