Wii Channels and savegames can (almost everytime, some exeptions) be stored on SD cards inserted into the Wii through the front SD slot. They are stored in the directory /private/wii/title/ on the card and consist of a single .bin-file. Channels are stored in files called content.bin while savegames are stored in data.bin files. Each Wii channel and game have a unique four letter ID. data.bin and content.bin are stored in subdirectories named after the game's or program's ID. Renaming the directory will make the Wii not recognize the file anymore. Some games like Virtual Console titles can have both a content.bin and a data.bin.
Looking at the bin-files reveals that they are structured in 64 byte segments. There is for example plaintext information about the certificate used to encrypt and decrypt the file stored in the content bin which is artificially padded by leading and trailing blocks of 64 zero bytes (0x00) and the ASCII strings are also padded with zeros to reach the 64 byte block size.
See the content.bin file format page for detailed discussion of this format.
Each bin file starts with a header which can be decrypted successfully by every Wii console, since the icon, banner, title and description of the game are all readable in the Wii SD card menu, even if the file was not originally created on this Wii or is even from the same region. The header is broken into 64 byte segments and its last block is followed by a block with the first four bytes 0x00000070 being followed by the four bytes 0x426B0001. The next four bytes are the Wii ID of the specific console this file was created on stored in binary. Further information in the header includes the size of the following data and later the ID of the program in plaintext ASCII. The more colorful the icon of the file the bigger the header will be, strongly indicating an image compression of some sort.
The data is encrypted and little can be said about its plaintext. At the end of the data two certificates are described, each one referring to the unique Wii ID thus making it plausible that the data is encrypted with a secret key only known to ones own Wii. A checksum of some sort might be the last piece of information stored in the penultimate block which is then followed by a last 64 byte block of zeros.
WiiLi contain additional discussion about the data format.
Copying a bin file to the Wii
A content.bin or data.bin file with a well-formed header will appear in the Wii's data manager on the SD card displaying it's icon and name and description if clicked upon. If a savegame or channel is not already present in the Wii's internal memory the bin-file can be encrypted and copied successfully.
Copying files from one Wii to the other
When copying a file that was created on another Wii the copying will fail with a corresponding message.
"Data was not copied."
Changing anything in the data (not the header, see below) will cause the copying to end with this message. Deleting or adding bytes at the end of the file will also yield this message. A checksum seems to check the integrity of the whole file or at least the data segment, since even changing something in the obviously useless and uninterpreted 64 byte zero segments or in the dead space beyond the plaintext strings in the certificate information will cause the copy process to fail with this message.
The White "?" Box
Every manipulation of the bin-file's header will cause the channel or savegame to appear as a white box with a black question mark inside it in the Wii's SD card manager. The file can still be examined but the name and description are filled with question marks also. Interestingly the file will still appear fine even if all blocks beyond the header are deleted. Only one byte needs to follow the isolated header, possibly to prevent the last byte of the header to be the end of file also. The value of the one byte is of no importance.
File does not appear at all
The file will not appear when its directory is renamed. Combined with the last statement this might mean that the Wii checks only the headers first and either the directoy's name is stored in the header in encrypted form or it is part of the key that is used by the Wii to decrypt the header.
These are the details of the Content.bin file structure.
VC games and Wii channels, when saved to a SD card, will be stored in a file named "private/wii/title/XXXX/content.bin", where XXXX is the four-character name of the game/channel.
The general layout of this file is as follows. Most of the data here is sketchy, at best.
|0x0640||Part A: Encrypted header|
|variable, padded to 64-byte boundary||Part B: Encrypted icon|
|0x70, padded to 64-byte boundary||Part C: Cleartext "Bk" header|
|0x1E4 + num_contents*0x24, padded to 64-byte boundary||Part D: Cleartext TMD block, including content_records for the following files|
|num_contents*variable, padded to 64-byte boundary||Part E: Encrypted data contents|
|0x340||Part F: Cleartext certificates|
Part A: Encrypted header
The header is encrypted by the SD key and SD IV. When decrypted, it contains the following structure: (* means the field is discussed below)
|0x000||0x007||8||Title ID (which is 00 01 00 01 followed by the four-character code)|
|0x008||0x00B||4||Size of part B|
|0x00C||0x01B||16||MD5 Hash of header|
|0x01C||0x02B||16||MD5 Hash of decrypted icon|
|The part below is identical to the start of opening.bnr|
|0x080||0x09B||28||* IMET data|
|0x09C||0x0EF||42*2||Channel name in UTF-16BE (Japanse version -- can be empty).|
|0x0F0||0x143||42*2||Channel name in UTF-16BE (English version).|
|0x144||0x197||42*2||Channel name in UTF-16BE (German version).|
|0x198||0x1EB||42*2||Channel name in UTF-16BE (French version).|
|0x1EC||0x23F||42*2||Channel name in UTF-16BE (Spanish version).|
|0x240||0x293||42*2||Channel name in UTF-16BE (Italian version).|
|0x294||0x2E7||42*2||Channel name in UTF-16BE (Dutch version).|
|0x2E8||0x63F||0x358||* Padding (normally zero)|
This value looks almost like the four-letter code of a channel/game. I have found HADP on most files, but HAGP on Super Mario/NES and '\0UPD' (that is, the first byte is 00, then UPD) on two N64-games.
- Title-ID-reference_1 and Title-ID-reference_2
These two looks like two Title-ID:s. On most files I have analyzed they are: 00 01 00 08 HALP and 00 01 00 08 HAKP (this is from a PAL Wii). However, on Super Mario/NES I found 00 01 00 02 HAFP and 00 01 00 02 HAGA. A guess is that they might stipulate some kind of dependencies on system files. (HALx and HAKx correspond to the EULA and Region Select Channels where x is the region code.)
If the guess about depencencies is correct, then this might be a padding field which is zero only if not more than two dependencies are needed.
- IMET data
The IMET data follows a quite strict format, with a few changes between files. I don't have any good idea what those changes represent. The only major difference is found i Metroid Prime 3 Preview, which have everyting zero except the "IMET" header. The values indicated below is for all other files I've studied, which was non-zero.
|0x000||0x003||4||IMET header "IMET"|
|0x004||0x00B||8||Fixed value, always 00 00 06 00 00 00 00 03.|
|0x00C||0x017||12||Three 32-bit numbers (sizes?), typically in the range of 0x84BC to 0x56318.|
|0x018||0x01B||4||Flags? This is normally just zero, but Everybody Votes has 0050 0000 and Mii Contest has 0060 4100.|
- Padding (normally zero)
For Metroid Prime 3 Preview, this field was not completely zero. The three bytes with positions 0x313, 0x367 and 0x3BB was 0x20 instead of 0. My guess is that this doesn't matter, but then again, it could have something to do with the weird IMET data of MP3preview.
Part B: Encrypted icon
Part C: Cleartext "Bk" header
This part is not encrypted. It is similar to the Bk header found in savegames, but the contents only partially match. The header could also be exactly 0x80 long; the size of 0x70 is a guess based on the first field being a size parameter.
|0x000||0x003||4||Size of this part (presumably; always 0x70)|
|0x004||0x007||4||Magic word, always 0x42 0x6B 0x00 0x01 (Bk..)|
|0x014||0x017||4||Size of TMD|
|0x018||0x01B||4||Size of included contents|
|0x01C||0x01F||4||Size of content.bin, not including part A nor part B. ECC signature is calculated from PART C on.|
|0x020||0x05F||0x40||Included contents. (We believed shared contents were never included, and that is indeed reflected here, but if they were to be included, it would show up here.)|
Part D: Cleartext TMD block
This part is not encrypted. It is well described on the TMD file format page. Some things to note:
- Only the tmd struct is included here, not the certificates.
- As described on the TMD file format page, after the main struct (with a size of 0x1E4), there follows an array of content_record structs.
- There is as many structs as the num_contents field in the tmd struct indicates. For VC, this seems to be always 7.
- The type and size file of the content_record is of special interest, since they describe part E.
- Contents included are described in the content inclusion field of the "Bk" header. Shared contents are usually never included, but if they are, that will be indicated in the "Bk" header.
Part E: Encrypted data contents
This part is encrypted. The encryption key is the PRNG seed, extracted with xyzzy, with an IV of the 2 byte content index, followed by 14 0x00's. This key is unique to the Wii that created content.bin It consists of several separate "files", one for each of the contents with the 0x0001 type flag in the TMD content_record, padded to 64-byte boundary.
Part F: Cleartext certificates
This part is not encrypted. This data is an ECC signature, generated by the Wii at content.bin's creation time. Attached to the signature, is the ECC public key to verify the signature, and a certificate signed by Nintendo's private key, to assure that we didn't just make up the ECC key ourselves.