Difference between revisions of "Savegame Files"

From WiiBrew
Jump to navigation Jump to search
(Added footer info)
 
(17 intermediate revisions by 10 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 [[#Footer|footer]]. 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 ===
+
== Footer ==
 +
The footer is mainly used for encryption.
 +
{| class="wikitable"
 +
|-
 +
! Start
 +
! End
 +
! Length
 +
! Description
 +
|-
 +
| 0x000
 +
| 0x03C
 +
| 60
 +
| Unknown
 +
|-
 +
| 0x03D
 +
| 0x040
 +
| 4
 +
| Unknown
 +
|-
 +
| 0x041
 +
| 0x238
 +
| 504
 +
| NG certificate
 +
|-
 +
| 0x239
 +
| 0x270
 +
| 56
 +
| Padding
 +
|-
 +
| 0x271
 +
| 0x275
 +
| 4
 +
| Unknown
 +
|-
 +
| 0x276
 +
| 0x46E
 +
| 504
 +
| AP certificate
 +
|}
 +
 
 +
== See Also ==
 +
 
 +
* [[FE100]]
 +
* [[Wii Savegame Parser]]
  
Savegames can be parsed with the [[Wii_Savegame_Parser|savegame parser]]
+
[[Category:File formats]]

Latest revision as of 22:49, 20 July 2021

Format

A savegame consists of a Header, followed by a Bk Header and a set of files contained in a files section, and finally a footer. The savgames are signed while being copied to the SD card using the Wii's private NG key.

Header

The Header is 0xF0C0 bytes long. It is encrypted (AES128-CBC) using the "sd-key" and the "sd-iv" initialization vector.

The plaintext header contents are described in the following table.

It's divided in two parts: The "main header" and the "banner"

Main header

Start End Length Description
0x0000 0x0007 8 Savegame ID
0x0008 0x000B 4 size of banner (0x72A0 or 0xF0A0, also seen 0xBAA0)
0x000C 0x000C 1 permissions
0x000D 0x000D 1 ?? unknown
0x000E 0x001D 16 md5 of plaintext header with md5 blanker applied
0x001E 0x001F 2 ?? unknown


Start End Length Description
0x0020 0x0023 4 magic ('WIBN') (Wii Banner?)
0x0024 0x0027 4 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.
0x0028 0x002A 2 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.
0x002B 0x003F 22 Reserved
0x0040 0x007F 64 Game title (big endian Unicode)
0x0080 0x00BF 64 Game subtitle (big endian Unicode)
0x00C0 0x60BF 24576 banner (192x64) - RGB5A3 GX texture format
0x60C0 0x72BF 4608 icon0 (48x48) - RGB5A3 GX texture format
0x72C0 0x84BF 4608 icon1 (optional, present if size of header is 0xF0C0)
0x84C0 0x96BF 4608 icon2 (optional, present if size of header is 0xF0C0)
0x96C0 0xA8BF 4608 icon3 (optional, present if size of header is 0xF0C0)
0xA8C0 0xBABF 4608 icon4 (optional, present if size of header is 0xF0C0)
0xBAC0 0xCCBF 4608 icon5 (optional, present if size of header is 0xF0C0)
0xCCC0 0xDEBF 4608 icon6 (optional, present if size of header is 0xF0C0)
0xDEC0 0xF0BF 4608 icon7 (optional, present if size of header is 0xF0C0)

Bk ("BacKup") Header

The Bk Header is 0x70 bytes long (plus 0x10 bytes of padding/aligning). It is not encrypted.

Start End Length Description
0x000 0x003 4 Size of the header (0x00000070)
0x004 0x005 2 magic ('Bk')
0x006 0x007 2 magic2 or version (0x0001)
0x008 0x00B 4 NG id
0x00C 0x00F 4 number of files
0x010 0x013 4 size of files
0x014 0x017 4 ?? unknown
0x018 0x01B 4 ?? unknown
0x01C 0x01F 4 total size
0x020 0x05F 64 ?? unknown
0x060 0x063 4 ?? unknown
0x064 0x067 4 Game ID (ex. 'RMGP' for Super Mario Galaxy)
0x068 0x06D 6 Mac address of the wii
0x06E 0x06F 2 ?? unknown
0x070 0x07F 16 null padded

Files

A savegame consists of several files up to the number specified in the Bk Header. Each file is described using a File Header and a File Data section. Files are stored immediately after the Bk Header using the format described in the next sections.

File Header

The file header is 0x80 bytes long. It is not encrypted.

Start End Length Description
0x000 0x003 4 magic1 (0x03adf17e)
0x004 0x007 4 size of file
0x008 0x008 1 permissions
0x009 0x009 1 attributes
0x00A 0x00A 1 type (1=file, 2=directory)
0x00B variable variable name (null terminated)
... ... ... ...
0x050 0x05F 16 IV for file data decryption
0x060 0x07F ... ?? unknown

File Data

File data comes after the 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.

Footer

The footer is mainly used for encryption.

Start End Length Description
0x000 0x03C 60 Unknown
0x03D 0x040 4 Unknown
0x041 0x238 504 NG certificate
0x239 0x270 56 Padding
0x271 0x275 4 Unknown
0x276 0x46E 504 AP certificate

See Also