Skip to content

Instantly share code, notes, and snippets.

@BadMagic100
Last active November 3, 2025 05:46
Show Gist options
  • Save BadMagic100/47096cbcf64ec0509cf75d48cfbdaea5 to your computer and use it in GitHub Desktop.
Save BadMagic100/47096cbcf64ec0509cf75d48cfbdaea5 to your computer and use it in GitHub Desktop.
Instructions to get a useful decompilation out of an il2cpp game. Or, "I spent hours to trial and error so hopefully you won't have to"

Decompiling IL2CPP Games with Il2CppDumper and Ghidra

This guide will walk through how to decompile/reverse engineer IL2CPP games for modding usage.

Note: expect this entire process to take upwards of an hour. Have something ready to do on the side while waiting for processing to finish.

Prerequisites

  1. Download Il2CppDumper
  2. Download Ghidra
    • Ghidra requires a supported installation of OpenJDK 17 - I recommend Amazon Corretto
  3. Download a current version of Python. Honestly I don't even know what version is set as my default so I suspect any python3 will work.

Extracting Symbol Information

Decompiling the assembly with Ghidra will lose most symbol information by default. Fortunately, IL2CPP preserves symbol information for us as global metadata. We will use Il2CppDumper to extract the relevant metadata.

  1. Open up a command line in your game folder
  2. Create a directory which will hold your outputs
  3. Run the following: Path/To/Il2CppDumper/Executable GameAssembly.dll GameName_Data/il2cpp_data/Metadata/global-metadata.dat Path/To/Output/Folder
  4. Il2CppDumper will generate a variety of files for you.
    • In the DummyDll folder, you will find stub assemblies similar to what you would get from MelonLoader.
    • il2cpp.h contains C header files with type information.
    • script.json provides configuration info for Ghidra and IDA scripts.
    • stringliteral.json provides information of all the string literals in the program.
  5. The default file generated by Il2CppDumper has compatibility issues with Ghidra, so we will have to address them. Fortunately there is an easy script to do this.
    1. Navigate to your output directory
    2. Run the following: python Path/To/Il2CppDumper/Folder/il2cpp_header_to_ghidra.py
    3. Observe that il2cpp_ghidra.h has been generated.

Decompiling the Program with Ghidra

  1. Navigate to your Ghidra installation and run ghidraRun.bat
  2. File -> New Project
  3. Set the project name as desired (I like the format GameName_X_Y_Z where X, Y, and Z make up the version number).
  4. Finish
  5. Click the Code Browser (dragon head) icon.
  6. File -> Import File. Select GameAssembly.dll. When prompted, the default settings should be sufficient.
    • You will be prompted to do an auto-analysis, select no as it will make Ghidra run much slower.
  7. Import type data
    1. File -> Parse C Code
    2. Under Parse Configuration, select VisualStudio22_64.prf
    3. Click "Save Profile to New Name" (2nd icon in the top bar)
    4. Remove all entries from "Source Files to Parse", "Include Paths", and "Parse Options"
    5. Add the generated il2cpp_ghidra.h to the "Source Files to Parse" section.
    6. Click "Parse to Program" and then "Continue". If prompted, select "Use Open Archives". This may take a while.
      • If the parser encounters syntax errors, open the file in a text editor like Notepad++ and navigate to the line in question. Note down the line number for later and comment out the entire body of the struct where the syntax error appears. Often, the syntax error Ghidra is complaining about is not a real error so we'll just work around it until Ghidra is happy.
      • If needed, we can later use the Structure Editor in Ghidra to re-populate the struct
    7. Repeat as needed until Ghidra successfully parses the header.
    8. You can view the imported types in the data types window
  8. Import function data. Open the script manager (green play icon) and run ghidra_with_struct.py. When Prompted, select the script.json that Il2CppDumper generated earlier.
    • If this is your first time, you'll have to add the Il2CppDumper scripts to Ghidra by clicking "Manage Script Directories" (third-to-last icon in the script manager top bar) and adding your Il2CppDumper install directory to the list
  9. Wait patiently while Ghidra decompiles the code. You can watch the progress in the lower right corner. This will take a while.

Using Ghidra to View the Code

  • Use Window -> Functions to open the function display. Here we can search for the methods we want. Start with ClassName$$MethodName or ClassName$$ if you don't know the specific method you want yet.
  • Dealing with async functions and coroutines - these get generated as anonymous state machine classes. For example, they might appear in ClassName.<MethodName>d__44$$MoveNext (the numbers are compiler generated). When you decompile the original method, you should easily be able to identify the calls to these state machines, and can track them down in functions window as you normally would. Again, the MoveNext method is where the state machine is actually implemented.
  • You can right click variables to rename them for easier readability.
@tenzinhl
Copy link

Holy crap, it finally finished. Definitely was an issue with run order though.

My theory on the speed issue is this: From what I can tell the issue is that Ghidra is incredibly slow at deleting/replacing type definitions. When parsing il2cpp_ghidra.h fails partway through, Ghidra still stores all successfully parsed type definitions. However, trying to parse the header file again at this point leads to a bunch of replacement operations which are known to be incredibly slow in Ghidra: NationalSecurityAgency/ghidra#4431 . I tried manually deleting the definitions from the "Data Type Manager" (bottom left in Ghidra), but this too looked like it would take millenia.

The fastest way to actually retry was to (crazily enough) recreate a Ghidra project and do all of the steps from the beginning again. When I did this with a il2cpp_ghidra.h with no parse errors, parsing took only 5 minutes (vs. I had let it run for 2 hours previously and it had not terminated).

For people coming to this thread in the future: I'd recommend making sure your il2cpp_ghidra.h is completely free of parse errors before trying to parse in Ghidra to avoid this issue and having to recreate your Ghidra project. I tried messing around with gcc to do this, but I didn't find a good set of options for only giving you the fatal cases that would cause Ghidra parse errors. gcc -fsyntax-only -Wfatal-errors was close, but I think the issue is that the il2cpp_ghidra.h uses compiler directives that gcc doesn't understand. My guess is there's probably a way to properly do it with MSVC. (Edit: Yeah, seems like it's an MSVC thing. gcc was getting upset by __int8 directives: https://learn.microsoft.com/en-us/cpp/cpp/int8-int16-int32-int64?view=msvc-170)

@Thexoxo
Copy link

Thexoxo commented Jan 29, 2025

I find the best method and its really fast lets me explaib @tenzinhl use the update version of Il2CppInspectorand with this version its will extract .h good the name is Il2CppInspector pro https://github.com/jadis0x/Il2CppInspectorPro and its work perfect https://github.com/jadis0x/Il2CppInspectorPro

@Thexoxo
Copy link

Thexoxo commented Jan 29, 2025

I find the best method and its really fast lets me explaib @tenzinhl use the update version of Il2CppInspectorand with this version its will extract .h good the name is Il2CppInspector pro https://github.com/jadis0x/Il2CppInspectorPro and its work perfect https://github.com/jadis0x/Il2CppInspectorPro

and yeah i find a video who use this exact version https://github.com/jadis0x/Il2CppInspectorPro/releases/tag/2024.12 and your theory about ressource @tenzinhl is maybe correct

@sajicooltoday
Copy link

sajicooltoday commented Jan 31, 2025

dumb question but how do you compile it back into a game. im using a exctracted apk that uses il2cpp and the tutorial works perfect i got the code i wanted to change but idk how to put it back inside and recompile. (im intending for this to work in a multiplayer game, i already got all the things i wanted to change)

@BadMagic100
Copy link
Author

You don't. You use a modloader like MelonLoader to inject and edit code at runtime

@sajicooltoday
Copy link

oh then, ill just use the LemonLoader fork of MelonLoader because it does not support apk.

also would be great if u edit the tutorial and maybe add a part of how to make the mod.

@BadMagic100
Copy link
Author

That's well out of scope here, I'm only aiming to demonstrate the reverse engineering process.

@manjaroman2
Copy link

manjaroman2 commented May 4, 2025

The Decompiler says: No function. Why?
Edit: it works, just right click -> Disassemble :)

@brainless-tee
Copy link

If you encounter errors during parsing then I strongly recommend you to fix them one by one on Visual Studio with MSVC. Most of the time the errors come from reserved keywords of the C language used as variable names. That's why I also recommend you to use the Python script from this PR [Perfare/Il2CppDumper/pull/764] (thank you @ExternalAddress4401) which renames most of these variables. Don't forget to run it from the Ghidra script manager! In my case, I had to modify it to fix all the errors.

Note that with an UP-TO-DATE VERSION of Ghidra, if the header file does not contain any errors then the parsing should be done in a few minutes maximum, even for a huge file.
Don't forget to remove the data types (or recreate the ghidra project lol) after each modification of the header file after an erroneous parsing. Otherwise the parsing will take a very very long time (thank you @tenzinhl).

@Kishandevani2006
Copy link

I have one Il2cpp backend game but when i tried this process i notice that only like 20 method or funtion show me also that is empty what to do next ?

@BeboKhouja
Copy link

BeboKhouja commented Jul 4, 2025

Can you revise the gist, and include that you may need to start over if your computer runs out of memory, while analyzing the classes? I was analyzing classes for 4 hours straight, until it finally gave up, and ran out of memory. I was at 55% iirc, and now I have to start over again.

Edit: Oops, auto analysis should be done for just a while to analyze just the game classes, Ghidra crashed before, and I restarted, and it done auto analyzing for some reason.

@ImanCol
Copy link

ImanCol commented Jul 10, 2025

I find the best method and its really fast lets me explaib @tenzinhl use the update version of Il2CppInspectorand with this version its will extract .h good the name is Il2CppInspector pro https://github.com/jadis0x/Il2CppInspectorPro and its work perfect https://github.com/jadis0x/Il2CppInspectorPro

I get this error when I run the .py script
image

@Thelta
Copy link

Thelta commented Jul 10, 2025

I find the best method and its really fast lets me explaib @tenzinhl use the update version of Il2CppInspectorand with this version its will extract .h good the name is Il2CppInspector pro https://github.com/jadis0x/Il2CppInspectorPro and its work perfect https://github.com/jadis0x/Il2CppInspectorPro

I get this error when I run the .py script image

add #@runtime PyGhidra at top of your python script.

@ImanCol
Copy link

ImanCol commented Jul 10, 2025

add #@runtime PyGhidra at top of your python script.

same error

image image

i use this version:
https://github.com/jadis0x/Il2CppInspectorPro/releases/tag/2025.6
Guidra 10.4

@Thelta
Copy link

Thelta commented Jul 10, 2025

You need at least ghidra 11.3 to run python3 scripts. Also you need to run ghidra with runPyghidra script.

@ImanCol
Copy link

ImanCol commented Jul 11, 2025

You need at least ghidra 11.3 to run python3 scripts. Also you need to run ghidra with runPyghidra script.

Ok, now I've updated Ghidra to 11.4, recreated everything, and parsed the C source code. Now, when I rerun the script with "#@runtime PyGhidra" at the top, I get this error:
image

edit: i found pyghidraRun.bat in folder Support, I'm testing right now

edit 2:
It asked me to copy il2cpp.json along with the script, I thought there would be a pop-up window.
image

and I fail
image

@ImanCol
Copy link

ImanCol commented Jul 11, 2025

I think it was fixed by changing

toAddr(address)

to

toAddr(str(address))

I'm not good at programming in Python, but hopefully the script won't cause any more problems.

@ImanCol
Copy link

ImanCol commented Jul 11, 2025

I have opened an issue in the tool's repo to see if the problem can be traced.

@BuffYoda21
Copy link

image I've followed the steps all the way to the end and found the function I wanted to view but where do I view it here?

@benny-dreamly
Copy link

benny-dreamly commented Jul 29, 2025

I've wanted to try using this for powerwash simulator, I originally tried running the global metadata file through il2cppdumper but it kept saying the auto detection failed, and a cursory research session told me it meant it was encrypted in some manner... I'm still not sure if that was 100% true

@benny-dreamly
Copy link

I've wanted to try using this for powerwash simulator, I originally tried running the global metadata file through il2cppdumper but it kept saying the auto detection failed, and a cursory research session told me it meant it was encrypted in some manner... I'm still not sure if that was 100% true

Oh my god it wasn't encrypted, I was just using the tool wrong... thank you for this guide!

@ExternalAddress4401
Copy link

image I've followed the steps all the way to the end and found the function I wanted to view but where do I view it here?

You should auto analyze the binary at this point to decompile all functions.

@humanboness
Copy link

I seriously, seriously appreciate this guide. I think it's the most useful resource so far for helping me get to a point where I have decompiled code.

Unfortunately my knowledge of programming is very limited, and I'm stuck on my current project (which is to grab assets from an APK for my own archival purposes) at a point that is past this guide. Right now I'm just at the point where I need to figure out exactly how assets are called upon and from where- but like I said, I've little-to-no experience with programming and game development.

I don't know how much information to post in this comment, because I'm worried that now it's too off topic from the original guide, but I'm really just looking to access image files. It's a gacha game, so there's numerous assets that weren't in my ripping attempts with apkTool and AssetStudio :( Somehow there's no obb file in my emulator either, so I can't even retrieve them that way.

I'm really sorry if this is too far away from the point of the guide, I'm just desperate and a bit too stupid 🥺 I'm seeking help or insight anywhere and everywhere I can, because I've been working on this for 2 weeks now and I feel like I've exhausted every possible google search that I could.

TLDR; Absolutely killer guide! I just wish I knew where to go next with the decompiled code though 😭

@khanhkhoktvn
Copy link

Encrypted metadata stopped me damn. Works well in normal il2cpp games tho <3

@ExternalAddress4401
Copy link

ExternalAddress4401 commented Sep 15, 2025

I seriously, seriously appreciate this guide. I think it's the most useful resource so far for helping me get to a point where I have decompiled code.

Unfortunately my knowledge of programming is very limited, and I'm stuck on my current project (which is to grab assets from an APK for my own archival purposes) at a point that is past this guide. Right now I'm just at the point where I need to figure out exactly how assets are called upon and from where- but like I said, I've little-to-no experience with programming and game development.

I don't know how much information to post in this comment, because I'm worried that now it's too off topic from the original guide, but I'm really just looking to access image files. It's a gacha game, so there's numerous assets that weren't in my ripping attempts with apkTool and AssetStudio :( Somehow there's no obb file in my emulator either, so I can't even retrieve them that way.

I'm really sorry if this is too far away from the point of the guide, I'm just desperate and a bit too stupid 🥺 I'm seeking help or insight anywhere and everywhere I can, because I've been working on this for 2 weeks now and I feel like I've exhausted every possible google search that I could.

TLDR; Absolutely killer guide! I just wish I knew where to go next with the decompiled code though 😭

Depends highly on the game and Ghidra might not be the way to go here. If they're stored encrypted or in a container format you're not going to get them out without significant programming and reverse engineering knowledge. Frida might help you bypass some of that but it also requires programing knowledge and a lot of digging to determine what functions you're interested in. It's also possible they're coming over the network and you're looking in the wrong place. That might require bypassing SSL which the app will most likely be using and sniffing requests that way.

@JonJon565
Copy link

Is there a new script for wasm files? There's the ghidra_wasm.py but that one is outdated.

@1ilir0lika
Copy link

what should i do if the metadata file is encrypted?
I can't manage to get it after it gets decrypted because for whatever reason frida doesn't allow me to do such thing

@ExternalAddress4401
Copy link

what should i do if the metadata file is encrypted? I can't manage to get it after it gets decrypted because for whatever reason frida doesn't allow me to do such thing

You can you just don't know how. You don't do anything until you get a decrypted copy of the metadata. That's the point of encryption.

@1ilir0lika
Copy link

what should i do if the metadata file is encrypted? I can't manage to get it after it gets decrypted because for whatever reason frida doesn't allow me to do such thing

You can you just don't know how. You don't do anything until you get a decrypted copy of the metadata. That's the point of encryption.

would you suggest a script to help me read obfuscated metadata?

@ExternalAddress4401
Copy link

what should i do if the metadata file is encrypted? I can't manage to get it after it gets decrypted because for whatever reason frida doesn't allow me to do such thing

You can you just don't know how. You don't do anything until you get a decrypted copy of the metadata. That's the point of encryption.

would you suggest a script to help me read obfuscated metadata?

Nope. This is on you to determine what they've done and how they've encrypted it.

https://katyscode.wordpress.com/2021/02/23/il2cpp-finding-obfuscated-global-metadata/

There is no script you can just use to magically get decrypted metadata from every game out there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment