Edit code in Unity APK (IL2CPP)
Unity android app can be build in 2 ways:
- Mono – DLL can be simply reversed to C#
- L2CPP – where C# code is compiled directly to binary files for ARM processor — and here the fun begins.
IL2CPP has some strengths, for example: app is faster and its code is not easily reversible. However, simple changes to it are not really difficult to do. Here we have an app that has 2 hard coded variables and 1 that we can increment.
Button increment first variable. Below is the code for this app.
It’s easy to say that by changing its code, we can achieve changes to all variables on the screen. Let’s try to doing the following:
What we need:
- Ghidra
- Il2CppDumper
- Il2CppInspector – it’s optional (we also can use only Il2CppDumper)
- APK Easy Tool
- Frhed
First of all, we need to decompile APK archive using APK Easy Tool.
Simply, choose “APK” and press “decompile” button.
I would strongly recommend to generate assembly info with Il2CppInspector now. Start application, drag and drop APK, choose the way you’d like to split files and click “extract”.
Now you can see what classes and methods are in game. Personally, I think this represents the topic in a clearest way. You as well can see it in the output files of Il2CppDumper, however the output of Il2CppDumper is needed.
Open the program and you have to choose 2 file libil2cpp.so (binary data of code) what can be found in its path
[extracted APK]/libs/[architecture]/libil2cpp.so
and global-metadata.dat (additional data to reverse more information)
[extracted APK]\assets\bin\Data\Managed\Metadata\global-metadata.dat
Now press “start”
Having all the needed files, we can finally go to the Ghidra.
Start it and create a new project.
Drag and drop or choose to add libil2cpp.so file. Ghidra should detect processor architecture and apply best options by clicking “OK”.
Now double-click on the imported file and open it. The program will ask you to analyse the file: click “yes”, then “Analyze”.
When the process is working in background, search for ghidra.py in Il2CppDumper installation directory and copy the code from the file.
In Ghidra, click green arrow to run script, create new script by clicking sheet with plus and choose Python script, name it and paste the script from Il2CppDumper inside the editor on right.
You can run it by clicking the green arrow in toolbar. Script will ask you to provide scripts.json that Il2CppDumper has generated. Find it in its output directory.
Now Ghidra knows names of functions, so it can search for method/class you want to inspect.
If you have done everything too fast, you’ll probably see some nonsense data. It’s sign that analyser hasn’t completed its work yet, so please wait.
After a while, you can see the code in assembler and some C interpretation.
To achieve changing our values in game we need to modify the assembly. Here it is shown that first some instructions are assigning to register 0 value of property a.
In C interpretation, it’s easy to see where and when all 3 variables are assigned.
Now in Frhed we can modify the binary code (libil2cpp.so).
Having changed the binary, I open it using Ghidra to see what was modified. We can see everything is changed as intended.
Now, simply select the folder of decompiled APK in APK Easy Tool and compile it again.
After compiling and running APK we can see the variables in the game changed to 255 (FF) 254 (FE) and 253(FD), so the goal is achieved.