[Engage] Code Editing notes

This is a draft document. Expect the process to change as I get more familiar.

Things you need:

  • dumped romfs & exefs
  • Ghidra with the nintendo switch loader plugin
    • make sure the versions match: at time of posting the latest release of Ghidra is 10.2.3, but the latest release of SwitchLoader is only compatible with Ghidra 10.2.2 (or you can build from source)
  • il2cppdumper
  • switch-tools (compiled version here)
  • python 3
  • HxD

Setting up Ghidra:

  1. Copy exefs/main and roms/managed/metadata/global-metadata.dat into the il2cpp folder and run il2cppdumper.exe. This will create an il2cpp/output folder.
    • Next run il2cpp_header_to_ghidra.py. This will give you il2cpp/il2cpp_ghidra.h
  2. Open Ghidra
    • File > Install Extensions and install the SwitchLoader extension.

    • Create a new project, and File>Import File selecting exefs/main (i tend to rename the ProgramName to the title update version number e.g. main1.2 as of current writing)

    • Once imported, let it run analysis with the default options (takes a while)

  3. Window > Script Manager and create a new script (type: Python). Name it whatever. When the text input window appears, copy and paste in the contents of il2cpp/ghidra_with_struct.py.
  4. Save and run the script. When prompted, select il2cpp/output/script.json.
  5. File > Parse C Source and add a new source file to parse. When prompted select il2cpp/il2cpp_ghidra.h that we created previously. Click ‘Parse to Program’.

You can now start looking through the code for interesting functions.

Making edits:

Let’s make it so items don’t consume uses. The function we’re after is App.UnitItem$$Expend which can be found in the Symbol Tree.

The address (in v1.2) is 0x7102408f60. We want to change the code here to never expend an item. Below we can see that it does some checks and branches based on the number of uses. We can nop the branch to ensure it always returns 0 without expending a use.

First, using the switch tools you can use decompress.cmd to turn main into main.elf.

Using HxD you can make edits to main.elf. To find the address in HxD we first subtract the 0x7100000000 offset, giving us 0x2408f74. Then we add 0x908 header giving us 0x240987c. I use https://armconverter.com/ to turn assembly into hex - Switch uses ARM64:

Copy and paste the hex into HxD, using CTRL+B instead of CTRL+V so that it doesn’t alter the file size.

Then you can run compress.cmd to get main.nso. Copy this into your mod’s exefs folder and rename it to main (no extension). You should now be able to try it in game.

Coming soon: advanced il2cpp reverse engineering (?)


Hello, Mr. circles! I’ve learned some asm hacking skills through cheat code making tutorials. And I wonder if we can build a decomp project for engage like zelda did(It is called botw on the github) :thinking:

Hi, thanks for your notes. They were super helpful!

I am a complete newbie though, so wanted to check something. Is it normal for the main file to have lots of unknowns after doing all the steps?

Like there’s a massive gap starting from 7104e12dd9.

Logically, I guess it wouldn’t be unusual, since we’re trying to decompile compiled code. But wanted to double check, just in case!