Converting .3DS to .CIA for Hackers!

Hello, and welcome to the great guide on how to convert your games to work on CFW/Gateway yourself, without ever having to read a "user-friendly" script to ever know what the hell went wrong.
At the end of this tutorial you will know how to convert your games by using tools made by others, and if you're going to repeat this process often, you will probably want to hack a script together yourself to automate this (Protip: it's actually not that difficult to copypasta some commands into your favorite text editor).
This guide is geared towards linux users, but in contrast to pre-made scripts, these commands can be used almost anywhere as long as you have the tools on said platform.
Some games are really big, and because they are stored about 2 or 3 times their size in ram during some operations, you may need a 64bit computer and/or some swap space.

So, without further ado, let's begin:

First, we need the tools. Create a directory somewhere to put them.
Let's make a list:

* The game you want to convert
* On linux, you will compile the tools yourself, as there are no prebuilt binaries. You need at least gcc, g++ and make (search in your repositories), though installing the development tools package of your distribution isn't a bad idea.
* Python 2.7 (Again, search your repositories)
* A 3DS on 4.x with the mset exploit, or a 9.0-9.2.

* slot0x25KeyX.bin (Search the interwebz, because rulez disallow me from linking)
Put the hex number you found on the webz in a file called slot0x25KeyX.bin with your favorite hex editor. Copy the file to the tools directory.

* 3DS_Multi_Decryptor (or Decrypt9 if you're on 9.x) [thread]
The former contains prebuilt binaries in the github repo, the latter has a download link for prebuilt binaries in the thread.
To compile any of both yourself, grab devkitPRO (Just grab the perl updater and set variable, it's not difficult to install), and run "make" in the source directory.
Copy Launcher.dat and ctrKeyGen.py (or ncchinfo_gen.py if using Decrypt9) to your tools directory.
Optional (For firmware >=7.x roms): Copy MEX.py from 3DS_Multi_Decryptor to your tools directory.

* ctrtool and makerom (There are several versions on github, this is the most recently updated)
On linux, for makerom comment line 130 in ncch.c as it causes a segfault (details).
Run "make" in both directories, copy the binaries (named the same as their respective directories) to your tools directory.

* padxorer
Run "gcc -O3 padxorer.c -o padxorer" and copy the binary to the tools directory.

* Optional (for manual and download play): rom_tool [thread]
Just run "make" in the rom_tool directory and copy the resulting binary to the tools directory.

* Optional (If you don't want to create the rsf file yourself): rsfgen [post]
Also get dummy.rsf.
Just put rsfgen.py and dummy.rsf in the tools directory.
NOTE: It's inportant for dummy.rsf to use dos line endings. If you copy/pasted it instead of downloading it you may have problems. If the generated file by rsfgen.py looks weird, this may be the problem.

* Optional (To reinject the original headers into the rom): ExInjector [post]
Just put the file in the tools directory.


Now you should be ready for the action.
Create a new directory, place the tools directory inside and put your game there.

First, create ncchinfo.bin (Use ncchinfo_gen.py instead if you're using Decrypt9):
Code:
python2 tools/ctrKeyGen.py game.3ds && mv tools/ncchinfo.bin .

Now, grab a working Fat32-partitioned SD card (At least 2gb, but depends on game size).
Make sure slot0x25KeyX.bin has the right contents. If it doesn't, no program will tell you about it, and will continue generating your .cia happily.
Copy tools/Launcher.dat, tools/slot0x25KeyX.bin and ncchinfo.bin to the root of your SD card.
Pop it into your 3DS and launch the mset exploit (Or go to http://dukesrg.no-ip.org/3ds/go with the browser if using Decrypt9).
Choose "NCCH padgen" from the menu (I'm not sure about Decrypt9), and wait. This should take a while.
Pop the SD back into your PC, and copy all the *.Main.*.xorpad to some directory (I'll use "xorpads").

Now, extract the encrypted contents of your game:
Code:
tools/ctrtool -p --exheader=exheader.bin --romfs=romfs.bin --exefs=exefs.bin game.3ds
It may complain about the exheader hash, but you shouldn't care.

Optional: If you have a *.Main.exefs_7x.xorpad, the game is for formware 7.x or higher. You need to merge dem xorpads.
Code:
python2 tools/MEX.py exefs.bin xorpads/*.Main.exefs_norm.xorpad xorpads/*.Main.exefs_7x.xorpad xorpads/Main.exefs_norm.xorpad && rm xorpads/*.Main.exefs*.xorpad
NOTE: I haven't tested this, because I haven't encountered a 7.x game, yet.

Now, we have to decrypt the contents of the game:
Code:
array=(exheader exefs romfs); for item in ${array[@]}; do tools/padxorer $item.bin xorpads/*Main.$item*.xorpad; done
rm *.bin
rename .bin.out .bin *.out

Now, extract the exefs to obtain the icon and banner:
Code:
tools/ctrtool --exefsdir=exefs --decompresscode -t exefs exefs.bin

Now, create the rsf:
Code:
cp tools/dummy.rsf game.rsf
python2 tools/rsfgen.py --rsf game.rsf --rom game.3ds --exheader exheader.bin --regionfree exefs/icon.bin --spoof
The --spoof option is optional if you want to enable firmware spoofing.
The --regionfree option is optional if you want to patch regionfree.
NOTE: Check the generated game.rsf file. If it looks weird, your dummy.rsf probably doesn't use dos line endings. Download it with git (or zip download), or convert it with unix2dos or similar.

Optional: If you want the manual/download play, you need to extract the .cfa:
Code:
tools/rom_tool --extract=. game.3ds
rm -f *APPDATA.cxi *UPDATEDATA.cfa

Now, create the cxi:
Code:
tools/makerom -f cxi -o game.cxi -target t -rsf game.rsf -icon exefs/icon.bin -banner exefs/banner.bin -exefslogo -code exefs/code.bin -exheader exheader.bin -romfs romfs.bin

Optional: Inject original exheader
Code:
python2 tools/ExInjector.py -rom game.cxi -exheader exheader.bin -sd -fwspoof
The -fwspoof option is optional if you want to enable firmware spoofing.
NOTE: I've tried to use this with two roms, and it stuck on the 3ds logo. You may have a different experience, though.

Now, create the final cia:
Code:
tools/makerom -f cia -o game.cia -content game.cxi:0:0 -content $(echo *MANUAL.cfa):1:1 -content $(echo *DLP.cfa):2:2
You can remove any of the -content if your game doesn't have it, or you don't want it.
It may warn you about the cia not going to be encrypted, but we want it unencrypted.

That's it! Copy, install, and play!

If you're having problems, or there's something wrong with this guide, please post it in this thread.

Appendix

How to use rxTools to make this process a bit faster when bulking:
Okay, so recently, this thing got released, called rxTools.
It's a toolkit with a lot of different functions, and one of them is bulk-decrypting .3ds games, thus making it unnecessary to screw around with xorpads.
I'm going to explain how to bulk this stuff, my style.

First of all, you're going to need all the requirements of the original tutorial, except for 3DS_Multi_Decryptor, MEX.py and padxorer.

Now, get rxTools from here, and put rxTools.dat on the root of your SD card, along with slot0x25KeyX.bin, and copy your 3ds games anywhere except inside the "Nintendo 3DS" directory.
Launch rxTools with the web exploit, and press the "Decrypt CTR Titles" option. This can take a while.
Turn off your 3DS, and copy the (now decrypted) .3ds file(s) to your working directory.

Now, follow the appendix on how to convert decrypted .3ds files.

The next step would be throwing a script together to bulk the conversion.
How to convert decrypted .3ds files:
These kinds of files can be aquired in multiple ways, like rxTools, or converted CIAs you want to edit it's romfs. It's useful to be able to convert them.

You're going to need all the requirements of the original tutorial, except for 3DS_Multi_Decryptor, MEX.py and padxorer.

To convert a game, extract the (now decrypted) contents of your game like in the original tutorial (IMPORTANT: don't use the -p flag, this won't work), and follow the rest of it from the step where I show how to extract the exefs.
Common problems:
Problem: When you get this error when trying to build a cxi:
Code:
[EXHEADER ERROR] ExtSaveDataId is unavailable if AccessibleSaveDataIds is specified.
[EXHEADER ERROR] Failed to create ExHeader
Solution: Comment ExtSaveDataId in game.rsf

Like, subscribe, comment, share, shill, give it as a present to your mom and feed it to your dog!
 

mid-kid

GBAtemp spamBOT
OP
Member
Joined
Aug 2, 2012
Messages
879
Trophies
0
Age
25
XP
1,163
Country
Okay, jesus, calm down.

881880__safe_rainbow+dash_animated_screencap_upvotes+galore_reaction+image_angry_faic_tanks+for+the+memories_spoiler-colon-s05e05.gif


DO I LOOK ANGRY!?


Because I wasn't.
 

d0k3

3DS Homebrew Legend
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
I'm currently thinking about ways to streamline the process of converting 3DS to CIA files. My first idea was to code a complete 3DS to CIA converter into Decrypt9, but with all the stuff that makerom and rsfgen.py do, that might not be a possibility. As you may already know, my build of Decrypt9 (check my signature), at this point, already contains a full NCCH/NCSD decryptor (in other words, a feature that fully decrypts .3DS roms, without the need for xorpads, same as you already wrote rxTools does). This eliminates the need for ctrKeyGen.py, MEX.py and padxorer (or alternatives of these tools). It also has proper seed decryption.

Coding a CXI / MANUAL / DLP / EXEFS / ICON / BANNER extractor would be a snap, eliminating the need for using CTRtool.

Now, I still wonder...
  • Is ExInjector.py still needed or do the recent versions of makerom and rsfgen.py already handle this good enough?
  • Do we need to uncompress the .code in exefs? It looks like this is done somewhere, but I don't see where this is needed now.
  • Any other idea how we could make the process easier with further preprocessing in Decrypt9?
And, bonus question: What about converting CIA to 3DS? Can we do this simple in one step using makerom (yeah, it's clear that this will only run via Gateway then), or is something else needed?
 

mid-kid

GBAtemp spamBOT
OP
Member
Joined
Aug 2, 2012
Messages
879
Trophies
0
Age
25
XP
1,163
Country
I'm currently thinking about ways to streamline the process of converting 3DS to CIA files. My first idea was to code a complete 3DS to CIA converter into Decrypt9, but with all the stuff that makerom and rsfgen.py do, that might not be a possibility. As you may already know, my build of Decrypt9 (check my signature), at this point, already contains a full NCCH/NCSD decryptor (in other words, a feature that fully decrypts .3DS roms, without the need for xorpads, same as you already wrote rxTools does). This eliminates the need for ctrKeyGen.py, MEX.py and padxorer (or alternatives of these tools). It also has proper seed decryption.

Coding a CXI / MANUAL / DLP / EXEFS / ICON / BANNER extractor would be a snap, eliminating the need for using CTRtool.

Now, I still wonder...
  • Is ExInjector.py still needed or do the recent versions of makerom and rsfgen.py already handle this good enough?
  • Do we need to uncompress the .code in exefs? It looks like this is done somewhere, but I don't see where this is needed now.
  • Any other idea how we could make the process easier with further preprocessing in Decrypt9?
And, bonus question: What about converting CIA to 3DS? Can we do this simple in one step using makerom (yeah, it's clear that this will only run via Gateway then), or is something else needed?

Sorry for this late response.
I've never actually needed ExInjector, so I think it's fine. The code.bin has to be decompressed.
However, if you want to convert 3ds to cia actually properly (without the need to decrypt), you should only need to decrypt the exheader, and move the parts around into a cia. At least, that's what I think Riku's "Simple 3DS to CIA" program does (which is closed source).

--------------------- MERGED ---------------------------

So this wont work on 6.0 with mset exploit?

Use Decrypt9 with the web browser, or with CakeHax (Here's a reasonable up to date build). Use CakesROP.nds to install the ROP.
 
  • Like
Reactions: d0k3

Megalegacy98

Well-Known Member
Member
Joined
Aug 11, 2015
Messages
505
Trophies
0
Location
United States
XP
430
Country
United States
Sorry for this late response.
I've never actually needed ExInjector, so I think it's fine. The code.bin has to be decompressed.
However, if you want to convert 3ds to cia actually properly (without the need to decrypt), you should only need to decrypt the exheader, and move the parts around into a cia. At least, that's what I think Riku's "Simple 3DS to CIA" program does (which is closed source).

--------------------- MERGED ---------------------------



Use Decrypt9 with the web browser, or with CakeHax (Here's a reasonable up to date build). Use CakesROP.nds to install the ROP.
oh cool, thanks.
 

CuriousTommy

Well-Known Member
Member
Joined
Jul 22, 2014
Messages
524
Trophies
0
Age
27
XP
647
Country
United States
Installing a new cia now...

EDIT:
Worked... :-/
Do you know what exactly you did? I was able to convert everything but Kid Icarus: Uprising and The Legend of Zelda: A Link Between Worlds both go in a loop on the 3DS loading screen.

This is what I used to create the .cia file:
Code:
tools/ctrtool --exheader=rom/parts/exheader.bin --romfs=rom/parts/romfs.bin --exefs=rom/parts/exefs.bin rom/game.3ds && tools/ctrtool --exefsdir=rom/parts/exefs --decompresscode -t exefs rom/parts/exefs.bin && cp files/dummy.rsf rom/parts/game.rsf && python2 tools/rsfgen.py --rsf rom/parts/game.rsf --rom rom/game.3ds --exheader rom/parts/exheader.bin --regionfree rom/parts/exefs/icon.bin --spoof && tools/rom_tool --extract=rom/parts rom/game.3ds && rm -f rom/parts/*APPDATA.cxi rom/parts/*UPDATEDATA.cfa && tools/makerom -f cxi -o rom/parts/game.cxi -target t -rsf rom/parts/game.rsf -icon rom/parts/exefs/icon.bin -banner rom/parts/exefs/banner.bin -exefslogo -code rom/parts/exefs/code.bin -exheader rom/parts/exheader.bin -romfs rom/parts/romfs.bin && python2 tools/ExInjector.py -rom rom/parts/game.cxi -exheader rom/parts/exheader.bin -sd && cd rom/parts/ && ../../tools/makerom -f cia -o ../game.cia -content game.cxi:0:0 -content $(echo *MANUAL.cfa):1:1 -content $(echo *DLP.cfa):2:2 || ../../tools/makerom -f cia -o ../game.cia -content game.cxi:0:0 -content $(echo *MANUAL.cfa):1:1 || ../../tools/makerom -f cia -o ../game.cia -content game.cxi:0:0 -content $(echo *DLP.cfa):2:2 || ../../tools/makerom -f cia -o ../game.cia -content game.cxi:0:0 && rm -frd * && cd ../..
It looks disgusting but it works for the most part.
 

gudenau

Largely ignored
Member
Joined
Jul 7, 2010
Messages
3,882
Trophies
2
Location
/dev/random
Website
www.gudenau.net
XP
5,312
Country
United States
Do you know what exactly you did? I was able to convert everything but Kid Icarus: Uprising and The Legend of Zelda: A Link Between Worlds both go in a loop on the 3DS loading screen.

This is what I used to create the .cia file:
Code:
tools/ctrtool --exheader=rom/parts/exheader.bin --romfs=rom/parts/romfs.bin --exefs=rom/parts/exefs.bin rom/game.3ds && tools/ctrtool --exefsdir=rom/parts/exefs --decompresscode -t exefs rom/parts/exefs.bin && cp files/dummy.rsf rom/parts/game.rsf && python2 tools/rsfgen.py --rsf rom/parts/game.rsf --rom rom/game.3ds --exheader rom/parts/exheader.bin --regionfree rom/parts/exefs/icon.bin --spoof && tools/rom_tool --extract=rom/parts rom/game.3ds && rm -f rom/parts/*APPDATA.cxi rom/parts/*UPDATEDATA.cfa && tools/makerom -f cxi -o rom/parts/game.cxi -target t -rsf rom/parts/game.rsf -icon rom/parts/exefs/icon.bin -banner rom/parts/exefs/banner.bin -exefslogo -code rom/parts/exefs/code.bin -exheader rom/parts/exheader.bin -romfs rom/parts/romfs.bin && python2 tools/ExInjector.py -rom rom/parts/game.cxi -exheader rom/parts/exheader.bin -sd && cd rom/parts/ && ../../tools/makerom -f cia -o ../game.cia -content game.cxi:0:0 -content $(echo *MANUAL.cfa):1:1 -content $(echo *DLP.cfa):2:2 || ../../tools/makerom -f cia -o ../game.cia -content game.cxi:0:0 -content $(echo *MANUAL.cfa):1:1 || ../../tools/makerom -f cia -o ../game.cia -content game.cxi:0:0 -content $(echo *DLP.cfa):2:2 || ../../tools/makerom -f cia -o ../game.cia -content game.cxi:0:0 && rm -frd * && cd ../..
It looks disgusting but it works for the most part.

Use Simple Cia Converter.
 

yubimusubi

Member
Newcomer
Joined
Apr 9, 2016
Messages
7
Trophies
0
XP
57
Country
United States
I know this is an old thread, but I wanted to say thanks for this.

Do you know what exactly you did? I was able to convert everything but Kid Icarus: Uprising and The Legend of Zelda: A Link Between Worlds both go in a loop on the 3DS loading screen.

It would be nice if folks told how they fixed it :)

I had the same problem with ALBW but I rebuilt it without the ExInjector and it worked for me. There's no online mode with ALBW as far as I know so there's no reason for the ExInjector.

Use Simple Cia Converter.

I'm sure your intentions are good, but I feel like that comment runs counter to the spirit of the OP. Some of us can't or won't use a Windows computer. Personally I don't own a PC with a Windows license. And the whole point of building your own CIA files is to avoid piracy (I think) so pirating Windows doesn't really make sense.

I also wanted to echo the point about Linux `rename` command being different in different distributions. A pure bash solution for that line would be:

Code:
for f in *.bin.out; do mv $f ${f%.bin.out}.bin; done;

I think that's bash specific and might break in other implementations of sh like dash.

Another tip for command line junkies - I like to put the commands into my PATH... that way I don't have to type /path/to/tools each time I run them.

Also, keep in mind these commands eat a lot of RAM. I had other memory-hungry programs running at the same time and my system was swapping like crazy.

One more hiccup I experienced was that when I converted Bravely Default, I was able to run the CIA and create/save new games, but when I used SaveDataFiler (or svdt, etc.) to import my cartridge save I got an error when trying to load it (it showed up on the load screen, but clicking it error'd out). I was able to import it by rebuilding without the region free patch. I just thought I'd share to hopefully help anyone who ran into the same problem.

Thanks again for the guide! It's nice to feel like Linux users aren't second class citizens :)
 

gudenau

Largely ignored
Member
Joined
Jul 7, 2010
Messages
3,882
Trophies
2
Location
/dev/random
Website
www.gudenau.net
XP
5,312
Country
United States
I know this is an old thread, but I wanted to say thanks for this.



It would be nice if folks told how they fixed it :)

I had the same problem with ALBW but I rebuilt it without the ExInjector and it worked for me. There's no online mode with ALBW as far as I know so there's no reason for the ExInjector.



I'm sure your intentions are good, but I feel like that comment runs counter to the spirit of the OP. Some of us can't or won't use a Windows computer. Personally I don't own a PC with a Windows license. And the whole point of building your own CIA files is to avoid piracy (I think) so pirating Windows doesn't really make sense.

I also wanted to echo the point about Linux `rename` command being different in different distributions. A pure bash solution for that line would be:

Code:
for f in *.bin.out; do mv $f ${f%.bin.out}.bin; done;

I think that's bash specific and might break in other implementations of sh like dash.

Another tip for command line junkies - I like to put the commands into my PATH... that way I don't have to type /path/to/tools each time I run them.

Also, keep in mind these commands eat a lot of RAM. I had other memory-hungry programs running at the same time and my system was swapping like crazy.

One more hiccup I experienced was that when I converted Bravely Default, I was able to run the CIA and create/save new games, but when I used SaveDataFiler (or svdt, etc.) to import my cartridge save I got an error when trying to load it (it showed up on the load screen, but clicking it error'd out). I was able to import it by rebuilding without the region free patch. I just thought I'd share to hopefully help anyone who ran into the same problem.

Thanks again for the guide! It's nice to feel like Linux users aren't second class citizens :)
Just use mv...

Also Wine is an option.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
  • ZeroT21 @ ZeroT21:
    it wasn't a question, it was fact
  • BigOnYa @ BigOnYa:
    He said he had 3 different doctors apt this week, so he prob there. Something about gerbal extraction, I don't know.
    +1
  • ZeroT21 @ ZeroT21:
    bored, guess i'll spread more democracy
  • LeoTCK @ LeoTCK:
    @K3Nv2 one more time you say such bs to @BakerMan and I'll smack you across the whole planet
  • K3Nv2 @ K3Nv2:
    Make sure you smack my booty daddy
    +1
  • LeoTCK @ LeoTCK:
    telling him that my partner is luke...does he look like someone with such big ne
    eds?
  • LeoTCK @ LeoTCK:
    do you really think I could stand living with someone like luke?
  • LeoTCK @ LeoTCK:
    I suppose luke has "special needs" but he's not my partner, did you just say that to piss me off again?
  • LeoTCK @ LeoTCK:
    besides I had bigger worries today
  • LeoTCK @ LeoTCK:
    but what do you know about that, you won't believe me anyways
  • K3Nv2 @ K3Nv2:
    @BigOnYa can answer that
  • BigOnYa @ BigOnYa:
    BigOnYa already left the chat
  • K3Nv2 @ K3Nv2:
    Biginya
  • BigOnYa @ BigOnYa:
    Auto correct got me, I'm on my tablet, i need to turn that shit off
  • K3Nv2 @ K3Nv2:
    With other tabs open you perv
  • BigOnYa @ BigOnYa:
    I'm actually in my shed, bout to cut 2-3 acres of grass, my back yard.
  • K3Nv2 @ K3Nv2:
    I use to have a guy for that thanks richard
  • BigOnYa @ BigOnYa:
    I use my tablet to stream to a bluetooth speaker when in shed. iHeartRadio, FlyNation
  • K3Nv2 @ K3Nv2:
    While the victims are being buried
  • K3Nv2 @ K3Nv2:
    Grave shovel
  • BigOnYa @ BigOnYa:
    Nuh those goto the edge of the property (maybe just on the other side of)
  • K3Nv2 @ K3Nv2:
    On the neighbors side
    +1
  • BigOnYa @ BigOnYa:
    Yup, by the weird smelly green bushy looking plants.
    K3Nv2 @ K3Nv2: https://www.the-sun.com/news/10907833/self-checkout-complaints-new-target-dollar-general-policies...