1. Overview of Reverse Engineering
Reverse engineering refers to deconstructing and analyzing a product or system in reverse to effectively understand its design, structure, functionality, and underlying principles. Originally applied in machinery manufacturing for analyzing hardware mechanics, reverse engineering has expanded into software with the development of information technology. In game security analysis, it serves dual purposes: for legitimate uses like developing compatible software, and for malicious uses, such as in the illicit industry of cheat development. In the creation of game cheats, hackers perform reverse engineering on compiled binary files to study the operational mechanics and underlying code logic. Subsequently, they can identify vulnerabilities and write custom cheats for profit.
In game security, reverse engineering has become a critical technique in cheat writing. Two primary analysis methods are commonly employed in this process:
Type 1 - Static Analysis: This method involves analyzing the game's code without running the game, by studying the binary files within the installer package to extract key information, such as variables, functions, and control structures, thereby enabling a deeper understanding of the code logic.
Type 2 - Dynamic Analysis: For games that incorporate anti-static analysis techniques into their core logic, static analysis alone can be difficult. This is where dynamic debugging comes in. By monitoring the memory and function calls during runtime, analysts can capture memory snapshots and call stacks, allowing them to analyze real-time data flow to identify exploitable vulnerabilities.
Since static analysis forms the foundation of reverse engineering, this article will focus on its technical principles and practical applications. Advanced techniques related to dynamic analysis will be explored in depth in future works.
2. Mono vs. IL2CPP Mode
To understand the principles of static reverse engineering, let's first look at the standard compilation workflow. For Unity-based Android games, there are two primary runtime architectures: Mono and IL2CPP.
In Mono mode, Unity compiles C# code into cross-platform Intermediate Language (IL). The IL bytecode is packaged into the Assembly-CSharp.dll file. At runtime, the Mono virtual machine (VM) performs Just-In-Time (JIT) compilation, converting the IL bytecode into the target platform's machine code for execution. The workflow is illustrated as follows:
During compilation, C# code is transcompiled by Unity's internal compiler. In the first step, the compiler parses scripts for syntactic and semantic analysis, generating standard IL bytecode. This bytecode retains complete class structures, method implementations, and metadata. Subsequently, Unity packages these into a standard .NET assembly, generating the Assembly-CSharp.dll file.
When unpacking an APK, this Assembly-CSharp.dll file can be obtained directly. If it hasn't been obfuscated or encrypted, it can be reverse-engineered using common tools to obtain near-original C# source code. Since this Assembly-CSharp.dll centrally stores the game's core scripting logic, reverse engineering it allows us to reconstruct object behaviors, core algorithm implementations, and critical data structure definitions.
Unlike Mono's JIT compilation, IL2CPP employs a more advanced static compilation architecture. The core of this architecture is to transcompile IL bytecode into standard C++ code, which is then compiled into highly optimized native machine code using a platform-specific compiler (e.g., Android NDK). This results in an executable file, libil2cpp.so, and a metadata file, global-metadata.dat. This prepared statement not only allows the game to execute optimized machine code—yielding a 1.5x to 2x performance boost over Mono—but more importantly, significantly raises the difficulty of reverse engineering by stripping symbolic information such as class and function names. The workflow is as follows:
When unpacking an APK, the libil2cpp.so file can be obtained, which stores the game's core logic. However, since most semantic metadata (e.g., class/function names) is bypassed during the IL-to-C++ transcompilation, Unity generates the global-metadata.dat file to store metadata symbols. During static analysis, analysts must first recover function symbols from this global-metadata.dat file before proceeding.
Compared to Mono, IL2CPP offers substantial advantages in code protection and reverse engineering costs. At present, most commercial games with high performance or security requirements use the IL2CPP model. When combined with ACE Anti-Cheat, IL2CPP establishes a comprehensive security system spanning code obfuscation, memory protection, and real-time behavior monitoring to effectively mitigate cheat threats.
3. Applications of Static Analysis in Cheat Development
The choice of static analysis tools varies significantly depending on different compilation modes. For Mono games, the Assembly-CSharp.dll file retains the complete IL bytecode. Analysts can easily reverse-engineer it into high-level C# pseudocode that is nearly identical to the original source using tools such as ILSpy or dnSpy.
By comparing the decompiled output from ILSpy with the original Unity project's source code, it is shown that reverse-engineered code structures under Mono almost perfectly mirror the source code, making game logic exceptionally vulnerable to reverse engineering.
In contrast, IL2CPP games use AOT compilation, during which most symbolic information is bypassed from the libil2cpp.so file. This forces analysts to use tools like Il2CppDumper to parse the type system embedded in the global-metadata.dat file and map it to the machine code offset addresses in libil2cpp.so. Only then can they use professional tools like IDA Pro to restore the key game logic.
In contrast, IL2CPP employs a completely different protection mechanism. With AOT compilation, game logic is compiled into native machine code and stored in the libil2cpp.so file. During this process, most symbolic information is intentionally bypassed. As a result, analysts must combine tools like Il2CppDumper to parse the type system from the global-metadata.dat file and map it back to machine code offset addresses within libil2cpp.so.
This process generates a dump.cs file containing the method addresses from the source code, which provides critical reference points for analyzing the machine code with tools like IDA Pro. This dual-parsing mechanism significantly increases the difficulty of reverse engineering.
Based on these static analysis techniques, there are four common methods for cracking Unity games:
Type 1 : Direct modification of C# source code by decompilation of Assembly-CSharp.dll using tools like dnSpy—involving editing and recompiling the code before replacing the original file.
Type 2 : Reverse-engineering of Assembly-CSharp.dll, with modification of IL bytecode commands using editing tools (e.g., Harmony or ILDASM) without decompiling to C#.
Type 3 : Hooking the game's DLL loading process to dynamically reload recompiled DLL files. By intercepting API calls like LoadLibrary to decrypt or replace an encrypted DLL in memory before re-injecting it into the game's process.
Type 4 : Modifying the Unity game memory commands at runtime. Live command patching within game process memory using debuggers (e.g., Cheat Engine or x64dbg) to subvert program execution logic.
4. ACE's Countermeasures Against Static Analysis
To combat static analysis, ACE's hardening solution implements a multi-layered defense strategy to defend against static reverse engineering. The system applies triple encryption to key game components: encrypting export tables, function bodies, and critical code segments within SO files; encrypting symbolic metadata (variable/function/class names) in DLLs; applying high-strength protection to global-metadata.dat prevents tools like IDA Pro from accurately reconstructing core gameplay logic, substantially raising the barrier for cheat developers.
In Mono encryption, the encrypted Assembly-CSharp.dll file will lose its readable structure, rendering conventional decompilers unable to parse its contents correctly. For IL2CPP encryption, an encrypted installation package will cause parsing errors when analyzed with Il2CppDumper as the tool fails to recognize the encrypted data structure, which causes interruptions to reverse engineering.
Further analysis reveals that the encrypted global-metadata.dat file has an altered format. When parsed with Unity templates using binary editors (e.g., 010 Editor), parsing fails due to mismatched structures. This suggests the use of custom encoding or data structure reordering, which effectively breaks compatibility with standard reverse engineering tools and workflows. This protection mechanism effectively hinders conventional reverse engineering of metadata logic.
Before Encryption: Readable Metadata Structure
After Encryption: Unanalyzable Metadata Structure
5. Reverse Engineering Challenges and Defense Strategies
In cheat development, reverse-engineering the game's core logic is both the first and most time-consuming step. Successful exploitation requires deep comprehension of game data structures, critical function calls, and anti-cheat mechanisms to precisely identify exploitable vulnerabilities. For example, determining the variable address where gold is stored by static analysis, or intercepting the damage calculation function via dynamic debugging. Subsequent cheat features (e.g., aimbots or infinite resources) completely rely on these reverse engineering outcomes; failure here risks non-functional cheats or anti-cheat bans. This makes proactive defense at the source essential. The ACE anti-cheat solution, based on extensive, battle-tested data from numerous high-profile games and a deep understanding of the methods used by cheat developers, constructs a three-dimensional defense system: binary hardening, client-side shielding, and server-side behavioral monitoring—collectively resolving in-game cheating threats.
To learn more about how Anti-Cheat Expert identifies various PC and mobile game cheats and black-market operations, please click here or contact us at support@anticheatexpert.com.