What’s this global-metadata.dat thing and why does it matter?

Understand global-metadata.dat, the IL2CPP blueprint for Unity games, and learn what it reveals to hackers, plus how to keep them out.

By Tim UhlottFounder|Last updated: August 31, 2026|6 minutes read
cybersecurityobfuscationil2cpp
What’s this global-metadata.dat thing and why does it matter?
Ever poked around a Unity game folder and seen global-metadata.dat? When Unity builds with IL2CPP, that tiny file holds the blueprint of the game’s managed C# code. It’s metadata about your original C# types, methods, and fields. The IL2CPP runtime needs it. Reverse engineers like it too.

Wait - what is IL2CPP anyway?

Unity’s ahead-of-time trick. Instead of JIT-running C#, Unity converts the IL (that C#-compiled intermediate language) into C++, then compiles that into a native binary: GameAssembly.dll on Windows, libil2cpp.so on Android, same idea elsewhere. That’s necessary for platforms that forbid runtime code generation (for example iOS). Consoles do this too. Plenty of Android and desktop teams also pick IL2CPP because they want native code instead of managed DLLs. The downside: native code loses a lot of the “about the code” info that C# normally keeps. So Unity puts that info into global-metadata.dat. Without it, IL2CPP can’t behave like a managed environment.

What’s in that file?

Think of it as the game’s table of contents. The IL2CPP runtime uses it to find types, call methods, and read fields at the right memory offsets.
  • Type definitions - every class, struct, and interface
  • Method definitions - signatures and VTable info
  • Field definitions and offsets - how to read/write objects in memory
  • String literals and constants
  • A header with a magic number and offsets
All the structural stuff the runtime needs. It isn’t your original .cs files. Comments are gone. So is the project layout. What’s left is still a useful map of how the game is put together.

Where does Unity put it?

Same filename. Different folder, depending on the platform.
  • On Windows it sits next to GameAssembly.dll, often under GameName_Data/il2cpp_data/Metadata/
  • On Android it’s packed into the APK or AAB, usually under assets/bin/Data/Managed/Metadata/
  • On iOS it lives in the app bundle, again next to the IL2CPP data
If you can find GameAssembly.dll or libil2cpp.so, global-metadata.dat is usually nearby. Tools look for both files together.

Why is that a problem?

Because global-metadata.dat is basically a cheat-sheet for reverse engineers. Names of classes and methods, offsets of fields. Those breadcrumbs let tools like Il2CppDumper or Il2CppInspector recreate stubs or dummy DLLs you can open in a decompiler. They won’t get your original scripts. They will get a labeled outline. Names like Player.Health or ValidateReceipt tell someone exactly where to look. IL2CPP hides the C# better than Mono. The metadata file still makes reverse engineering much easier than a lot of teams expect.

Can devs make it harder to read?

Yes. Many teams try:
  • Encrypt or obfuscate the metadata on disk (simple XOR up to custom schemes)
  • Embed the metadata inside the native binary so it isn’t sitting out as a plain file
  • Obfuscate the code that loads or decrypts it, so finding the loader is a pain
Those things don’t make reverse engineering impossible. They just raise the effort. The file still has to become readable in memory when the game runs, so someone determined can hunt for that moment. The point is to stop the easy, automated path.

What about obfuscating the original C# before IL2CPP?

Do this and you get extra protection. If you obfuscate the managed C# first, rename classes, methods, and fields, scramble strings, then feed that into IL2CPP, the metadata that ends up in global-metadata.dat already has cloaked names. That changes the dump:
  • The metadata no longer hands out obvious names like Player.Health
  • Even if someone decrypts the file, it’s less useful (they see a.b.c1 instead)
  • Combined with on-disk protections, this raises the bar a lot
Renaming is the part that matters most for IL2CPP. Control-flow tricks that help on Mono often do less after the code has become C++. Hide the names and the sensitive strings first. Then encrypt the metadata if you can. Check out the GuardingPearSoftware Obfuscator for a way to do this.

What should you, as a dev, actually do?

Assume someone can see the metadata. Then:
  • Obfuscate your C# before IL2CPP so names are cloaked
  • Encrypt or hide global-metadata.dat on disk
  • Keep critical checks on the server - don’t trust the client
  • Use server-side validation for anything that affects fairness (scores, economy, matchmaking)
  • Test the protected build. Play through login, saves, and IAP. Then run a pen test or an internal red-team pass if you can
IL2CPP is a good default for platforms that need AOT. It’s also a useful extra wall on platforms that don’t. It isn’t a complete security plan by itself.

Final thought

global-metadata.dat is a small file. IL2CPP needs it to act like managed code, and it’s a convenient map for anyone trying to understand a binary. Obfuscate the original C# before IL2CPP so names are cloaked. Combine that with metadata encryption and server-side checks. Nothing is unbreakable. Make reversing annoyingly hard, and most attackers will move on.

Share this article

Frequently asked questions

Newsletter

Stay in the Loop.

Subscribe to our newsletter to receive the latest news, updates, and special offers directly in your inbox. Don't miss out!