Skip to content

Instantly share code, notes, and snippets.

@Slluxx
Last active April 30, 2024 01:11
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Slluxx/502e3c7d0ebe8608af2c74e8cafd01cb to your computer and use it in GitHub Desktop.
Save Slluxx/502e3c7d0ebe8608af2c74e8cafd01cb to your computer and use it in GitHub Desktop.
How to patch Nintendo Switch Applications in IDA

Patching the Youtube App

In short

  1. Extract the main NSO
  2. Convert it into an ELF (to strip header/hashes)
  3. Load it into Ida, find the function and patch the bytes back into the binary
  4. Convert the ELF back into NSO
  5. Use the nso as exefs patch or re-import it into the NCA/NSP

AFAIK its easier to just use the nso as layeredfs/exefs patch instead of worrying about replacing it with original files in NCAs and NSPs.

Detailed

1) Extracting the main NSO

This can be done in different ways. You may prefer using HACTool, extracting all NCAs and use HACTool again to extract the content of the NCA that contains the main.nso (in the files its just called "main").

I prefer using NxFileViewer, which allows me to preview filenames in a tree-structure and extract just the files i need from within NCAs.

2) Convert NSO to ELF

Use nx2elf2nso.zip, extract it and place your main file in there and click "decompress". It will automatically convert "main" to "main.elf", which you can then load in IDA. You can ignore errors, it should still be good to load.

Apparently you can load the main (nso) in Ida Pro using one of two plugins, but i didnt manage to make that work so above is what i advice to do.

3) Patching the ELF

This is the hardest part and it will change from app to app, maybe even from version to version.

Loading in Ida

Open up a new Ida instance and click "work on your own". After Ida is initialized, just drag the .elf file you generated into the Ida window, hit okay to everything (defaults should be fine) and let it load. This might take a long time and you shouldnt do anything in Ida while its doing its thing, because ida will drastically slow down if you do. It will inform you with a Windows sound as soon as its done analyzing and the bottom left corner will show "idle".

What you are seeing now, should be the node-view of the ARM assembly code. Its time to find the function you want to patch.

Patching

There isnt really anything i can tell you to find the function you want to patch. It will most likely be different and you need to poke around the nodes, function list and maybe strings (shift+f12) to find where you need or want to go. Keep in mind that there is more than one way to find where you need to go. If you think its easier going a different route, go ahead.

In the youtube app (2.0.0), you can click the "Functions" window on the left side and search (STRG + F) for GetNetworkService (the full function name is starboard::nxswitch::UserManager::GetNetworkService). Doublecklicking the entry will lead you inside the function. Functions can be called multiple times from multiple different places in the code.

If you are not in the node based view, i advice you to do that now by pressing SPACEBAR.

Find the function call (BL) to starboard::nxswitch::UserManager::AcquireNsaIdToken. thats the one that we need to replace.

The function call you need to find

Click that line, click on Edit (in the top left of Ida), go to "Patch program" and click on "Patch byte...". It will open up a new window, showing the Hex value that make up this ARM instruction. In my case its C7 01 00 94 1F 10 00 71 88 FE FF 54 E8 03 00 2A, which (using this site) translates to:

bl #0x71c
cmp w0, #4
b.hi #0xffffffffffffffd8
mov w8, w0

You can compare the screenshot with the "translation" and see that they are the same but instead of the names that Ida shows us, we get the actual Assembly "place". Thats because Ida tries its best to make it as much human readable as possible for us while analyzing it.

Instead of the function at #0x71c being executed, we want to write a 0 into the register w0. Explaining why would go beyond the scope of this little writeup. But you can press F5 in the IDA-view window to convert the ARM code into pseudo C like code and you see that there is a switch statement/comparison going on and we just want to have it a certain outcome.

You can use the same website to translate this:

mov w0, #0
cmp w0, #4
b.hi #0xffffffffffffffd8
mov w8, w0

back into the values that Ida accepts: 00 00 80 52 1F 10 00 71 88 FE FF 54 E8 03 00 2A

Now you can Apply those bytes to the original binary. Click on the line again, click on Edit (in the top left of Ida), go to "Patch program" and hit "Apply patches to input file". Everything should be fine, but i advice you to always check the "create backup" box.

4) Convert the ELF back into NSO

Now you can close ida (save database if you want to skip analyzing the binary the next time). If the elf file is not already inside the folder where the "nx2elf2nso" files are, place it in there and execute the "compress" batch file. It will create a new file called "main.nso".

5) Use the nso as exefs patch

Place the main.nso file on your switch in this folder (create if nessesary): atmosphere/contents/01003A400C3DA000/exefs and remove the ".nso" extension.

Start the youtube app to test the patch.

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