|
|
(20 intermediate revisions by 12 users not shown) |
Line 1: |
Line 1: |
− | (Feel free to fix or enhance this page)
| |
− |
| |
| = Format = | | = Format = |
| | | |
− | A savegame consists of a [[#Header|Header]], followed by a [[#Bk Header|Bk Header]] and a set of files contained in a [[#Files|files]] section. | + | A savegame consists of a [[#Header|Header]], followed by a [[#Bk Header|Bk Header]] and a set of files contained in a [[#Files|files]] section, and finally a [[Certificate chain|certificate chain]]. The savgames are signed while being copied to the SD card using the Wii's private NG key. |
| | | |
| == Header == | | == Header == |
Line 13: |
Line 11: |
| It's divided in two parts: The "main header" and the "banner" | | It's divided in two parts: The "main header" and the "banner" |
| | | |
− | <b><u>Main header</u></b>
| + | === Main header === |
− | {| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;" | + | {| class="wikitable" |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #cdc;" | '''Start'''
| + | ! Start |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccd;" | '''End'''
| + | ! End |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccc;" | '''Length'''
| + | ! Length |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dcc;" | '''Description'''
| + | ! Description |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0000
| + | | 0x0000 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x0007
| + | | 0x0007 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 8
| + | | 8 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Savegame ID
| + | | Savegame ID |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0008
| + | | 0x0008 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x000B
| + | | 0x000B |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | size of banner (0x72A0 or 0xF0A0)
| + | | size of banner (0x72A0 or 0xF0A0, also seen 0xBAA0) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x000C
| + | | 0x000C |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x000C
| + | | 0x000C |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
| + | | 1 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | permissions
| + | | permissions |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x000D
| + | | 0x000D |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x000D
| + | | 0x000D |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
| + | | 1 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown
| + | | ?? unknown |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x000E
| + | | 0x000E |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x001D
| + | | 0x001D |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 16
| + | | 16 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | md5 of plaintext header with md5 blanker applied
| + | | md5 of plaintext header with md5 blanker applied |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x001E
| + | | 0x001E |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x001F
| + | | 0x001F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 2
| + | | 2 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown
| + | | ?? unknown |
− | |- style="background-color: #ddd;"
| |
| |} | | |} |
| | | |
| | | |
− | <b><u>Banner</u></b>
| + | === Banner === |
− | {| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;" | + | {| class="wikitable" |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #cdc;" | '''Start'''
| + | ! Start |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccd;" | '''End'''
| + | ! End |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccc;" | '''Length'''
| + | ! Length |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dcc;" | '''Description'''
| + | ! Description |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0020
| + | | 0x0020 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x0023
| + | | 0x0023 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | magic ('WIBN') (Wii Banner?)
| + | | magic ('WIBN') (Wii Banner?) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0024
| + | | 0x0024 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x0027
| + | | 0x0027 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Reserved | + | | Flags - (Maskable) if set to 0x000001 the save cannot be copied from NAND via normal means, 0x000010 means to "Bounce" between 0 and the last frame. Setting it to 0x000000 makes the animation loop through all frames resetting to 0 on the final frame. |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0028
| + | | 0x0028 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x002B | + | | 0x002A |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4 | + | | 2 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Flags
| + | | AnimSpeed - Set per frame frameDelay*((animSpeed >> (2*nFrame))&3); 0 being no animation 1-3 being progressively slower, this is a little strange, but if the first two frames are set to 0, don't animate the icon. |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x002C | + | | 0x002B |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x003F
| + | | 0x003F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 20 | + | | 22 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Reserved
| + | | Reserved |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0040
| + | | 0x0040 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x007F
| + | | 0x007F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 64
| + | | 64 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Game title (big endian Unicode)
| + | | Game title (big endian Unicode) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0080
| + | | 0x0080 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x00BF
| + | | 0x00BF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 64
| + | | 64 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Game subtitle (big endian Unicode)
| + | | Game subtitle (big endian Unicode) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x00C0
| + | | 0x00C0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x60BF
| + | | 0x60BF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 24576
| + | | 24576 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | banner (192x64) - RGB5A3 GX texture format
| + | | banner (192x64) - RGB5A3 GX texture format |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x60C0
| + | | 0x60C0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x72BF
| + | | 0x72BF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4608
| + | | 4608 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | icon0 (48x48) - RGB5A3 GX texture format
| + | | icon0 (48x48) - RGB5A3 GX texture format |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x72C0
| + | | 0x72C0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x84BF
| + | | 0x84BF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4608
| + | | 4608 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | icon1 (optional, present if size of header is 0xF0C0)
| + | | icon1 (optional, present if size of header is 0xF0C0) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x84C0
| + | | 0x84C0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x96BF
| + | | 0x96BF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4608
| + | | 4608 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | icon2 (optional, present if size of header is 0xF0C0)
| + | | icon2 (optional, present if size of header is 0xF0C0) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x96C0
| + | | 0x96C0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0xA8BF
| + | | 0xA8BF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4608
| + | | 4608 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | icon3 (optional, present if size of header is 0xF0C0)
| + | | icon3 (optional, present if size of header is 0xF0C0) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0xA8C0
| + | | 0xA8C0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0xBABF
| + | | 0xBABF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4608
| + | | 4608 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | icon4 (optional, present if size of header is 0xF0C0)
| + | | icon4 (optional, present if size of header is 0xF0C0) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0xBAC0
| + | | 0xBAC0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0xCCBF
| + | | 0xCCBF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4608
| + | | 4608 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | icon5 (optional, present if size of header is 0xF0C0)
| + | | icon5 (optional, present if size of header is 0xF0C0) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0xCCC0
| + | | 0xCCC0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0xDEBF
| + | | 0xDEBF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4608
| + | | 4608 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | icon6 (optional, present if size of header is 0xF0C0)
| + | | icon6 (optional, present if size of header is 0xF0C0) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0xDEC0
| + | | 0xDEC0 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0xF0BF
| + | | 0xF0BF |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4608
| + | | 4608 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | icon7 (optional, present if size of header is 0xF0C0)
| + | | icon7 (optional, present if size of header is 0xF0C0) |
| |} | | |} |
| | | |
− | == Bk Header == | + | == Bk ("BacKup") Header == |
| | | |
| The Bk Header is 0x70 bytes long (plus 0x10 bytes of padding/aligning). It is not encrypted. | | The Bk Header is 0x70 bytes long (plus 0x10 bytes of padding/aligning). It is not encrypted. |
| | | |
− | {| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;" | + | {| class="wikitable" |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #cdc;" | '''Start'''
| + | ! Start |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccd;" | '''End'''
| + | ! End |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccc;" | '''Length'''
| + | ! Length |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dcc;" | '''Description'''
| + | ! Description |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x000
| + | | 0x000 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x003
| + | | 0x003 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Size of the header (0x00000070)
| + | | Size of the header (0x00000070) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x004
| + | | 0x004 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x005
| + | | 0x005 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 2
| + | | 2 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | magic ('Bk')
| + | | magic ('Bk') |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x006
| + | | 0x006 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x007
| + | | 0x007 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 2
| + | | 2 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | magic2 or version (0x0001)
| + | | magic2 or version (0x0001) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x008
| + | | 0x008 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x00B
| + | | 0x00B |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | NG id
| + | | NG id |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x00C
| + | | 0x00C |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x00F
| + | | 0x00F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | number of files
| + | | number of files |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x010
| + | | 0x010 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x013
| + | | 0x013 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | size of files
| + | | size of files |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x014
| + | | 0x014 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x017
| + | | 0x017 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown
| + | | ?? unknown |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x018
| + | | 0x018 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x01B
| + | | 0x01B |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown
| + | | ?? unknown |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x01C
| + | | 0x01C |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x01F
| + | | 0x01F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | total size
| + | | total size |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x020
| + | | 0x020 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x05F
| + | | 0x05F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 64
| + | | 64 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown
| + | | ?? unknown |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x060
| + | | 0x060 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x063
| + | | 0x063 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown
| + | | ?? unknown |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x064
| + | | 0x064 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x067
| + | | 0x067 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Game ID (ex. 'RMGP' for Super Mario Galaxy)
| + | | Game ID (ex. 'RMGP' for Super Mario Galaxy) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x068
| + | | 0x068 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x06B | + | | 0x06D |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4 | + | | 6 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown | + | | Mac address of the wii |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x06C | + | | 0x06E |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x06F
| + | | 0x06F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4 | + | | 2 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown
| + | | ?? unknown |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x070
| + | | 0x070 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x07F
| + | | 0x07F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 16
| + | | 16 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | null padded
| + | | null padded |
| |} | | |} |
| | | |
Line 234: |
Line 231: |
| The file header is 0x80 bytes long. It is not encrypted. | | The file header is 0x80 bytes long. It is not encrypted. |
| | | |
− | {| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;" | + | {| class="wikitable" |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #cdc;" | '''Start'''
| + | ! Start |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccd;" | '''End'''
| + | ! End |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ccc;" | '''Length'''
| + | ! Length |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dcc;" | '''Description'''
| + | ! Description |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x000
| + | | 0x000 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x003
| + | | 0x003 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | magic1 (0x03adf17e)
| + | | magic1 (0x03adf17e) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x004
| + | | 0x004 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x007
| + | | 0x007 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
| + | | 4 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | size of file
| + | | size of file |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x008
| + | | 0x008 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x008
| + | | 0x008 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
| + | | 1 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | permissions
| + | | permissions |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x009
| + | | 0x009 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x009
| + | | 0x009 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
| + | | 1 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | attributes
| + | | attributes |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x00A
| + | | 0x00A |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x00A
| + | | 0x00A |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
| + | | 1 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | type (1=file, 2=directory)
| + | | type (1=file, 2=directory) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x00B
| + | | 0x00B |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | variable
| + | | variable |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | variable
| + | | variable |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | name (null terminated)
| + | | name (null terminated) |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | ...
| + | | ... |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | ...
| + | | ... |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | ...
| + | | ... |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ...
| + | | ... |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x050
| + | | 0x050 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x05F
| + | | 0x05F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 16
| + | | 16 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | IV for file data decryption
| + | | IV for file data decryption |
− | |- style="background-color: #ddd;" | + | |- |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x060
| + | | 0x060 |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x07F
| + | | 0x07F |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | ...
| + | | ... |
− | | style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | ?? unknown
| + | | ?? unknown |
| |} | | |} |
| | | |
Line 291: |
Line 288: |
| File data comes after the [[#File Header|File Header]]. Each file actually occupies the length specified in the file header rounded up to the next 64 byte boundary. Data is encrypted (AES128-CBC) using the "sd-key" and the initialization vector specified in the File Header. | | File data comes after the [[#File Header|File Header]]. Each file actually occupies the length specified in the file header rounded up to the next 64 byte boundary. Data is encrypted (AES128-CBC) using the "sd-key" and the initialization vector specified in the File Header. |
| | | |
| + | === Parsing savegames === |
| + | |
| + | Savegames can be decrypted and unpacked with segher's tachtig and created with his twintig. |
| | | |
− | === Parsing savegames === | + | === Plaintext certificate chain area === |
| + | |
| + | For more information about each certificate layout, please refer to [[Certificate chain|this]] page. |
| + | |
| + | {| class="wikitable" |
| + | |- |
| + | ! Start |
| + | ! End |
| + | ! Length |
| + | ! Description |
| + | |- |
| + | | 0x000 |
| + | | 0x17F |
| + | | 0x180 |
| + | | Copy of the console-specific device certificate (also known as <code>NG</code> certificate), returned by [[:/dev/es|ES_GetDeviceCert]]. |
| + | |- |
| + | | 0x180 |
| + | | 0x2FF |
| + | | 0x180 |
| + | | Application-specific certificate (also known as <code>AP</code> certificate), dynamically generated during the <code>data.bin</code> file creation. |
| + | |} |
| + | |
| + | Both certificates hold a trimmed ECDSA signature and a trimmed 0x3C-byte long ECC public key. Both values must be padded with two leading <code>\x00</code> before each coordinate in order to be able to use them as part of crypto functions. |
| + | |
| + | The certificate name/identity from the <code>AP</code> certificate is always set to <code>AP0000000100000002</code>, because it's always generated by the System Menu. |
| + | |
| + | The ECC public key from the <code>AP</code> certificate is nothing more than an ECC shared secret generated using the random ECC private key from this very same certificate. |
| + | |
| + | Finally, the ECDSA signature from the <code>AP</code> certificate is issued by the <code>NG</code> certificate, using the console-specific ECC private key (stored inside the [[Hardware/OTP|OTP]]). |
| + | |
| + | == See Also == |
| + | |
| + | * [[FE100]] |
| + | * [[Wii Savegame Parser]] |
| | | |
− | Savegames can be parsed with the [[Wii_Savegame_Parser|savegame parser]]
| + | [[Category:File formats]] |