Once the client has associated to a host, it needs to get data from the host. Nintendo are using three “flows” (not IEEE802.11 channels.) for this, defined by sending to 03:09:bf:00:00:xx (Note! Not 00:09:bf!).
For xx,
Each stage seems to get a packet of each, in that order.
Each packet starts with:
The first byte of the payload indicates the type in some way.
Type 0×01:
Type 0×11:
Type 0×11′s payload is followed by a tail
while type 0×01′s is not.
xx is usually 00, other values have been seen in the Data 00 and Go! packets.
The cmds are (in order seen):
Length is always 0×75
After the cmd, 32-bit words as follows: (Examples from Polarium)
HDR
*(volatile uint32 *)0×027FFE24 = 0×02004000;)
ARM9
ARM7
Following 172 bytes are ignored by a flashme’d NDS.
This leaves us with 136 bytes @0×3e in the packet, which is the signature of the above. It’s the data that gets tacked onto the end of a signed .nds file (at the point which the NDS headers claim is the end of file)
9 sets of (Total 36 bytes)
Interestingly, most of the information is duplicated in the header, which is presumably where WiFiMe was able to work (by changing the start addresses that are used rather than the ones that are checked) and by enforcing the check in the newer BIOS, newer NDSs aren’t WiFiMeable. This of course didn’t work, I can’t WiFiMe yet. Changing only the NDS header did nothing, chaning the signature white-screens me.
There’s an .NDS signing tool around somewhere, and hopefully it’s open source and in the DevKitARM CVS, so the rest of this information’s source ought to be workoutable.
The NDS file is actually sent in three parts:
Each chunk is preceeded by
It does not appear to send the filename table, the FAT, or the ICON data. So far, both overlays have been 0′d.
The ICON data can be reconstructed (except the first 32 bytes) from the beacons, as detailed on the Wireless Multi-Boot Host Association page, except a given beacon contains only one language’s data. ^_^
Uh… Yuck. A few counterexamples, otherwise the first byte is length in words
Seen first bytes:
Starts with 04 81
Next byte is stage:
0: Nothing happening
7: Dunno what this is… Next byte cycles 01 02 03 04 00, and once you see
00 you’re ready to go on and send the RSA signature.
8: RSA signature received make with the data packets
9: Data packet received (next uint16 is next packet wanted, then count packets received)
a: Full image received.
b: Go! command received.
A little-endian 32-bit value less than 0×100… No idea, my flashme’d NDS happily accepted the same number over and over again, as well as a rand() value.
Here’s a little program I knocked up that’ll take a pcap file, and output an NDS and set of beacon payloads (suitable for feeding into dumpinfo.pl) as well as the entire RSA packet from cmd 3. A WMB pcap file supplied to me by someone on IRC (Sorry, I forgot your handle. Remind me if you see this please?) rebuilds the Polarium USA Demo distributed by Firefly, except for four random bytes between the arm7 space and the arm9 space, and the stuff after the arm9 space. I think those four random bytes are a mistake in the assembly of the .nds file, myself.
The packet dump I have been supplied has four garbage bytes at the end of each captured packet. This whackiness appears to be in the capture software. I don’t get it in my own captures, but it shows up in captures of both WMB.exe and the E3 WMB setup. It might be the FCS getting caught by the capturer, but ethereal doesn’t pick it up as such.
capread.c (Updated to output .rsa as expected by beacontest-dotrsa)
Here’s a modified version, that rebases the timecode of the packets to 0 when it sees the dataflow start. This was me trying to work out why my DS gave up after four seconds.
datacmp.c (Updated to output .rsa as expected by beacontest-dotrsa)