Decompiling C# Assemblies vs. IL2CPP Metadata Restoration
Auditing a Unity game starts by checking the compilation method. Mono builds place C# logic inside Assembly-CSharp.dll, which decompiles cleanly using dnSpy. To increase security, developers use IL2CPP (Intermediate Language to C++) to convert C# into native assembly. While this prevents simple decompilation, it does not prevent reverse engineering.
During an audit, we extract the metadata file (global-metadata.dat) and the compiled native binary (libil2cpp.so on Android or GameAssembly.dll on Windows). We run tools like Il2CppDumper to restore the C# class structures, method offsets, and string values, mapping the native assembly execution path:
# Run Il2CppDumper to generate dummy DLLs and metadata mapping
./Il2CppDumper libil2cpp.so global-metadata.dat output_directory
# Load output dummy DLLs into dnSpy to analyze class signatures Dynamic analysis and memory manipulation
If your game manages virtual currency or in-game purchases, we test the client's vulnerability to local memory editing. Attackers run memory scanners to scan the application's RAM, locate memory addresses holding values, and modify them. We verify if your game uses obfuscated data types to prevent raw integer scanning:
// Frida script hooking IL2CPP method to inspect score updates
const lib = Module.findBaseAddress("libil2cpp.so");
const scoreOffset = 0x123456; // Method offset from Il2CppDumper output
Interceptor.attach(lib.add(scoreOffset), {
onEnter: function (args) {
const currentScore = args[1].toInt32();
console.log("[Unity Audit] Current Score: " + currentScore);
}
}); The Fix: Never trust the client state. Crucial attributes (balance, level, inventory) must be stored and calculated on the server. If an offline mode is necessary, values in memory must be obfuscated or periodically hashed with cryptographic signatures to verify integrity.
API verification and parameter tampering
The most critical vulnerabilities in Unity games exist in their backend integrations. If the game server accepts client-submitted endpoints indicating purchases or scoring outcomes without verification, the game economy can be bypassed. We intercept HTTPS traffic using proxy tools (like Burp Suite) and attempt to replay and modify request parameters:
// VULNERABLE purchase callback payload sent by client
POST /api/purchase/verify
{
"productId": "coins_tier_4",
"purchaseToken": "mock_token_created_by_client",
"status": "success" // Server trusts this value without validating with Google/Apple stores
} The Fix: All purchases must undergo receipt validation server-side directly with the Apple App Store or Google Play Store APIs before crediting user balances.
Score injection in WebGL Unity game
We audited a Unity WebGL game used for a promotional marketing campaign with cash rewards. By dumping the WebGL WebAssembly file, we identified the websocket endpoint and the event hash used to report player scores. We constructed a custom script to send signed high-score events directly to the server, achieving top placement on the leaderboard without playing the game. Fix priority: high. Remediated by implementing server-side logic validation for player movements.
Building a Unity game or virtual platform? Secure your client-server logic.
Book a Unity Game AuditFrequently asked questions
Where is the compiled C# logic stored in Unity applications?
In standard Unity builds, code is compiled into C# assemblies (like `Assembly-CSharp.dll`) located in the managed data folder. If the game uses IL2CPP, the C# code is compiled into native C++ binaries (`libil2cpp.so` or `GameAssembly.dll`), which requires metadata restoration to analyze.
How do you test a Unity game's backend API?
We intercept HTTP/HTTPS requests sent by the Unity client to the game server. We check if the server relies on client-reported states (like scoring, purchase approvals, or inventory modifications) without independent verification.
Can attackers modify memory values in Unity games?
Yes. Attackers use memory editors (like Cheat Engine or GameGuardian) to search for active memory addresses holding values like coin balances or player health and alter them directly in RAM.
Related reading
Blog: Reverse engineering Android · Hardcoded key leaks · API-driven fraud scripting
Services: Mobile penetration testing · API security testing