*June 23rd, 2021 Update: Guardsquare Becomes the First Mobile Application Security Platform to Join Unity’s Verified Solutions Partner Program. Learn how Guardsquare protects Unity mobile games from cheaters
On top of this, the latest releases introduce specific techniques to obfuscate the C# metadata generated by Unity to prevent critical information from leaking. All of the above, when combined together, represent the most effective way to prevent revenue loss through piracy or reputational damage caused by cheating gamers.
With the release of DexGuard 8.6 and iXGuard 3.3, Guardsquare has extended its app security capabilities to mobile games built using the popular cross-platform game engine Unity. DexGuard and iXGuard can now process Unity games and apply all existing application shielding techniques, including code hardening (control flow obfuscation, string encryption, etc.) and runtime application self-protection (RASP) (jailbreak/root detection, hook detection, etc.).
In this blog post, we take a closer look at the metadata Unity generates, explain why it’s important to take extra measures to prevent this data from leaking, and describe how DexGuard and iXGuard can help game developers better secure their valuable creations.
As you likely know, Unity is a cross-platform game engine that enables developers to build games for Android and iOS using a single code base. It uses C# as a scripting language, which is not natively supported on either Android or iOS. The C# code is transformed into C++ code by Unity’s Il2Cpp compiler, which is then used to generate Xcode and Android Studio application projects.
In addition to C++ code, Il2cpp generates metadata, which is saved as an external file called ‘global-metadata.dat’. The file is stored inside the generated application and is loaded by the Il2Cpp runtime during application initialization. It contains information about all runtime entities used in the application, including the names and types of all classes, methods and properties and the links between them, as well as all string literals, such as API keys, used in the C# code. The metadata is referenced from the generated C++ code and serves to link methods to their implementation.
All of the metadata stored in the global-metadata.dat file is easy to retrieve and provides attackers with information they can use to reverse engineer mobile games. To retrieve the metadata, attackers can use readily available open source tools like Il2CppDumper. It generates a readable C# ‘dump.cs’ file from a metadata file and an application binary and writes all string literals to a ‘stringliterals.json’ file. In addition, it creates a dummy dll file that can be used in standard C# reverse engineering tools to further analyze the internal logic of the application. The collected information can be used, for example, to build an aimbot to get an unfair advantage over other gamers.
To illustrate how easy it is to retrieve information from the global metadata file, we run the Il2CppDumper on a small sample application. It generates the following output in ‘dump.cs’:
The file contains the definition of all classes used in the original C# code:
It also links the methods to the correct addresses in the supplied binary, providing a convenient starting point for reverse engineering the application. In this particular case, the ‘isPremium’ field could attract the attention of a hacker aiming at bypassing license checks to get unpaid access to premium content.
On top of that, Il2CppDumper exports all the used string literals, which can give unauthorized parties access to sensitive information such as API keys.
When DexGuard and iXGuard process and protect Unity games, they also obfuscate the information in the global metadata file. This doesn’t change the behavior of the application but defeats static analysis tools such as Il2CppDumper.
Running Il2CppDumper on the sample application after it has been protected by DexGuard yields entirely different results (iXGuard behaves similarly). The class definitions are there, but all class names are unreadable, making the output virtually unusable for reverse engineering:
DexGuard encrypts the string literals to ensure they cannot be retrieved from the global metadata file, as the ‘stringliteral.json’ file below shows:
As you can see, obfuscating metadata is an essential part of full application protection, especially when it comes to mobile games. Proper mobile game security should be layered and must include both code hardening and runtime application self-protection (RASP). Only a complete and layered approach to security will effectively protect apps against piracy and cheating, which can lead to major revenue loss and reputation damage.