Line 84:
Line 84:
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ...
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ...
|}
|}
+
+
=== Key and IV ===
+
+
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;"
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #cdc;" | '''Start'''
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccd;" | '''End'''
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccc;" | '''Length'''
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dcc;" | '''Description'''
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0bff
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x0c0e
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x0010
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Encrypted title key (decrypt using the master key)
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0c1c
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x0c23
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x0008
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | First 8 bytes of IV for title key decryption (last 8 bytes are zero)
+
|}
+
+
Note: this is probably part of the TMD/ticket/whatever. I'm throwing the offsets here for now, since this is arguably the most important part for extraction purposes.
+
+
=== File Table ===
+
+
WAD files contain a number of "files" in them. The number of files can be obtained from the halfword (2 bytes) at 0xede. The table itself starts at 0xee4, and it is composed of a number of file entries:
+
+
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;"
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #cdc;" | '''Start'''
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccd;" | '''End'''
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccc;" | '''Length'''
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dcc;" | '''Description'''
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x00
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x03
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x04
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | File number / ID
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x04
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x05
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x02
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | First 2 bytes of IV to decrypt contents (last 14 bytes are zero)
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x06
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x07
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x02
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Flags ?
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x08
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x0B
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x04
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Padding (zero)
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0C
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x0F
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x04
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | File size
+
|- style="background-color: #ddd;"
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x10
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x24
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x14
+
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | SHA-1 sum of decrypted file
+
|}
+
+
The files are located after the file table, with their starts aligned to a 64 byte boundary. To read a file, skip bytes until the next 64 byte boundary (unless already at one), read the ''File size'' bytes rounded to the next 16 bytes (the AES block size), decrypt using AES (using the title key and the IV in the file table entry plus 14 zero bytes), and take filesize bytes from the result to create the output file. The SHA-1 sum of this should match the one in the file table.