view · edit · attach · print · history

Wireless Multi-Boot Data Flow

1. Background

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,

  • 00 is the main data flow, host to client
  • 10 is the feedback flow, client to host
  • 03 is the feedback feeback flow, host to client

Each stage seems to get a packet of each, in that order.

2.  Main data flow

Each packet starts with:

  • 06
  • 01
  • 02 (except the last packet where it was 00)
  • 00
  • payload length, in 16-bit words.

The first byte of the payload indicates the type in some way.

Type 0×01:

  • 01
  • 00
  • first four bytes of previously sent payload. I dunno why…

Type 0×11:

  • 11
  • Cmd
  • Stuff (See Cmd below)

Type 0×11′s payload is followed by a tail

  • xx 02 00

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):

  • 01 (Sync)
  • 03 RSA signature
  • 04 NDS Data
  • 05 Go!

2.1  01 Sync

  • 0×00
  • 0×00
  • 0×00
  • 0×00

2.2  03 RSA signature transmission

Length is always 0×75

After the cmd, 32-bit words as follows: (Examples from Polarium)

  • 50 08 00 02 ARM9 EXE
  • 00 00 38 02 ARM7 EXE
  • 00 00 00 00
    HDR
  • 00 fe 7f 02 0×27ffe00
  • 00 fe 7f 02 HDR CPY (Passthrough notes that during a PassMe, the ARM9 is in a loop in the header data, which can be freed with *(volatile uint32 *)0×027FFE24 = 0×02004000;)
  • 60 01 00 00 Header LEN
  • 00 00 00 00
    ARM9 
  • 00 00 00 02
  • 00 00 00 02 ARM9 CPY
  • dc 85 11 00 ARM9 LEN
  • 00 00 00 00
    ARM7
  • 00 00 2c 02
  • 00 00 38 02 ARM7 CPY
  • 80 72 02 00 ARM7 LEN
  • 01 00 00 00

 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)

  • 00 00 00 00

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.

2.3  04 NDS file transmission

The NDS file is actually sent in three parts:

  • 0×160 bytes of NDS header.
  • The arm9 code, length and offset are in the header
  • The arm7 code, length and offset are in the header

Each chunk is preceeded by

  • mystery uint16_t
  • uint16_t chunk number. Header is 0, ARM9 starts at 1, ARM7 starts whereever ARM9 leaves off.

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. ^_^

3.  Feedback flow

Uh… Yuck. A few counterexamples, otherwise the first byte is length in words

Seen first bytes:

  • 00
  • 02
  • 04
  • 06
  • 07
  • 10

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.

4.  Feedback Feedback flow

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.

5.  Pulling it together

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)

view · edit · attach · print · history
Page last modified on December 17, 2005, at 07:30 PM