# frida-il2cpp-bridge: dumping IL2CPP games without the metadata file

> frida-il2cpp-bridge is a Frida module and command line tool that reconstructs the type information of an IL2CPP application while it is running, which means you do not need the global-metadata.dat file that normally has to be extracted from the binary. It can dump the classes, trace and replace method calls, and it emits the result as C# source.

**vfsfitvnm/frida-il2cpp-bridge** — A Frida module to dump, trace or hijack any IL2CPP application at runtime, without needing the global-metadata.dat file

- Repository: https://github.com/vfsfitvnm/frida-il2cpp-bridge
- Website: https://github.com/vfsfitvnm/frida-il2cpp-bridge/wiki
- Stars: 1,764 · Forks: 311
- Language: TypeScript
- License: MIT
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/vfsfitvnm-frida-il2cpp-bridge

## The type information, recovered at runtime

frida-il2cpp-bridge is a Frida module to dump, trace or hijack any IL2Cpp application at runtime, without needing the global-metadata.dat file.

That last clause is the whole point of the project. A Unity application built with IL2CPP keeps its type metadata in a separate file, global-metadata.dat, which is usually encrypted or packed inside the application package. The offline workflow is to extract that file, decrypt it, run it through a metadata parser and end up with a set of C# headers. This module skips that by asking the running process instead, reading the metadata structures out of the live IL2CPP runtime, which is where the answers already are.

The feature list is four lines. It dumps classes, methods, fields and so on. It traces, intercepts and replaces method calls. It lets you mess around with the C# runtime directly. And it gives you Il2Cpp structs and global metadata almost for free, with the almost doing quiet work in that last phrase.

The package is published to npm as frida-il2cpp-bridge, it is MIT licensed, and the primary language in the repository listing is TypeScript and the CLI in Python under cli/.

## Unity versions, platforms, and the tested caveat

The Compatibility section has two parts, and the second one is the one to plan around.

For Unity versions, it should work for any Unity version in the range 5.3.0 to 6000.3.x. That is a very wide range covering most of the lifetime of the Unity versions that shipped IL2CPP as the default for mobile, and it means the module is not tied to a particular engine generation.

For platforms, Android, Linux, Windows, iOS and macOS are supported. However, only Android and Linux are tested, and the documentation says plainly to expect breakage if you are using another platform.

That is an unusual admission to find in a compatibility table, and it is worth taking at face value. The module does low-level things inside another process, so it depends on the runtime layout, the compiler and the platform conventions, and each of those differs. If you are on Windows or iOS, the support is plausible and untested, which is a different thing from unsupported.

The pragmatic reading is that the project has a real user base on Android and Linux, which is where the majority of IL2CPP games actually run, and that the other platforms are there because the mechanism is in principle portable.

## The CLI that ships with the npm package

Starting from version 0.10.0, a frida-il2cpp-bridge Python executable is included alongside the NPM package installation. The executable wraps the frida command and adds IL2CPP specific features, and to invoke it you simply run:

```sh
npx frida-il2cpp-bridge --help
```

or, equivalently:

```sh
npm exec frida-il2cpp-bridge -- --help
```

The packaging detail is worth noticing. The package is a Node module, its main, module and exports entries all point at dist/index.js, and the types come from dist/index.d.ts, but the bin entry is cli/main.py. So a JavaScript library and a Python command line tool ship in the same tarball, and the Python side is what gives you the dumping subcommand.

Wrapping the frida command is the design decision that makes the CLI useful. Frida's own command line is the transport for attaching to a process and injecting a script, and the IL2CPP specific work sits on top of that, so you get the familiar frida options plus the dumping and tracing commands that only make sense for an IL2CPP target.

## The dump subcommand and its output options

The dump subcommand is the part everybody uses, and its options are about the shape of the C# output rather than about the scan itself.

The main switches are --out-dir, where to save the dump, defaulting to the current working directory, and --cs-output with the values none, stdout, flat and tree, defaulting to tree. None does nothing, stdout prints to the console, flat writes one single file called dump.cs, and tree produces a directory structure with one file per assembly.

Then there are the switches that change how the types are written. --no-namespaces suppresses namespace blocks and prepends the namespace name in class declarations instead. --flatten-nested-classes writes nested classes at the same level as their enclosing classes. --keep-implicit-base-classes writes the implicit base classes, meaning class becomes System.Object, struct becomes System.ValueType and enum becomes System.Enum. --enums-as-structs writes enum declarations as structs. --no-type-keywords uses fully qualified names for the built-in types instead of their keywords. There is also --actual-constructor-names and --indentation-size.

The point of that list is fidelity to a C# compiler's output. A dump is only useful if it compiles, or at least reads like something a decompiler would produce, and each of those switches exists because some other tool expects that shape.

## The build, and the bundling trick

The package is TypeScript that gets compiled into a single bundled JavaScript file, and the Makefile shows how.

The dist target depends on node_modules, the lib directory and tsconfig.json, and it runs the TypeScript compiler to emit a bundled JavaScript file, a map and typings, touching the output afterwards so the build system notices the change. The node_modules target is a plain npm install, and the clean target removes the dist directory and the compiled test agent.

The prepare script in the package manifest is make dist, which means an install from a git checkout builds the bundle, and the watch script runs the compiler in watch mode through tspc.

The dev dependencies explain the bundle. There is ts-patch, which is the usual way to patch the TypeScript compiler, and ts-transformer-inline-file, a transformer that inlines the source of individual files into the emitted output. The second one is the reason the published package is a single file rather than a directory of modules, and the overrides block pins the TypeScript version that transformer needs.

The formatting configuration in the manifest is unusual in one respect, with a printWidth of 160 and a tabWidth of 4, which is wider than the usual 80 or 100. For generated-looking code and for a bundle that is read by people debugging it, that is a reasonable choice, and the prettier settings are in the package manifest rather than in a separate file, which keeps the configuration next to the code it applies to.

## How the tests are built, and what they run against

The test setup is the most interesting engineering in the repository, because it solves a problem that would otherwise be unsolvable: you need a real IL2CPP binary to test against.

The Makefile looks for Unity versions by listing the directories under test/unity and taking the last path component of each, which gives a UNITY_VERSIONS list, and the help target prints them sorted by version. The tests then run against each of those GameAssembly.so files, either locally or in a container.

There are four relevant targets. The assembly target creates a GameAssembly.so using the given UNITY_VERSION by running make inside the test/unity version directory, and it is marked as Linux only. The image target builds a Docker image containing that GameAssembly.so, tagged frida-il2cpp-bridge-playground with the version. The test target runs the tests against each local GameAssembly.so, and the testd target runs them against the dockerized ones, taking the Docker host from the current docker context.

The test agent is a separate TypeScript program in test/agent that is compiled with tspc into test/agent/dist, and there is a small native host program, test/src/host.c, compiled with clang into test/build/host, which is what actually loads the Unity assembly.

So the test matrix is the set of Unity versions the maintainer keeps checked out, and the assertion is that the bridge still recovers the right types from each one. The .check_UNITY_VERSION guard makes the version a required input rather than a default, which stops a run from silently testing only one engine generation.

## The repository and the release state

The top-level entries show a small project with a real test harness, and the directory names line up with the architecture: lib/ for the Frida module, cli/ for the Python command line tool, example/ for a sample TypeScript program with its own package.json and tsconfig, and test/ for the Unity versions, the agent and the native host.

The rest is the build configuration: a Makefile with the targets above, a .clang-format for the C++ side, a tsconfig.json for the TypeScript side, and a package.json that ties them together. There is a LICENSE file for the MIT terms.

The release history is regular and the version numbers are small. Version 0.13.1 came on 2026-04-30, 0.13.2 on 2026-08-07 and 0.14.0 on 2026-09-06, with the last push on 2026-09-06, the same day as the newest tag. The repository is not archived, and the package manifest carries version 0.14.0.

The 0.x numbering is the one thing to hold in mind when you depend on it. A tool that reconstructs type information from a running process is going to break when the runtime changes underneath it, and the project has been honest about that in the platform section. Treat the version as something you check when you upgrade the target, rather than something that upgrades itself.

## Conclusion

Adopt frida-il2cpp-bridge if you are reverse engineering a Unity IL2CPP application and the usual detour of extracting global-metadata.dat from the binary is the part you want to skip, or if you need the type layout at runtime for instrumentation rather than offline. Do not adopt it if your target is a Mono build, since the whole mechanism depends on the IL2CPP runtime, and do not expect it to be equally supported everywhere, because only Android and Linux are described as tested. Before you start, check the Unity version of your target against the supported range, and expect the CLI to want the application running or a way to attach to it.

## FAQ

### What does frida-il2cpp-bridge do?

It is a Frida module to dump, trace or hijack any IL2CPP application at runtime, without needing the global-metadata.dat file. It can dump classes, methods and fields, trace, intercept and replace method calls, mess with the C# runtime, and gives you Il2Cpp structs and global metadata almost for free.

### Which Unity versions and platforms are supported?

It should work for any Unity version in the range 5.3.0 to 6000.3.x. Android, Linux, Windows, iOS and macOS are supported, but only Android and Linux are described as tested, and the documentation says to expect breakage on the others.

### How do I run the frida-il2cpp-bridge command line tool?

From version 0.10.0 the package includes a frida-il2cpp-bridge Python executable that wraps the frida command and adds the IL2CPP specific features. You invoke it with npx frida-il2cpp-bridge --help or npm exec frida-il2cpp-bridge -- --help, and the package bin entry points at cli/main.py.

### What output options does the dump command have?

The --cs-output switch chooses between none, stdout, flat and tree, with tree as the default, producing a directory with one file per assembly, and flat writing a single dump.cs. There are also switches for namespaces, nested class flattening, implicit base classes, enums as structs, fully qualified type names, actual constructor names and the indentation size.

### How is the frida-il2cpp-bridge project tested?

Against real Unity builds. The Makefile lists the Unity versions checked out under test/unity, builds a GameAssembly.so for each, and runs the tests either locally or in a Docker image tagged with the Unity version. A TypeScript test agent is compiled with tspc and a small native host is compiled from test/src/host.c with clang.

## Sources

- [License: MIT](https://github.com/vfsfitvnm/frida-il2cpp-bridge/blob/master/LICENSE)
- [Project website](https://github.com/vfsfitvnm/frida-il2cpp-bridge/wiki)
- [README](https://github.com/vfsfitvnm/frida-il2cpp-bridge/blob/master/README.md)
- [Releases](https://github.com/vfsfitvnm/frida-il2cpp-bridge/releases)
- [vfsfitvnm/frida-il2cpp-bridge on GitHub](https://github.com/vfsfitvnm/frida-il2cpp-bridge)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/vfsfitvnm-frida-il2cpp-bridge
