| #34923 posted 2016-08-09 @ 18:21 GMT |
Since the beginning of the 3DS hacking scene, Gateway provided probably, for the time, the best method (or uh, gateway) into modifying one’s 3DS. I’d dare say they probably were the sole reason homebrew existed at all for the public prior to 9.2 and the release of ninjhax. Following 9.2 and their Gateway 3.0 Ultra release, while having an initially successful release and userbase influx, eventually led to their downfall due to how easily their ARM11 and ARM9 kernel exploits were able to be reverse engineered (see yifanlu’s writeup about that here), as well as the nature of firmlaunchhax being that kernel access through it is extremely clean, and as a result FIRM modifications were easy to perform and relaunching a modified FIRM was trivial.
While Gateway used to be suggested for their ease of use and ease of piracy, a large portion of the 3DS development scene sees them now as a joke. They did, however, leave behind a very interesting piece of hardware: Their 3DS DRM cartridge used to load ROMs and protect their secrets. So how does it work?
Where to Look
Reversing Gateway’s own payload to figure out how their cartridge IO works can, without a wealth of tools and time, be extremely difficult. Older payloads are easier to reverse than newer ones, due to newer payloads constantly layering more and more obfuscation tactics on top of what already existed. However for a more clear picture of their cartridge init sequence, Supercard’s own freegame custom firmware yields an enticing opportunity to look into how the Gateway card init sequence functions.
To expand a bit on why looking at something Supercard created can assist with reversing Gateway’s own card, Supercard is a company which makes DS flash cartridges, the DSTwo being their most notable cartridge. It contains its own coprocessor for the NDS to use for GBA and SNES emulation as well as for media and other purposes. They later released another iteration, the Supercard DSTwo+ which sported a much more powerful processor, more memory, and the ability to emulate Gateway’s cart. With that ability, however, they initially opted to provide their cart as a stand-in replacement for Gateway’s card, effectively stealing all of their work on the 3DS firmware end. Gateway fired back by bricking users who were using DSTwo+ cartridges with their firmware, and as a result Supercard forked ReiNAND into freegame and made their own firmware. This isn’t the first time this has happened, however. Several clone carts existed when Gateway was originally starting up, and they were also met with the same fate.
Since their firmware is a fork of ReiNAND (released without source despite the GPL license I might add), reversing its functionality is fairly easy since you can diff ReiNAND against their code and figure out the differences. For now though, I’ll only be focusing on the gwcard init sequence.
The card init sequence starts the same as any normal CTR cartridge: Initialize NTR cart registers and initialize it as an NTR cartridge. The first step past this, however, is a very large SPI upload to the cartridge. With Supercard, a very large static buffer is fed over SPI, and after a few bytes being sent the cartridge begins to reply with its upper 5 bits yielding a 0xA0 return value. The entire upload appears to be a set of commands, and the commands differ slightly between what Supercard sends and what Gateway sends. It is possible that Supercard purposely designed their custom firmware to not work with Gateway cards, however that is an easy fix if it is the case.
Once the entire SPI blob is uploaded, a 0xA0 ntrcard command is sent to the card until it replies with 0x0 or exhausts a set number of attempts. It is possible for this to fail, I’ve found that depending on the situation it can take 4-5 cartridge resets, SPI blob reuploaded, and probing for life in the cart for it to work. Once its initialized it works fine, however.
Once the cart replies with 0 and alerts the 3DS that it is initialized, 128 ntrcard 0xBC commands are sent with the first request having argument 0xFFFFFFFF and the rest with argument 0x0. ntrcard and ctrcard command 0xBC changes the cartridge ID of the cart for Gateway cartridges.
After setting the cartridge ID 128 times, the cart finally transitions into 16 bit NTR mode and into CTR cartridge mode.
A Special Cartridge
Once in CTR cartridge mode, the Gateway cartridge largely functions like an actual cartridge, although it does a few things rather uniquely. Command 0xBF, normally used to read a block from the 3DS cartridge, will instead read a block from the Gateway SD card (hence why early Gateway versions required 3DS ROMs to be directly written to SD sectors). This effectively means that it is relatively simple to tie the Gateway cart into a fatfs implementation and read from the cartridge. Dealing with the cartridge init sequence in relation to fatfs can be a bit tricky with this since you need to sanity check Gateway carts vs 3DS carts, and probe for the status of the Gateway cartridge. In my own tests after implementation, I found that an SD card which would read at 152.6KB/s in the N3DS microSD slot would read at 110.5KB/s in the gwcard SD slot, which is honestly not too horrible.
The Gateway card also has some of its own commands. Earlier I mentioned command 0xBC which is used to change the cartridge ID, which is not implemented in retail cartridges (It might be in development ones though?), some other interesting cartridge commands include command 0x72 which can turn on the inbuilt RGB LED to any 24-bit color:
With this much research done, I thought it would be somewhat disappointing to see this piece of hardware go entirely unused. As such, I’m releasing some source files for the gwcard protocol and command set which can be used in public ARM9 payloads to experiment with the Gateway cartridge, and perhaps Supercard’s cartridge as well. It would also be interesting to look at differences between various clone cartridges in their behavior to see how Gateway managed to detect clone vs legitimate cartridge. Sky3DS cartridges allegedly pass Gateway’s SPI tests, so investigating this could possibly result in methods of detecting and blocking Sky3DS cartridges from future 3DS firmwares, if Nintendo still cares about that.
Source code to my gwcard protocol implementation can be found here. Assuming the implementation of NTRCARD and CTRCARD are in line, it should Just Work. Also includes the magic SPI blobs for both Gateway and Supercard in bin form.
_____________________________ ____________ __________________ /\________
\ __________________ \ _____/____/ _ \ /_ /
/ / | l/ _/ ____) _/ _ \ \/ cREAM /
/______________l_______/ \______________\_______| \_ /________/
-+--Mo!-------------- \________/ ------------------- l_______/_____\ -----+-