Hacking Introduction to how 3DS hacks work

MrJason005

√2
OP
Member
Joined
Nov 26, 2014
Messages
2,521
Trophies
0
Location
Κάπου
XP
1,607
Country
Greece
INTRODUCTION TO 3DS HACKING
"What the fuck am I doing when I follow 3ds.guide?"


The goal here is simple: To explain how the 3DS works behind the scenes.
Most people who hack their 3DS using 3ds.guide don't know what they are doing. We unfortunately have ended up with a big black magic box that's supposed to do all of our work for us, even when we are working in a system so complicated that even to make small modifications you will need to know a lot about its inner workings.
To quote yifan.lu:
writing mods for the 3DS is extremely difficult and usually requires an in depth knowledge of the system even to make simple modifications.
I've seen countless posts here, in chatrooms, on reddit, and on many other forums where people blindly follow the instructions for installing the popular B9S/Luma combo on their 3DS, only to finish the guide, and just stare at their monitor thinking "Wow, I have no idea what I just did, but hey, it works, so, let's keep it".
I believe that people should know what they are doing, since it only benefits them in the end. There is no noob-friendly total complete package that explains everything fundamental about the 3DS, and I believe that simply pointing everyone to a lot of dev-speak that they cannot understand, is not the correct way to educate people and encourage them to learn more.

When you are finished reading this guide, you will have a basic understanding of how we actually hack the 3DS, and hopefully I will have answered a lot of questions that may be in your minds.
There are nearly zero pre-requisites needed for this guide, since I have tried to explain everything either through parenthesis or through foot-notes. However, if you have a decent amount of computer knowledge you would be many steps ahead.
The people who fall into this category are the people who can install Arch linux without issues on their computer. What I mean to say is that if you have questions in your mind along the lines of "What is FAT32?" or "What does 'cutoff' mean when someone says that a processor can only access a certain part of RAM?" or "What is a service?" or "What's a function in a program?" you aren't in this category. But this isn't bad! It just means that you may have to re-read some parts of the guide a few times to get the point I'm trying to make.

Also, if there is some part of the guide that doesn't make sense, then I am doing something wrong. Let me know and I'll look into fixing it up.

So, without further ado, let's get right to it.

3DS HARDWARE AND SOFTWARE
Hardware
Okay, to begin, let's talk about the hardware. The 3DS has two processors, one is the ARM11, and the other is the ARM9. Now, to be technically correct, there is also an ARM7 for better backwards compatibility with GBA and NDS games, but we're not going to go into too much detail because this isn't a thread about NDS-Bootstrap Loader1, or AGB_FIRM2
The ARM11 is the more powerful processor, and it is what handles running the actual 3DS games. So, whatever you see, the home menu, the web browser, games, all run on that processor.
The ARM9 is used heavily when you play a DS game on the 3DS using the DS backwards compatibility mode (Called TWL_FIRM3). However, in 3DS mode, the ARM9 is reused as a security processor.
The 3DS also has RAM (because it is essentially a computer), and it is split into a lot of different areas (FCRAM, AXI WRAM, ITCM, SoC memory, etc.), but it boils down to 3 parts: RAM that is only for the ARM9 processor, RAM that is shared between the two processors, and RAM that is for the ARM11.

Apart from the actual chips that are soldered on your 3DS motherboard that do the processing, we also have the power cycle of the 3DS, or more specifically, the bootROMs for each of the two processors.
Since the bootROMs are embedded in the actual die of the CPU, I will put this explanation here, in hardware.
"But Jason, what is a bootROM?" Good question. So, whenever you turn on your 3DS, your 3DS doesn't simply turn on. Instead, this happens20:
Code:
Power button --> ARM9 BootROM initialized --> Run some code --> Lockout the BootROM permanently (Until the next cold restart) --> Arm9loader --> Load the console-specific keys stored in the OTP region --> Lockout the OTP region permanently (Until the next cold restart) --> Load the Firmware (The actual "OS" of the 3DS)

What does all this mean?
Well, the bootROM is a very small portion of the processor in which some code is located, such that it is the very first thing that is initialized whenever you press the power button. In this case, the ARM9 bootROM is initialized first, and then the ARM11 is initialized later (of course by its own bootROM), but keep in mind that the ARM9 sends the command for the ARM11 to power on, not the power button.
As you may or may not know, ROM stands for Read Only Memory (R.O.M.). This means that whatever code is in that area, it is there for good, and cannot be modified by a firmware update, the only way is through a new hardware revision. The good thing about such a system is that it ensures that it is unhackable, since you cannot write your own hack to that region. The bad thing though, is that if you slip up and make a mistake and leave it in that unwritable area, you cannot fix it, and spoiler alert, Nintendo did slip up and leave an exploit for us in the bootROM.

Apart from the bootROM, you may have also read about the OTP region. The OTP region is a region in the SoC4 where the console-specific data is located at. From this console-specific data, you can generate keys which are going to be console-specific. These console-specific keys are important for decrypting many things on your 3DS, for example decrypting the NAND.
Lastly, you may have noticed that there is a "bootROM lockout" and "OTP lockout". What these mean is that, after the system accesses whatever it needs to access from those regions, it locks them out permanently until the next cold restart8. This is because there is very sensitive information in there (Things like various keys and the "source" code9, which we can search for exploits), and Nintendo didn't want people to mess around in that area.

There are a few more things implemented in the hardware that might interest us, like the AES and the RSA engine which are integrated in the ARM9 die (really important for signatures!), but apart from that, we don't really need to know more in order to understand how the 3DS security is actually breached.

Implementation & Software
So now that we know what's under the hood, let's see how it's all connected and programmed.
As you know, the ARM9 is used as a security processor. Specifically, whenever you try to run a game, encrypt or decrypt something, install anything with DevMenu, BigBlueMenu or FBI, the ARM9 makes sure that whatever you are trying to do is legit. Also important to note is that the ARM9 is the processor that actually reads and writes to the NAND (Essentially the hard drive of your 3DS). Now, all those capabilities have to be called from somewhere, we need to tell the system to execute those capabilities somehow (we call these capabilities "functions"), and the ARM11 does that. To be exact, the ARM11 kernel.
Here's a diagram of how the the tree of privileges is implemented (credit goes to the 32c3 nintendo presentation):

RGQ9j5QMQ_uSvozWRfrTfg.png
At the top we have the ARM96 After that is the ARM11 kernel and the ARM11 itself.
Whatever application you run, be it games or anything else, run in the ARM11 userland (Userland, as in, that's where the user resides). The ARM11 kernel (Sometimes abbreviated to K11, as in, KERNEL11) is what has full rights over the entire ARM11 processor, and that includes the userland. The ARM11 is also what handles the actual installation process of CIAs, granted the ARM9 authorizes it first (It does so by checking the signature7), so, if a signature is checked to be legit, the installation/runtime is approved by the ARM9.

HACKING THE 3DS - GETTING ARM9 ACCESS
Now we get to the real meat of the story. So what exactly are we trying to do when we say "I'm going to hack my 3DS"? What do the hackers mean when they say "Breaching the 3DS security"?
What I need to say right now is that our end goal when trying to hack a 3DS is getting access to the ARM9. We want our 3DS to boot up automatically on coldboot to an environment where the ARM9 is hacked automatically. And to do that, we need NAND read/write access. What we are trying to do is, install Boot9Strap (I'll get to what it is later, for now, treat it as the files we need to copy over to the NAND so that we install the hack), and it requires the ability to read/write to the NAND. You know how when you try to install an application in windows using a .exe installer? That requires writing and reading to the hard drive. And same for the 3DS. When we need to install something10, we need to access to the 3DS' storage, the NAND.
In order to get NAND access, we need to take control of the ARM9, and as you already know, the ARM9 is the security processor, which means it has plenty of security features.
So, let's step back a bit and look at the bigger picture. We are trying to hack our 3DS, and we need to get NAND access to install Boot9Strap. We need to get ARM9 access in order to get access to the NAND, therefore, our goal is to hack the ARM9. But how do we hack the ARM9?

I will now explain, from start to finish, how Soundhax works, which is one of the most popular ways of hacking 3DSes (I explain NTRBoot later on...)

First of all, Soundhax is just the userland exploit. You can't really do much in userland, if your end goal is to install boot9strap. Our end goal is to get ARM9 access. And good news, there is an ARM9 exploit, it's called safehax!

Safehax is actually an old exploit from 2013.
The old exploit, called firmlaunch-hax, took advantage of the fact that during a FIRM launch, the ARM9 would write some data to the RAM shared between the ARM11 and the ARM9, and it wouldn't expect the ARM11 to do anything to that portion of RAM. We of course abused this and, with the ARM11 kernel access we had, we would write whatever we wanted to that portion of RAM, and the ARM9 would execute it without noticing that that region of RAM was overwritten with a hack payload. And we got our ARM9 code execution.
But what is a FIRM launch? To understand this, you first have to understand how the 3DS firmware is split up.
You see, the 3DS' firmware is split into 3 parts, those are NATIVE_FIRM, TWL_FIRM and AGB_FIRM.
Whenever you play a DS/DSi game, TWL_FIRM is loaded. Whenever you play a GBA game through GBA Virtual Console, AGB_FIRM is loaded. Whenever you are doing anything else, NATIVE_FIRM is loaded.
A FIRM launch is essentially changing from one FIRM to another (e.g. you go from NATIVE_FIRM to TWL_FIRM), and during a FIRM launch, the ARM9 is vulnerable to firmlaunch-hax.
The important thing here is that the 3DS has a special mode, called SAFE_MODE_FIRM, in which you can boot into. And this mode almost never gets updated12, so it should have very old exploits. And that is exactly the case. The catch though, is that you need ARM11 kernel access.
Therefore, if we can somehow get ARM11 kernel access, we can reboot into this SAFE_MODE_FIRM, and have access to old code, and exploit it! And that is what we do11.
For a more detailed explanation, refer to Swiftloke's safehax explanation.

So now we just learned that safehax requires K11 access, and we are in luck, because there is an exploit that can give us K11, it's called udsploit.
udsploit works by a curious hardware flaw of the 3DS.
The 3DS' GPU has access to a certain part of RAM (because a graphics card needs memory). However, the GPU is wired up to much more more memory than it should be wired up to. It is connected to the entire 3DS' memory in fact.
When you have a userland exploit, you have entire access to the GPU (because games use the GPU to draw graphics on the screen), and with access to the GPU, you can copy data to the GPU's RAM (masqueraded as a texture copy) , which in this case, is also main memory. This is called D.M.A. short for Direct Memory Access. Once you copy over data to the main memory with the GPU, the ARM11 kernel will get this code and it will run it, because it stills thinks it's running whatever piece of software it was running before. This exploit of getting the GPU to render to the main memory is called GSPWN.
For example, if you had a copy of Ocarina of Time 3D, and you used the userland exploit in that, the 3DS wouldn't know that you are in the homebrew launcher, it would still think that you are playing OoT. And if the 3DS gets a request from the GPU to copy textures, it will obey since it thinks it's running an innocent OoT game19.

If you are in the homebrew launcher, this means that you were able to get userland code execution. In order to elevate from userland to K11 you will have to use the GSPWN exploit.
However, the GSPWN exploit was sort of fixed with a special register. The GSPWN exploit is essentially a hardware exploit (since if you wire up the GPU to the RAM then it is an unfixable exploit), BUT, you can program the 3DS so that it only allows a certain part of memory to be used by the GPU. It is set by a special register in a configuration, and you cannot change this register from userland.
There is way of configuring this register though. The 3DS' WiFi module has access to this register, and by using our userland access to use the WiFi module, we could reset this config register and then the GPU would have entire access to the memory. Once we have entire access to the memory, we can do whatever we want with the ARM11 kernel and write whatever code we want to the memory so that it gets executed by the ARM11 kernel. And this exactly is the reason why you need to have the WiFi enabled, it's so that you can set this register that allows you to do the GSPWN exploit!

And now the last step we need to achieve is to get a userland exploit, which is easy, we got soundhax for that. Now, I won't get too technical about this, but you can watch this if you're interested. Suffice it to say, it works

One last thing to say here is that the exploits are actually executed backwards, we first get userland, then we get K11, then we get ARM9. This is how it's done in 3ds.guide as well, it first instructs you to execute soundhax, then through the homebrew launcher you can execute udsploit, then we execute safehax.

WHY THE 3DS NEEDS TO BE HACKED ON EVERY RESTART - THE NEED FOR A COLD BOOT EXPLOIT
So now that we have taken over the ARM9 and we can execute whatever code we want there, we essentially can do whatever we want with the 3DS. We can patch out signature checking, we can do custom modifications to the system, essentially what most people want out of a CFW.
Here's the issue though, every time we reboot the 3DS, all of our work gets erased (because RAM gets cleared on shutdown13), so every time we shutdown and boot up the 3DS, we need to go through this process again of soundhax-->udsploit-->safehax, and it can get a bit annoying.
This is how Gateway14 or rxTools was back in the day. Every time you shutdown your 3DS, you had to execute the old DS Profile exploit15, and it would get annoying sometimes.
But why can't we make it so that the 3DS get hacked on bootup?
Let's get back to the bootROM we talked about earlier. See, the bootROM is programmed to only load genuine firmwares (Firmware = Operating System of the 3DS), so even if we got ARM9 access, all that we can do is simply patch whatever we already have, what is already loaded by the 3DS. We cannot load whatever firmware we want, because the bootROM will refuse to load it as it is not signed by Nintendo, and even if we have ARM9 access, we cannot do anything to change the fact that the bootROM will only load genuine firmwares, as it is read only.

What the 3DS hacking scene was trying to do is find a way to load unauthorized firmwares right from bootup, and it took us until Derrek announced at 33c3 this thing called sighax, which allows us to sign our own firmwares, essentially allowing us to load whatever we want in the 3DS without ever needing to go through the hacking process. If we never had Boot9Strap (or A9LH16 for that matter), every time you would want to run a unsigned game you would have to run the 3 hacks in a row and go through a lot of time in order to get code execution.

So now, the big question in everyone's mind is "What is Boot9Strap?". Everyone refers to it as the hack you need to install, but, what does that even mean?
Well to explain it entirely, we need to explain how digital signatures actually work.

RSA DIGITAL SIGNATURES
The basics
RSA Stands for Rivest Shamir Adleman (The three people that invented it). It is an asymmetric cryptographic algorithm, which means that we can encrypt something with a public key, but only decrypt it with a private key, or the other way around, we can encrypt something with a private key, and only decrypt it with the public key.
The public key and the private key are mathematically connected. The reason why you cannot retrieve the private key from the public key, is because you would need to factor a very large (617+ digits long!) number into two prime numbers (See Fundamental theorem of arithmetic), something which is nearly impossible.


A hashing algorithm is basically a function, in which you give it some data, and it spits out some gibberish. The reason why this is useful is because:

  • If you enter the same thing in this function, you will always get the same gibberish
  • No two inputs give the same gibberish
  • You cannot reverse the output to get the input, it is impossible
The algorithm which we use for hashing is SHA-2, the 256 bit version of SHA-2 to be exact.



The simple way of signing
If you want to sign something, the following things are done:
  1. First, you take the piece of data and hash it (So that if you have a huge piece of data you want to sign, you can just hash it and get a unique hash which is essentially the same as the piece of of data)
  2. Then, you take your private key and encrypt that hash
  3. The encrypted hash is now the signature
  4. Once the recipient receives your letter, he hashes the message
  5. The recipient decrypts the signature with your public key and gets the decrypted hash
If the hash he produced from your message matches the encrypted hash you sent him (which he decrypted using your public key), we are 100% sure that the piece of data was signed by you, because only you have the secret key.
If someone wants to forge a signature, he must obtain your private key in some way shape or form, and use it to encrypt the hash of whatever he wants to send, or he can also try to brute force a perfect signature which when decrypted using the public key will give a desired hash. There is no other way to forge your signature, unless... you don't implement the RSA algorithm properly.

See, when a computer program goes and reads a signature, it actually reads this:

RXgXCwlNQHeQ2-55nD3r4g.png
That above, is an actual RSA signature. We generate it by taking the piece of data we want to sign (In this case, the 3DS' NAND header), hashing it, and encrypting it.
You may notice however, all these "ffffffff" that are taking up the majority of the space here. These "fffffff" are called padding, and the reason why we use padding is quite simple.

See, in the end, a signature is just a number. In order to encrypt something, we do the following exponential operation:

CQoczPqYRJGsQNhc16sc1A.png
Where c is the data you want to encrypt, d is the private key and n is the public key (the product of the two primes)
If you remember, there is this following property of exponentials:
vCwGCbOOQ6W3xnyg3tWHiA.png
From these 2 facts, we can create our own encrypted messages without knowing the private key. For example, if you have an encrypted message A:

sHf3FZGvQjO9s8enfc16kw.png
And also, another encrypted message B:
yc5K0yJATyqjTDXtj7-uyA.png
Then you can find what AB is equal to:

AFjomIX2Q4CkBRdBK741Bw.png
And be sure that AB will be regarded as a legitimately encrypted message, since the match checks out.

This is a big problem for our signature! What can we do?
Well, we... could add some gibberish in the signature, making it so that the signatures can't be fabricated with the math trick above. And this exactly, is called padding.
We add some gibberish (in this case, the "fffffff"s sprinkled in), and this bypasses the big problem we had. Problem solved!

Now, you don't need to know the nitty-gritty details about all of this, but in order to understand the ingenious trick behind sighax (I'll get to what it is in a bit), you need to understand a few basic things.
First of all, the signature is read from left to right, top to bottom. We have a pointer that is similar to the pointer you get when you type something on a computer

f01a6b4c-153c-4348-bac1-e5c30ceae7f1
giphy.gif
Now this cursor, goes, from left to right, top to bottom as I have said. For example, here is the signature block I posted being parsed:

giphy.gif


What happens here, is the parser 17 reads every single byte (a byte in this context meaning a pair of characters, so we start with the 00 and we continue on to 01 and ff etc.) one by one18. And as the parser goes along, it reads every single byte and checks it to see if it is a correct one or not (Don't worry, I'll explain in a bit)


SIGHAX EXPLAINED

So what is sighax? Good question!
Sighax is a bootROM exploit that allows us to sign our own firmwares. But how does this exploit work? How is it even possible? Aren't signatures encrypted with the private key and decrypted with the public key?
Well, we're going to go through this step by step, so stick to me and it will make sense.

How a signature is parsed:

Let's start by looking at the signature with which the NAND is signed:

RXgXCwlNQHeQ2-55nD3r4g.png
Whenever you turn on the 3DS, the bootROM has to make sure that the signature is indeed legit. It does this by parsing the signature byte by byte.
First of all, it reads this 00 at the start. This declares that we are about to start a signature.
After that, it finds this 01 value. This value, called padding type, declares whether padding will exist in this signature or not, 01 meaning "Padding will follow" and 02 meaning "Padding will not follow".
If you read the math spoiler above, you would know that this should always be set to 01, since this increases the security of signatures dramatically. But... Nintendo, for whatever reason, decided to allow us to just use the 02 value if we want, and the bootROM has no objections to that.

Already we have a major problem! You should never allow people to write signatures without padding, as you can brute force signatures a LOT easier!
We don't know why Nintendo did this, but the fact of the matter is this: You can disable padding in signatures.
Now, OK, this is... very big indeed. But still, a signature is a signature. The fact that you can skip a padding scheme may help in brute forcing a signature, but it doesn't magically erase the fact that a brute force effort must take place (If you want to brute force a signature).
So, let's move on:

If you set this byte to 01 you will make the bootROM check all of that padding, and make sure it is all "fffff". If you don't, it will just skip along. In both cases however the bootROM will keep reading until it finds this 00 byte at the end. Once it finds this 00 byte, it says "OK, I parsed all of the padding, now we will continue on to the other important bits"

The next few bytes aren't really that important for us. The 30 byte must always be set to 30, and it does some minor thing. The 31 is completely ignored (Nintendo ¯\_(ツ)_/¯ ), and this other 30 must always be set to a value of 30.
After that, we get to the good stuff.
This 0d value (in lime green) is the most important value in the entire signature, and I'll tell you why:

This 0d value, tells the parser how long the next value is going to be (The washed-out lime color, 060960...). But here's something funny: The parser completely skips this next value!
This value that follows the 0d is called inner block data, and it is supposed to tell the parser which type of hashing algorithm was used. We all know we are using SHA256, and the bootROM expects the signature to use this hashing algorithm for the hashing process, and the bootROM never reads this value!
When the bootROM never reads a value, it completely skips it. This means that I can, for example, add a 5, so the parser will know the length of inner block data is 5, and it will skip 5 bytes (5 pairs of characters, 10 characters). Or I can type 0f and it will skip exactly 15 bytes *. Note that this value can only be written as hexadecimal, i.e in 0x00 form (Numbers in base 16).
Here's what the parser does when it sees this value:

Firstly, it comes to the byte which declares how many bytes the next value is going to be:
giphy.gif

Then, it reads this value. In this case, 0d in hexadecimal means 13 in base 10. This means that we will skip 13 bytes, or 26 characters (Since a byte is a pair of two characters)
giphy.gif

Then it does the skipping process...
giphy.gif

And it continues on normally the parsing process.


If however, you were to modify this value: Instead of 0d you modified this to, for example 0f, you would skip 15 bytes instead of 13. So in total 30 characters:

giphy.gif

OK, so we can skip any number of bytes we want, essentially moving the pointer to whatever point we want. This is cool and all... but we don't have a use for it (...yet).
Let's just finish explaining the parsing process before we move on to sighax and its skipping trick.

We left off at parsing inner block size and inner block data, so naturally, we continue on parsing normally.
After that follows a 04 and 20 that tell the parser some information, but the parser skips these values as well.

Now finally we get to the finishing part of the signature, and this is the hash. As you already know, the fundamental idea behind a signature is a hash comparison.
You have one hash which you encrypt (Called the correct hash), and one hash which you calculate on the spot (called the calculated hash), and if those two hashes match, then the signature is legit.

After the final 20 byte is the correct hash.
What the bootROM does when it gets to this part, is it jumps ahead to the next hash, which is the calculated hash.
Once the pointer is at the start of the calculated hash, the bootROM hashes the NAND i.e. it generates a new hash right there on the spot, then it overwrites whatever hash would have been there.
Afterwards, it compares this newly created hash with the correct hash, which is located directly above. If the comparison goes well, and the two hashes are identical, then the signature is 100% legit.
If they don't match, then the signature is not legit, and the bootROM will refuse to load the NAND image. If you were to install any hacks in the NAND, then the calculated signature would change, and then the comparison would fail, and you would be forced to try to find another signature which, when decrypted, would give you this desired hash of a modified NAND, something which is pretty hard to do.
You'd have to brute-force a signature, which, when decrypted with the public key, would give the desired hash in the correct hash field.

The trick

Did you notice the big * that I put above?

"When the bootROM never reads a value, it completely skips it. This means that I can, for example, add a 5, so the parser will know the length of inner block data is 5, and it will skip 5 bytes (5 pairs of characters, 10 characters). Or I can type in 0f and it will skip exactly 15 bytes *. "

It's because it's here where we do the magic for sighax.

Think about this: You can move the pointer wherever you want thanks to the 0d value, and you also brute force a signature (given enough computational power) which when decrypted with the public key will give you your desired layout of all the bytes. What can we do with these two facts?

Well, what we can do is move the pointer at the start of the calculated hash. The bootROM will think that it has been pointed to the start of the correct hash, and it will skip an entire hash length, thinking that it will go to the start of the calculated hash. However, since it was pointed to the start of the calculated hash, it will skip a hash length and it will point outside of the entire signature.
Now, the bootROM will generate a new hash right there on the spot, and write that data in a region outside of the signature. Now, you have a new hash that has been written right after the calculated hash.

Normally, the bootROM would write this new hash in the calculated hash region, not this new region that's been invented outside of the signature. It would then compare this hash with the hash that's right above, and it would determine whether the signature is legit or not. However, since we made it so that it generates a new hash outside of the signature "block", we made it so that it compares this new region with the calculated hash region. And this comparison will always succeed, because the calculated hash region will contain the hash of the current state of the NAND header, and the region that's right below that (the one that's been invented) will contain the hash that's been generated right there on the spot.
The hash of the current state of the NAND header is the same hash as when you generate a new hash of the NAND header right there on the spot.

And this exactly is the ingenious trick behind sighax! This is how we can sign our own firmwares, and exactly this is how we can have a hack on coldboot!

So now that we can sign our own firmwares, we can install whatever hack we want to the NAND. We essentially can do whatever we want with our 3DS...


SO WE HAVE SIGHAX, NOW WHAT?

Now that we can sign our own firmwares, we can write anything to the NAND and it will always be accepted by the bootROM. And we are essentially finished!

Boot9strap is installed to the NAND with d0k3's SafeB9SInstaller, and with that we have a coldboot hack that is executed by the bootROM on cold boot. Boot9strap's overall goal is to load a boot.firm file from the SD card, and that boot.firm file can be whatever you want. CFW, a Nintendo FIRM, or even your own OS written from scratch.

However! Boot9strap is a lot more than just injecting the NAND with code that loads a custom firmware from the SD card and then signing it with the magic sighax signature. Boot9strap is a whole piece of work on its own, and it can dump the bootROM of your 3DS.
The details of what it does are out of the scope of this writeup, however I may look into writing another guide to explain it. The main take-away point is that it loads a boot.firm file from the SD card.


BUT WAIT, WHAT THE HECK IS NTRBOOT?

Ah, NTRBoot is a special case of installing CFW.

When Boot9Strap was first released and the bootROMs got dumped, people looked through the bootROM code and discovered something quite peculiar.

Whenever your 3DS turns on from cold boot, the bootROM checks to see if a special key combination is being held down, the START + SELECT + X + LID CLOSED combination. If it is checked and it is being held down, then the bootROM will try to boot from a DS cartridge, kinda like how your PC can boot from a DVD drive to install Windows. The catch though, is that the firmware that you will put on the DS cartridge must be signed as well. With sighax however we can just sign it easily.

This allows us to make a malicious DS cartridge that can give us code execution, and ARM9 code execution at that, giving us an incredibly powerful entrypoint into the 3DS, which is unpatchable on top of all that!


CONCLUSION


I hope that this writeup has made sense to you. There may be a number of mistakes, and I am doing my best to find them and fix them. I am also requesting that any developers reading this to correct me on the technical details, as my goal is not to spread misinformation.
If anyone reading this has any questions, please, send them to me.

Apart from that... thanks for reading! I hope that I have helped you gain a basic understanding of the 3DS.


Additional reading
Here you can find some additional information that did not necessarily fit in my writeup. However now that you have gained some basic knowledge of the 3DS, you can read some of the more technical explanations.

https://pastebin.com/Fq7F3j1V

Footnotes


1 NDS-Boostrap is essentially a piece of software that allows you to run DS games on your 3DS, straight from the SD card of your 3DS, without a DS flashcart. You can read more here and here. NDS-Bootstrap Loader is the actual software, while TWLoader is the interface that runs that code.
2 Basically, whenever your 3DS is going to play a GBA game, it doesn't run an emulator that's been designed by Nintendo, it loads AGB_FIRM, which, you can think of it as a virtualbox simulator, where you allocate some resources and then you run a piece of software in that simulated space, and that is what AGB_FIRM does.
3 As explained in the above note, TWL_FIRM works very similarly to AGB_FIRM, with the whole idea of a simulator.
4 SoC stands for System On (a) Chip. It is where all of the processing hardware for the 3DS is located at.
5 So, imagine a family tree: You have a grandfather, a father, and a son. The grandfather tells everyone what to do, both the father and the son. The parent tells only the son what to do, but not the grandfather, and the son can only listen, he doesn't have a say in anything. That is how a tree of privileges works. The ARM9 can tell everyone what to do, the ARM11 kernel can only tell the ARM11 userland, and the ARM11 userland can only control itself, he doesn't have a say in what happens to the ARM11 kernel and the ARM9.
6 Technically there is an ARM9 kernel, then the ARM9 userland. But because if you are in just the ARM9 userland you can do everything that the ARM9 kernel does, we combine them into one. It's one exception to the privilege rule
7 If you want a nice bite-sized explanation on digital signatures, watch this video from 3:29 to 6:36
8 When you have a computer, and you click "Shut down" in windows, it shut downs to a cold state, meaning that it doesn't use any power. So when we say cold shutdown, we aren't referring to a sleep mode, or hibernation, or a "soft restart" (In the 3DS hacking sense) where it shuts down some programs, then relaunches some others. No, we mean absolutely shutting down the 3DS by holding its power button until all the screens and LEDs are turned off, and it is "cold"
9 Technically it is just a dump of whatever machine code was in the bootROM, not the actual source code. However, you can disassemble the machine code into assembly, reverse engineer it, and then get the "source code".
10 Technically, in order to install a Legit CIA you only need ARM11 kernel access, since you can ask the ARM9 to install the Legit CIA for you from just the ARM11 kernel, and the ARM9 will gladly do it since it's a Legit CIA and its signature is accepted by the ARM9
11 Yes I know about the patch they tried to implement, but it failed miserably, that's why I'm not bringing it up. Read here.
12 The reason SAFE_MODE_FIRM never gets updated is because it is the safe mode of the 3DS. You know how Windows has its own safe mode, which you can boot into incase something goes horribly wrong? Logically you don't want to mess with this safe mode because it is there for emergencies, and you want to make sure it is always there. Same thing with the 3DS, you don't really want to update SAFE_MODE_FIRM because you want it always there in perfect working condition, and that is why it has old code that we can abuse.
13 To be correct about this, the 3DS' RAM doesn't get fully erased on shutdown. There's a huge bug that makes it so not all RAM is cleared on restart, so some memory still contains some data after a restart.
14 Gateway was a company which produced the first ever 3DS flashcart which could play 3DS backups. The fact that it was a flashcart did not mean that you didn't have to hack the 3DS. In fact, you had to do much of the same work that today's hacks do, because the backups that you loaded on the flashcart (As .3DS files) weren't signed and you had to patch out the signature checks, and therefore you needed to hack the ARM9.
15 The DS Profile Exploit (Which was only on version 4.0-4.5, and recently made to work with 6.0) was an old exploit, and pretty much the first exploit ever in the 3DS hacking scene that allowed us to takeover the ARM9.
16 A9LH (Which stands for Arm9Loaderhax) is an old hack, that was similar to Boot9Strap, it allowed us to load into the 3DS our own firmwares on coldboot, but in a method very different to Boot9Strap's. I will not go into details as it is now history.
17 A parser is the computer program that reads a piece of data and converts it to something that it can understand
18 I know the developers are most likely cringing and writing hate comments, but this isn't some university lecture. This is a post on an online forum trying to explain to people, in simple terms, what sighax is.
19 It's important to note that there is no DEP here, so we don't have to worry about using ROP.
20 Technically, only the N3DS has the arm9loader. The O3DS does not have the arm9loader at all
21 I may refer later on in the sighax explanation to "NAND" instead of "NAND header", but bear in mind that what's actually being signed and hashed is the NAND header, not the NAND itself
 
Last edited by MrJason005, , Reason: Add a new link to the pastebin

Blasingame

Well-Known Member
Member
Joined
Feb 1, 2009
Messages
139
Trophies
1
XP
1,290
Country
United States
The more you know!

In all seriousness this is a great write up. As someone who just followed the directions I'm glad to know this information about why we do what the 3DS.Guide tells us to do.

I hope to see this guide grows as more information and techniques are discovered.

Is it possible you will publish this guide will exist on another website?

Props for all the hard work in researching and glad there are footnotes!
 

senkunmusashi

@!#?@!?
Member
Joined
Nov 29, 2017
Messages
108
Trophies
0
XP
108
Country
Netherlands Antilles
I am mind blown! And I love how @MrJason005 wrote it, the balance of fine storytelling with just the right amount of technical information, not too dumbed down nor overwhelmingly dry, i actually understood the sheer amount of brilliance and tenacity the devs had to go through to get us here today. Now every time I boot the lil console up into gm9, I have a much greater appreciation for the effort that went into it.

Thank you for this great write up!
 

CrispyCola

zero-two
Member
Joined
Feb 8, 2017
Messages
320
Trophies
0
Location
the stars
XP
261
Country
United States
INTRODUCTION TO 3DS HACKING
"What the fuck am I doing when I follow 3ds.guide?"


The goal here is simple: To explain how the 3DS works behind the scenes.
Most people who hack their 3DS using 3ds.guide don't know what they are doing. We unfortunately have ended up with a big black magic box that's supposed to do all of our work for us, even when we are working in a system so complicated that even to make small modifications you will need to know a lot about its inner workings.
To quote yifan.lu:

I've seen countless posts here, in chatrooms, on reddit, and on many other forums where people blindly follow the instructions for installing the popular B9S/Luma combo on their 3DS, only to finish the guide, and just stare at their monitor thinking "Wow, I have no idea what I just did, but hey, it works, so, let's keep it".
I believe that people should know what they are doing, since it only benefits them in the end. There is no noob-friendly total complete package that explains everything fundamental about the 3DS, and I believe that simply pointing everyone to a lot of dev-speak that they cannot understand, is not the correct way to educate people and encourage them to learn more.

When you are finished reading this guide, you will have a basic understanding of how we actually hack the 3DS, and hopefully I will have answered a lot of questions that may be in your minds.
There are nearly zero pre-requisites needed for this guide, since I have tried to explain everything either through parenthesis or through foot-notes. However, if you have a decent amount of computer knowledge you would be many steps ahead.
The people who fall into this category are the people who can install Arch linux without issues on their computer. What I mean to say is that if you have questions in your mind along the lines of "What is FAT32?" or "What does 'cutoff' mean when someone says that a processor can only access a certain part of RAM?" or "What is a service?" or "What's a function in a program?" you aren't in this category. But this isn't bad! It just means that you may have to re-read some parts of the guide a few times to get the point I'm trying to make.

Also, if there is some part of the guide that doesn't make sense, then I am doing something wrong. Let me know and I'll look into fixing it up.

So, without further ado, let's get right to it.

3DS HARDWARE AND SOFTWARE
Hardware
Okay, to begin, let's talk about the hardware. The 3DS has two processors, one is the ARM11, and the other is the ARM9. Now, to be technically correct, there is also an ARM7 for better backwards compatibility with GBA and NDS games, but we're not going to go into too much detail because this isn't a thread about NDS-Bootstrap Loader1, or AGB_FIRM2
The ARM11 is the more powerful processor, and it is what handles running the actual 3DS games. So, whatever you see, the home menu, the web browser, games, all run on that processor.
The ARM9 is used heavily when you play a DS game on the 3DS using the DS backwards compatibility mode (Called TWL_FIRM3). However, in 3DS mode, the ARM9 is reused as a security processor.
The 3DS also has RAM (because it is essentially a computer), and it is split into a lot of different areas (FCRAM, AXI WRAM, ITCM, SoC memory, etc.), but it boils down to 3 parts: RAM that is only for the ARM9 processor, RAM that is shared between the two processors, and RAM that is for the ARM11.

Apart from the actual chips that are soldered on your 3DS motherboard that do the processing, we also have the power cycle of the 3DS, or more specifically, the bootROMs for each of the two processors.
Since the bootROMs are embedded in the actual die of the CPU, I will put this explanation here, in hardware.
"But Jason, what is a bootROM?" Good question. So, whenever you turn on your 3DS, your 3DS doesn't simply turn on. Instead, this happens20:
Code:
Power button --> ARM9 BootROM initialized --> Run some code --> Lockout the BootROM permanently (Until the next cold restart) --> Arm9loader --> Load the console-specific keys stored in the OTP region --> Lockout the OTP region permanently (Until the next cold restart) --> Load the Firmware (The actual "OS" of the 3DS)

What does all this mean?
Well, the bootROM is a very small portion of the processor in which some code is located, such that it is the very first thing that is initialized whenever you press the power button. In this case, the ARM9 bootROM is initialized first, and then the ARM11 is initialized later (of course by its own bootROM), but keep in mind that the ARM9 sends the command for the ARM11 to power on, not the power button.
As you may or may not know, ROM stands for Read Only Memory (R.O.M.). This means that whatever code is in that area, it is there for good, and cannot be modified by a firmware update, the only way is through a new hardware revision. The good thing about such a system is that it ensures that it is unhackable, since you cannot write your own hack to that region. The bad thing though, is that if you slip up and make a mistake and leave it in that unwritable area, you cannot fix it, and spoiler alert, Nintendo did slip up and leave an exploit for us in the bootROM.

Apart from the bootROM, you may have also read about the OTP region. The OTP region is a region in the SoC4 where the console-specific data is located at. From this console-specific data, you can generate keys which are going to be console-specific. These console-specific keys are important for decrypting many things on your 3DS, for example decrypting the NAND.
Lastly, you may have noticed that there is a "bootROM lockout" and "OTP lockout". What these mean is that, after the system accesses whatever it needs to access from those regions, it locks them out permanently until the next cold restart8. This is because there is very sensitive information in there (Things like various keys and the "source" code9, which we can search for exploits), and Nintendo didn't want people to mess around in that area.

There are a few more things implemented in the hardware that might interest us, like the AES and the RSA engine which are integrated in the ARM9 die (really important for signatures!), but apart from that, we don't really need to know more in order to understand how the 3DS security is actually breached.

Implementation & Software
So now that we know what's under the hood, let's see how it's all connected and programmed.
As you know, the ARM9 is used as a security processor. Specifically, whenever you try to run a game, encrypt or decrypt something, install anything with DevMenu, BigBlueMenu or FBI, the ARM9 makes sure that whatever you are trying to do is legit. Also important to note is that the ARM9 is the processor that actually reads and writes to the NAND (Essentially the hard drive of your 3DS). Now, all those capabilities have to be called from somewhere, we need to tell the system to execute those capabilities somehow (we call these capabilities "functions"), and the ARM11 does that. To be exact, the ARM11 kernel.
Here's a diagram of how the the tree of privileges is implemented (credit goes to the 32c3 nintendo presentation):

RGQ9j5QMQ_uSvozWRfrTfg.png
At the top we have the ARM96 After that is the ARM11 kernel and the ARM11 itself.
Whatever application you run, be it games or anything else, run in the ARM11 userland (Userland, as in, that's where the user resides). The ARM11 kernel (Sometimes abbreviated to K11, as in, KERNEL11) is what has full rights over the entire ARM11 processor, and that includes the userland. The ARM11 is also what handles the actual installation process of CIAs, granted the ARM9 authorizes it first (It does so by checking the signature7), so, if a signature is checked to be legit, the installation/runtime is approved by the ARM9.

HACKING THE 3DS - GETTING ARM9 ACCESS
Now we get to the real meat of the story. So what exactly are we trying to do when we say "I'm going to hack my 3DS"? What do the hackers mean when they say "Breaching the 3DS security"?
What I need to say right now is that our end goal when trying to hack a 3DS is getting access to the ARM9. We want our 3DS to boot up automatically on coldboot to an environment where the ARM9 is hacked automatically. And to do that, we need NAND read/write access. What we are trying to do is, install Boot9Strap (I'll get to what it is later, for now, treat it as the files we need to copy over to the NAND so that we install the hack), and it requires the ability to read/write to the NAND. You know how when you try to install an application in windows using a .exe installer? That requires writing and reading to the hard drive. And same for the 3DS. When we need to install something10, we need to access to the 3DS' storage, the NAND.
In order to get NAND access, we need to take control of the ARM9, and as you already know, the ARM9 is the security processor, which means it has plenty of security features.
So, let's step back a bit and look at the bigger picture. We are trying to hack our 3DS, and we need to get NAND access to install Boot9Strap. We need to get ARM9 access in order to get access to the NAND, therefore, our goal is to hack the ARM9. But how do we hack the ARM9?

I will now explain, from start to finish, how Soundhax works, which is one of the most popular ways of hacking 3DSes (I explain NTRBoot later on...)

First of all, Soundhax is just the userland exploit. You can't really do much in userland, if your end goal is to install boot9strap. Our end goal is to get ARM9 access. And good news, there is an ARM9 exploit, it's called safehax!

Safehax is actually an old exploit from 2013.
The old exploit, called firmlaunch-hax, took advantage of the fact that during a FIRM launch, the ARM9 would write some data to the RAM shared between the ARM11 and the ARM9, and it wouldn't expect the ARM11 to do anything to that portion of RAM. We of course abused this and, with the ARM11 kernel access we had, we would write whatever we wanted to that portion of RAM, and the ARM9 would execute it without noticing that that region of RAM was overwritten with a hack payload. And we got our ARM9 code execution.
But what is a FIRM launch? To understand this, you first have to understand how the 3DS firmware is split up.
You see, the 3DS' firmware is split into 3 parts, those are NATIVE_FIRM, TWL_FIRM and AGB_FIRM.
Whenever you play a DS/DSi game, TWL_FIRM is loaded. Whenever you play a GBA game through GBA Virtual Console, AGB_FIRM is loaded. Whenever you are doing anything else, NATIVE_FIRM is loaded.
A FIRM launch is essentially changing from one FIRM to another (e.g. you go from NATIVE_FIRM to TWL_FIRM), and during a FIRM launch, the ARM9 is vulnerable to firmlaunch-hax.
The important thing here is that the 3DS has a special mode, called SAFE_MODE_FIRM, in which you can boot into. And this mode almost never gets updated12, so it should have very old exploits. And that is exactly the case. The catch though, is that you need ARM11 kernel access.
Therefore, if we can somehow get ARM11 kernel access, we can reboot into this SAFE_MODE_FIRM, and have access to old code, and exploit it! And that is what we do11.
For a more detailed explanation, refer to Swiftloke's safehax explanation.

So now we just learned that safehax requires K11 access, and we are in luck, because there is an exploit that can give us K11, it's called udsploit.
udsploit works by a curious hardware flaw of the 3DS.
The 3DS' GPU has access to a certain part of RAM (because a graphics card needs memory). However, the GPU is wired up to much more more memory than it should be wired up to. It is connected to the entire 3DS' memory in fact.
When you have a userland exploit, you have entire access to the GPU (because games use the GPU to draw graphics on the screen), and with access to the GPU, you can "render" (really we are copying not rendering) data to the GPU's RAM, which in this case, is also main memory. Once you copy over data to the main memory with the GPU, the ARM11 kernel will get this code and it will run it, because it stills thinks it's running whatever piece of software it was running before. This exploit of getting the GPU to render to the main memory is called GSPWN (From the system module GSP)
For example, if you had a copy of Ocarina of Time 3D, and you used the userland exploit in that, the 3DS wouldn't know that you are in the homebrew launcher, it would still think that you are playing OoT. And if the 3DS gets a request from the GPU to "render" something, it will obey since it thinks it's running an innocent OoT game19.

If you are in the homebrew launcher, this means that you were able to get userland code execution. In order to elevate from userland to K11 you will have to use the GSPWN exploit.
However, the GSPWN exploit was sort of fixed with a special register. The GSPWN exploit is essentially a hardware exploit (since if you wire up the GPU to the RAM then it is an unfixable exploit), BUT, you can program the 3DS so that it only allows a certain part of memory to be used by the GPU. It is set by a special register in a configuration, and you cannot change this register from userland.
There is way of configuring this register though. The 3DS' WiFi module has access to this register, and by using our userland access to use the WiFi module, we could reset this config register and then the GPU would have entire access to the memory. Once we have entire access to the memory, we can do whatever we want with the ARM11 kernel and write whatever code we want to the memory so that it gets executed by the ARM11 kernel. And this exactly is the reason why you need to have the WiFi enabled, it's so that you can set this register that allows you to do the GSPWN exploit!

And now the last step we need to achieve is to get a userland exploit, which is easy, we got soundhax for that. Now, I won't get too technical about this, but the general idea is that we achieve a buffer overflow with .M4A header format.

One last thing to say here is that the exploits are actually executed backwards, we first get userland, then we get K11, then we get ARM9. This is how it's done in 3ds.guide as well, it first instructs you to execute soundhax, then through the homebrew launcher you can execute udsploit, then we execute safehax.

WHY THE 3DS NEEDS TO BE HACKED ON EVERY RESTART - THE NEED FOR A COLD BOOT EXPLOIT
So now that we have taken over the ARM9 and we can execute whatever code we want there, we essentially can do whatever we want with the 3DS. We can patch out signature checking, we can do custom modifications to the system, essentially what most people want out of a CFW.
Here's the issue though, every time we reboot the 3DS, all of our work gets erased (because RAM gets cleared on shutdown13), so every time we shutdown and boot up the 3DS, we need to go through this process again of soundhax-->udsploit-->safehax, and it can get a bit annoying.
This is how Gateway14 or rxTools was back in the day. Every time you shutdown your 3DS, you had to execute the old DS Profile exploit15, and it would get annoying sometimes.
But why can't we make it so that the 3DS get hacked on bootup?
Let's get back to the bootROM we talked about earlier. See, the bootROM is programmed to only load genuine firmwares (Firmware = Operating System of the 3DS), so even if we got ARM9 access, all that we can do is simply patch whatever we already have, what is already loaded by the 3DS. We cannot load whatever firmware we want, because the bootROM will refuse to load it as it is not signed by Nintendo, and even if we have ARM9 access, we cannot do anything to change the fact that the bootROM will only load genuine firmwares, as it is read only.

What the 3DS hacking scene was trying to do is find a way to load unauthorized firmwares right from bootup, and it took us until Derrek announced at 33c3 this thing called sighax, which allows us to sign our own firmwares, essentially allowing us to load whatever we want in the 3DS without ever needing to go through the hacking process. If we never had Boot9Strap (or A9LH16 for that matter), every time you would want to run a unsigned game you would have to run the 3 hacks in a row and go through a lot of time in order to get code execution.

So now, the big question in everyone's mind is "What is Boot9Strap?". Everyone refers to it as the hack you need to install, but, what does that even mean?
Well to explain it entirely, we need to explain how digital signatures actually work.

RSA DIGITAL SIGNATURES
The basics
RSA Stands for Rivest Shamir Adleman (The three people that invented it). It is an asymmetric cryptographic algorithm, which means that we can encrypt something with a public key, but only decrypt it with a private key, or the other way around, we can encrypt something with a private key, and only decrypt it with the public key.
The public key and the private key are mathematically connected. The reason why you cannot retrieve the private key from the public key, is because you would need to factor a very large (617+ digits long!) number into two prime numbers (See Fundamental theorem of arithmetic), something which is very difficult to do with traditional computers, and the only way we can achieve such a feat in a reasonable amount of time is by using quantum computers.



A hashing algorithm is basically a function, in which you give it some data, and it spits out some gibberish. The reason why this is useful is because:

  • If you enter the same thing in this function, you will always get the same gibberish
  • No two inputs give the same gibberish
  • You cannot reverse the output to get the input, it is impossible
The algorithm which we use for hashing is SHA-2, the 256 bit version of SHA-2 to be exact.



The simple way of signing
If you want to sign something, the following things are done:
  1. First, you take the piece of data and hash it (So that if you have a huge piece of data you want to sign, you can just hash it and get a unique hash which is essentially the same as the piece of of data)
  2. Then, you take your private key and encrypt that hash
  3. The encrypted hash is now the signature
  4. Once the recipient receives your letter, he hashes the message
  5. The recipient decrypts the signature with your public key and gets the decrypted hash
If the hash he produced from your message matches the encrypted hash you sent him (which he decrypted using your public key), we are 100% sure that the piece of data was signed by you, because only you have the secret key.
If someone wants to forge a signature, he must obtain your private key in some way shape or form, and use it to encrypt the hash of whatever he wants to send, or he can also try to brute force a perfect signature which when decrypted using the public key will give a desired hash. There is no other way to forge your signature, unless... you don't implement the RSA algorithm properly.

See, when a computer program goes and reads a signature, it actually reads this:

RXgXCwlNQHeQ2-55nD3r4g.png
That above, is an actual RSA signature. We generate it by taking the piece of data we want to sign (In this case, the 3DS' NAND header), hashing it, and encrypting it.
You may notice however, all these "ffffffff" that are taking up the majority of the space here. These "fffffff" are called padding, and the reason why we use padding is quite simple.

See, in the end, a signature is just a number. In order to encrypt something, we do the following exponential operation:

CQoczPqYRJGsQNhc16sc1A.png
Where c is the data you want to encrypt, d is the private key and n is the public key (the product of the two primes)
If you remember, there is this following property of exponentials:
vCwGCbOOQ6W3xnyg3tWHiA.png
From these 2 facts, we can create our own encrypted messages without knowing the private key. For example, if you have an encrypted message A:

sHf3FZGvQjO9s8enfc16kw.png
And also, another encrypted message B:
yc5K0yJATyqjTDXtj7-uyA.png
Then you can find what AB is equal to:

AFjomIX2Q4CkBRdBK741Bw.png
And be sure that AB will be regarded as a legitimately encrypted message, since the match checks out.

This is a big problem for our signature! What can we do?
Well, we... could add some gibberish in the signature, making it so that the signatures can't be fabricated with the math trick above. And this exactly, is called padding.
We add some gibberish (in this case, the "fffffff"s sprinkled in), and this bypasses the big problem we had. Problem solved!

Now, you don't need to know the nitty-gritty details about all of this, but in order to understand the ingenious trick behind sighax (I'll get to what it is in a bit), you need to understand a few basic things.
First of all, the signature is read from left to right, top to bottom. We have a pointer that is similar to the pointer you get when you type something on a computer

f01a6b4c-153c-4348-bac1-e5c30ceae7f1
giphy.gif
Now this cursor, goes, from left to right, top to bottom as I have said. For example, here is the signature block I posted being parsed:

giphy.gif


What happens here, is the parser 17 reads every single byte (a byte in this context meaning a pair of characters, so we start with the 00 and we continue on to 01 and ff etc.) one by one18. And as the parser goes along, it reads every single byte and checks it to see if it is a correct one or not (Don't worry, I'll explain in a bit)


SIGHAX EXPLAINED

So what is sighax? Good question!
Sighax is a bootROM exploit that allows us to sign our own firmwares. But how does this exploit work? How is it even possible? Aren't signatures encrypted with the private key and decrypted with the public key?
Well, we're going to go through this step by step, so stick to me and it will make sense.

How a signature is parsed:

Let's start by looking at the signature with which the NAND is signed:

RXgXCwlNQHeQ2-55nD3r4g.png
Whenever you turn on the 3DS, the bootROM has to make sure that the signature is indeed legit. It does this by parsing the signature byte by byte.
First of all, it reads this 00 at the start. This declares that we are about to start a signature.
After that, it finds this 01 value. This value, called padding type, declares whether padding will exist in this signature or not, 01 meaning "Padding will follow" and 02 meaning "Padding will not follow".
If you read the math spoiler above, you would know that this should always be set to 01, since this increases the security of signatures dramatically. But... Nintendo, for whatever reason, decided to allow us to just use the 02 value if we want, and the bootROM has no objections to that.

Already we have a major problem! You should never allow people to write signatures without padding, as you can brute force signatures a LOT easier!
We don't know why Nintendo did this, but the fact of the matter is this: You can disable padding in signatures.
Now, OK, this is... very big indeed. But still, a signature is a signature. The fact that you can skip a padding scheme may help in brute forcing a signature, but it doesn't magically erase the fact that a brute force effort must take place (If you want to brute force a signature).
So, let's move on:

If you set this byte to 01 you will make the bootROM check all of that padding, and make sure it is all "fffff". If you don't, it will just skip along. In both cases however the bootROM will keep reading until it finds this 00 byte at the end. Once it finds this 00 byte, it says "OK, I parsed all of the padding, now we will continue on to the other important bits"

The next few bytes aren't really that important for us. The 30 byte must always be set to 30, and it does some minor thing. The 31 is completely ignored (Nintendo ¯\_(ツ)_/¯ ), and this other 30 must always be set to a value of 30.
After that, we get to the good stuff.
This 0d value (in lime green) is the most important value in the entire signature, and I'll tell you why:

This 0d value, tells the parser how long the next value is going to be (The washed-out lime color, 060960...). But here's something funny: The parser completely skips this next value!
This value that follows the 0d is called inner block data, and it is supposed to tell the parser which type of hashing algorithm was used. We all know we are using SHA256, and the bootROM expects the signature to use this hashing algorithm for the hashing process, and the bootROM never reads this value!
When the bootROM never reads a value, it completely skips it. This means that I can, for example, add a 5, so the parser will know the length of inner block data is 5, and it will skip 5 bytes (5 pairs of characters, 10 characters). Or I can type 0f and it will skip exactly 15 bytes *. Note that this value can only be written as hexadecimal, i.e in 0x00 form (Numbers in base 16).
Here's what the parser does when it sees this value:

Firstly, it comes to the byte which declares how many bytes the next value is going to be:
giphy.gif

Then, it reads this value. In this case, 0d in hexadecimal means 13 in base 10. This means that we will skip 13 bytes, or 26 characters (Since a byte is a pair of two characters)
giphy.gif

Then it does the skipping process...
giphy.gif

And it continues on normally the parsing process.


If however, you were to modify this value: Instead of 0d you modified this to, for example 0f, you would skip 15 bytes instead of 13. So in total 30 characters:

giphy.gif

OK, so we can skip any number of bytes we want, essentially moving the pointer to whatever point we want. This is cool and all... but we don't have a use for it (...yet).
Let's just finish explaining the parsing process before we move on to sighax and its skipping trick.

We left off at parsing inner block size and inner block data, so naturally, we continue on parsing normally.
After that follows a 04 and 20 that tell the parser some information, but the parser skips these values as well.

Now finally we get to the finishing part of the signature, and this is the hash. As you already know, the fundamental idea behind a signature is a hash comparison.
You have one hash which you encrypt (Called the correct hash), and one hash which you calculate on the spot (called the calculated hash), and if those two hashes match, then the signature is legit.

After the final 20 byte is the correct hash.
What the bootROM does when it gets to this part, is it jumps ahead to the next hash, which is the calculated hash.
Once the pointer is at the start of the calculated hash, the bootROM hashes the NAND i.e. it generates a new hash right there on the spot, then it overwrites whatever hash would have been there.
Afterwards, it compares this newly created hash with the correct hash, which is located directly above. If the comparison goes well, and the two hashes are identical, then the signature is 100% legit.
If they don't match, then the signature is not legit, and the bootROM will refuse to load the NAND image. If you were to install any hacks in the NAND, then the calculated signature would change, and then the comparison would fail, and you would be forced to try to find another signature which, when decrypted, would give you this desired hash of a modified NAND, something which is pretty hard to do.
You'd have to brute-force a signature, which, when decrypted with the public key, would give the desired hash in the correct hash field.

The trick

Did you notice the big * that I put above?

"When the bootROM never reads a value, it completely skips it. This means that I can, for example, add a 5, so the parser will know the length of inner block data is 5, and it will skip 5 bytes (5 pairs of characters, 10 characters). Or I can type in 0f and it will skip exactly 15 bytes *. "

It's because it's here where we do the magic for sighax.

Think about this: You can move the pointer wherever you want thanks to the 0d value, and you also brute force a signature (given enough computational power) which when decrypted with the public key will give you your desired layout of all the bytes. What can we do with these two facts?

Well, what we can do is shift the signature, so that the correct hash is in the location for the calculated hash, thereby making it so that the calculated hash and correct hash overlap. Now, why would this be useful?

We can change the 0d value so that the pointer is moved right at the start of the calculated hash, which also happens to be the start of the correct hash (since the two hashes now overlap). Now, when the bootROM goes ahead and does its overwrite procedure for generating the hash (for the comparison), it will overwrite not only the calculated hash but also the correct hash.

So now, when it overwrites the calculated/correct hash with the newly generated hash (which it does on boot), it will compare the calculated hash with the correct hash.
However! Since the calculated hash and the correct hash are in the same location, it would just compare this block to.... itself... right? And this will always... succeed...
And this exactly is the ingenious trick behind sighax! This is how we can sign our own firmwares, and exactly this is how we can have a hack on coldboot!

So now that we can sign our own firmwares, we can install whatever hack we want to the NAND. We essentially can do whatever we want with our 3DS.


SO WE HAVE SIGHAX, NOW WHAT?

Now that we can sign our own firmwares, we can write anything to the NAND and it will always be accepted by the bootROM. And we are essentially finished!

Boot9strap is installed to the NAND with d0k3's SafeB9SInstaller, and with that we have a coldboot hack that is executed by the bootROM on cold boot. Boot9strap's overall goal is to load a boot.firm file from the SD card, and that boot.firm file can be whatever you want. CFW, a Nintendo FIRM, or even your own OS written from scratch.

However! Boot9strap is a lot more than just injecting the NAND with code that loads a custom firmware from the SD card and then signing it with the magic sighax signature. Boot9strap is a whole piece of work on its own, and it can dump the bootROM of your 3DS.
The details of what it does are out of the scope of this writeup, however I may look into writing another guide to explain it. The main take-away point is that it loads a boot.firm file from the SD card.


BUT WAIT, WHAT THE HECK IS NTRBOOT?

Ah, NTRBoot is a special case of installing CFW.

When Boot9Strap was first released and the bootROMs got dumped, people looked through the bootROM code and discovered something quite peculiar.

Whenever your 3DS turns on from cold boot, the bootROM checks to see if a special key combination is being held down, the START + SELECT + X + LID CLOSED combination. If it is checked and it is being held down, then the bootROM will try to boot from a DS cartridge, kinda like how your PC can boot from a DVD drive to install Windows. The catch though, is that the firmware that you will put on the DS cartridge must be signed as well. With sighax however we can just sign it easily.

This allows us to make a malicious DS cartridge that can give us code execution, and ARM9 code execution at that, giving us an incredibly powerful entrypoint into the 3DS, which is unpatchable on top of all that!


CONCLUSION


I hope that this writeup has made sense to you. There may be a number of mistakes, and I am doing my best to find them and fix them. I am also requesting that any developers reading this to correct me on the technical details, as my goal is not to spread misinformation.
If anyone reading this has any questions, please, send them to me.

Apart from that... thanks for reading! I hope that I have helped you gain a basic understanding of the 3DS.


Additional reading
Here you can find some additional information that did not necessarily fit in my writeup. However now that you have gained some basic knowledge of the 3DS, you can read some of the more technical explanations.

https://pastebin.com/Fw1SnmPD

Footnotes


1 NDS-Boostrap is essentially a piece of software that allows you to run DS games on your 3DS, straight from the SD card of your 3DS, without a DS flashcart. You can read more here and here. NDS-Bootstrap Loader is the actual software, while TWLoader is the interface that runs that code.
2 Basically, whenever your 3DS is going to play a GBA game, it doesn't run an emulator that's been designed by Nintendo, it loads AGB_FIRM, which, you can think of it as a virtualbox simulator, where you allocate some resources and then you run a piece of software in that simulated space, and that is what AGB_FIRM does.
3 As explained in the above note, TWL_FIRM works very similarly to AGB_FIRM, with the whole idea of a simulator.
4 SoC stands for System On (a) Chip. It is where all of the processing hardware for the 3DS is located at.
5 So, imagine a family tree: You have a grandfather, a father, and a son. The grandfather tells everyone what to do, both the father and the son. The parent tells only the son what to do, but not the grandfather, and the son can only listen, he doesn't have a say in anything. That is how a tree of privileges works. The ARM9 can tell everyone what to do, the ARM11 kernel can only tell the ARM11 userland, and the ARM11 userland can only control itself, he doesn't have a say in what happens to the ARM11 kernel and the ARM9.
6 Technically there is an ARM9 kernel, then the ARM9 userland. But because if you are in just the ARM9 userland you can do everything that the ARM9 kernel does, we combine them into one. It's one exception to the privilege rule
7 If you want a nice bite-sized explanation on digital signatures, watch this video from 3:29 to 6:36
8 When you have a computer, and you click "Shut down" in windows, it shut downs to a cold state, meaning that it doesn't use any power. So when we say cold shutdown, we aren't referring to a sleep mode, or hibernation, or a "soft restart" (In the 3DS hacking sense) where it shuts down some programs, then relaunches some others. No, we mean absolutely shutting down the 3DS by holding its power button until all the screens and LEDs are turned off, and it is "cold"
9 Technically it is just a dump of whatever machine code was in the bootROM, not the actual source code. However, you can disassemble the machine code into assembly, reverse engineer it, and then get the "source code".
10 Technically, in order to install a Legit CIA you only need ARM11 kernel access, since you can ask the ARM9 to install the Legit CIA for you from just the ARM11 kernel, and the ARM9 will gladly do it since it's a Legit CIA and its signature is accepted by the ARM9
11 Yes I know about the patch they tried to implement, but it failed miserably, that's why I'm not bringing it up. Read here.
12 The reason SAFE_MODE_FIRM never gets updated is because it is the safe mode of the 3DS. You know how Windows has its own safe mode, which you can boot into incase something goes horribly wrong? Logically you don't want to mess with this safe mode because it is there for emergencies, and you want to make sure it is always there. Same thing with the 3DS, you don't really want to update SAFE_MODE_FIRM because you want it always there in perfect working condition, and that is why it has old code that we can abuse.
13 To be correct about this, the 3DS' RAM doesn't get fully erased on shutdown. There's a huge bug that makes it so not all RAM is cleared on restart, so some memory still contains some data after a restart.
14 Gateway was a company which produced the first ever 3DS flashcart which could play 3DS backups. The fact that it was a flashcart did not mean that you didn't have to hack the 3DS. In fact, you had to do much of the same work that today's hacks do, because the backups that you loaded on the flashcart (As .3DS files) weren't signed and you had to patch out the signature checks, and therefore you needed to hack the ARM9.
15 The DS Profile Exploit (Which was only on version 4.0-4.5, and recently made to work with 6.0) was an old exploit, and pretty much the first exploit ever in the 3DS hacking scene that allowed us to takeover the ARM9.
16 A9LH (Which stands for Arm9Loaderhax) is an old hack, that was similar to Boot9Strap, it allowed us to load into the 3DS our own firmwares on coldboot, but in a method very different to Boot9Strap's. I will not go into details as it is now history.
17 A parser is the computer program that reads a piece of data and converts it to something that it can understand
18 I know the developers are most likely cringing and writing hate comments, but this isn't some university lecture. This is a post on an online forum trying to explain to people, in simple terms, what sighax is.
19 It's important to note that there is no DEP here, so we don't have to worry about using ROP.
20 Technically, only the N3DS has the arm9loader. The O3DS does not have the arm9loader at all

"introduction" to 3ds hacking
tbh this is a really cool thread tho
 

GosuSan

Member
Newcomer
Joined
Jan 23, 2018
Messages
5
Trophies
0
Age
33
XP
65
Country
Germany
I actually registered here because of 2 reasons only:
1. To say thanks for this awesome, easy to understand and very well written insight into this topic.
2. To get more informed / involved in the hacking scene of 3DS because I bought one recently.

So just a big thanks from someone that enjoys actually knowing what he does when hacking a console!
 
  • Like
Reactions: MrJason005

StrifeSephiroth

New Member
Newbie
Joined
Jul 7, 2018
Messages
4
Trophies
0
Age
43
XP
164
Country
Dominican Republic
It's been great how you've explained the concepts behind what it means to hack a 3DS.
Previously I had read a bit about the subject of cryptography. The explanations you have given have only increased my interest.
It took me a couple of hours to read everything carefully and "understand" (English is not my first language). I think that with a second reading I will be able to better assimilate the concepts presented.
 

hoodhippo

Well-Known Member
Newcomer
Joined
Jul 20, 2018
Messages
45
Trophies
0
Website
www.sciencedaily.com
XP
134
Country
United States
holy shit man.. thank you so much for this. everyone that hacks the 3ds should be required to learn this. a greater appreciation would be found than "i just downloaded some stuff and pressed some buttons and i hacked it" lol
 

MegaGenesis

Well-Known Member
Member
Joined
Jul 29, 2018
Messages
133
Trophies
0
Age
27
XP
480
Country
Brazil
Man, its amazing how much Homebrew Devs must crack and learn about a console and its system in order to fully unlock it, for many times we take for granted these hacks and just use them, never caring how much attention was put into developing it. Also, cool to discover my 3DS have GBA tech aside from the the GBA BIOS. Makes me think if Nint was planing the GBA Virtual Console for everyone on eShop, but droped the idea to making it into a Ambassador Exclusive.
 

Punkonjunk

Well-Known Member
Newcomer
Joined
Dec 28, 2011
Messages
57
Trophies
1
XP
203
This is an extremely comprehensive write-up with an excellent low to mid level tech understanding approach that I really enjoyed reading!

I was simply curious how far 3ds hacking had come, and this not only answered all my curiosity, but gave me a great breakdown of the history and culmination of exploits I was aware of with exploits that are new to me, and how they resulted in really amazing leaps forward for the 3ds!

One minor nitpick - a hash is a lot more like a fingerprint, that's the comparison I've commonly used - while you can use a hash to identify the source, you cannot use the hash to rebuild the source without the source, nor can you identify the source without at least some access to it - a lot like a fingerprint versus a fingerprint database. You can identify a criminal with his fingerprint, if his fingerprint is in whichever database you have access to - but without having it in the database, it's not useful in finding the criminal at all.

Just my two cents. Someone might have a better metaphor, but your explanation makes a hash sound more like compression, rather than cryptographic identification/validation.

That said though, this writeup was still amazing and very satisfying to read!
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • BigOnYa @ BigOnYa:
    @K3Nv2 What is nps you mentioned?
  • K3Nv2 @ K3Nv2:
    Because your pc has a hamster innit
    +3
  • BakerMan @ BakerMan:
    R.I.P. LittleBigPlanet PS3 servers
  • BakerMan @ BakerMan:
    LBP2 still the goat tho
  • K3Nv2 @ K3Nv2:
    That can be played on ps5 iirc
  • BigOnYa @ BigOnYa:
    I'm surprised any PS3 servers are still up, tbh
  • K3Nv2 @ K3Nv2:
    Alot of manufactures do care about older consoles they just want to whine about piracy
    +2
  • S @ salazarcosplay:
    @BigOnYa I had 4.89 hfw on super slim that was great, but when I got a new hard disk I forgot where the guide was and could only find a guide for 4.90 and its resources
  • S @ salazarcosplay:
    @BigOnYa I think another reason to want to update is if the hfw is at the level of the fw
  • S @ salazarcosplay:
    you can sync trophies
  • BigOnYa @ BigOnYa:
    Yea that's what I'm sitting on now- 4.9, and it seems fine, have had no issues at all
  • S @ salazarcosplay:
    I don't know if people play online or such
  • K3Nv2 @ K3Nv2:
    My ps3 short circuited during a deep clean still salty about it after downloading 2tbs worth but SteamDeck okay with emulation still just can't run mgs4 worth shit
  • BigOnYa @ BigOnYa:
    Yea forgot bout trophies. They just silly to me. Just like the xbox achievements. Hey, to each they own tho.
  • K3Nv2 @ K3Nv2:
    It keeps players in touch with the game like a check list of things to do after they beat it
  • S @ salazarcosplay:
    @BigOnYa they ruined the gaming experience for me to be honest
  • S @ salazarcosplay:
    @BigOnYa Im not crazy about getting all of them, i feel like I have something to show for for the time put in
  • S @ salazarcosplay:
    @BigOnYa If you want to do rgh or 360 mod
  • S @ salazarcosplay:
    does it matter if you update your 360 or not before trying is it advisable or not
  • BigOnYa @ BigOnYa:
    Yea I don't pay attention to them really. Or do I try to 100% a game. I just play till story ends/ or I get the girl!
  • K3Nv2 @ K3Nv2:
    Bigonya uses his wiener to mod 360s
    +1
  • Xdqwerty @ Xdqwerty:
    Going to the water park, see ya
  • BigOnYa @ BigOnYa:
    You should update the 360 to newest dash before RGHing it yes. But not a big deal if you don't, you can install new dash/avatar updates after. It's just easier to do it auto online before, instead manual offline after.
  • BigOnYa @ BigOnYa:
    Have fun @Xdqwerty. If you see a chocolate candy bar floating in the water, don't eat it!
  • AncientBoi @ AncientBoi:
    :O:ohnoes: Y didn't U Tell ME that ALSO? @BigOnYa :ohnoes: 🤢🤮
    AncientBoi @ AncientBoi: :O:ohnoes: Y didn't U Tell ME that ALSO? @BigOnYa :ohnoes: 🤢🤮