Difference between revisions of "Wii Disc"

From WiiBrew
Jump to navigation Jump to search
(changed the word "disc" to "partition" for the H3 table discussion)
m (Not software)
 
(31 intermediate revisions by 18 users not shown)
Line 1: Line 1:
 
This article describes the logical layout of data on a '''Wii disc'''.
 
This article describes the logical layout of data on a '''Wii disc'''.
  
== Disc Format ==
+
== "System Area" ==
 
   
 
   
{| 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: #ded;" | '''Start'''
+
! Start
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | '''Size'''
+
! Size
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | '''Name'''
+
! Name
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | '''Description'''
+
! Description
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x00000
+
| 0x00000
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1024
+
| 1024
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Header
+
| [[#Header|header]]
| 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;" | 0x40000
+
| 0x40000
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 48
+
| >=120
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Partitions information
+
| [[#Partitions information|Partitions information]]
| 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;" | 0x4E000
+
| 0x4E000
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 32
+
| 32
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Region setting
+
| [[#Region setting|Region setting]]
| 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;" | 0x4FFFC
+
| 0x4FFFC
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Magic (0xC3F81A8E)
+
| Magic (0xC3F81A8E)
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" |  
+
|  
 
|}
 
|}
 
   
 
   
Line 35: Line 35:
 
The first 0x400 bytes are like the GameCube disc header format.
 
The first 0x400 bytes are like the GameCube disc header format.
 
   
 
   
{| 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: #ded;" | '''Start'''
+
! Start
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | '''Size'''
+
! Size
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | '''Name'''
+
! Name
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | '''Typical Value'''
+
! Typical Value
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | '''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: #ddd;" | 1
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Disc ID
+
| Disc ID
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |  
+
|  
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | [[Wiidisc_IDs]]
+
| [[Wiidisc IDs]]
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x001
+
| 0x001
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 2
+
| 2
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Game code
+
| Game code
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |  
+
|  
| 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;" | 0x003
+
| 0x003
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Region code
+
| Region code
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |
+
|  
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | 'E' = USA | 'P' = PAL | 'J' = JAP | 'K' = KOR
+
| 'D' = German ; 'E' = USA ; 'F' = France ; 'I' = Italy ; 'J' = Japan ; 'K' = Korea ; 'P' = PAL ; 'R' = Russia ; 'S' = Spanish ; 'T' = Taiwan ; 'U' = Australia
|- 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: #ddd;" | 2
+
| 2
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Maker code
+
| Maker code
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |  
+
|  
| 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;" | 0x006
+
| 0x006
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Disc ID
+
| Disc number
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |
+
| 0x00
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" |
+
| Used in multi-disc games
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x007
+
| 0x007
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Disc version
+
| Disc version
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |  
+
|  
| 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;" | 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: #eed;" | Audio streaming
+
| Audio streaming
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |
+
| 0
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" |
+
| 0: Streaming disabled, nonzero: streaming enabled.  No Wii game uses streaming.{{check}}
|- 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: #ddd;" | 1
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Streaming buffer size
+
| Streaming buffer size
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |
+
| 0
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" |
+
| Buffer size for audio streaming, only used when streaming is enabled.  0 uses the default value, which is 10.
|- 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: #ddd;" | 14
+
| 14
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" |  
+
|  
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x00
+
| 0x00
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | unused?
+
| unused?
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x18
+
| 0x018
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Magicword
+
| Wii Magicword
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x5D1C9EA3
+
| 0x5D1C9EA3
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" |  
+
| Identifies Disc as Wii.  Present on Wii discs, zero on Gamecube discs.
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x020
+
| 0x01C
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 64
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Game title
+
| Gamecube Magicword
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |  
+
| 0xC2339F3D
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | though most docs claim it to be 0x400 the Wii only reads 0x44 which will be padded by the DI driver to 0x60
+
| Identifies Disc as Gamecube.  Present on Gamecube discs, zero on Wii discs.
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x060
+
| 0x020
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
+
| 64
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" |  
+
| Game title
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |  
+
|  
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Disable hash verification and make all disc reads fail even before they reach the DVD drive.
+
| though most docs claim it to be 0x400 the Wii only reads 0x44 which will be padded by the DI driver to 0x60
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x061
+
| 0x060
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" |  
+
|  
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" |  
+
|  
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Disable disc encryption and h3 hash table loading and verification (which effectively also makes all disc reads fail because the h2 hashes won't be able to verify against "something" that will be in the memory of the h3 hash table. none of these two bytes will allow unsigned code)
+
| Disable hash verification. On retail consoles, this makes all disc reads fail even before they reach the DVD drive.
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x080
+
| 0x061
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 380
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Padding
+
|  
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x00
+
|  
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" |  
+
| Disable disc encryption and h3 hash table loading and verification. On retail consoles, this effectively also makes all disc reads fail because the h2 hashes won't be able to verify against "something" that will be in the memory of the h3 hash table. None of these two bytes will allow unsigned code on retail consoles.
 +
|-
 +
| 0x080
 +
| 380
 +
| Padding
 +
| 0x00
 +
|  
 
|}
 
|}
+
 
 
=== Partitions information ===
 
=== Partitions information ===
 
   
 
   
 
The Wii disc format uses partitions, mostly one is used for updates (the 1st) and the 2nd for the game.
 
The Wii disc format uses partitions, mostly one is used for updates (the 1st) and the 2nd for the game.
 
   
 
   
{| 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: #ded;" | '''Start'''
+
! Start
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | '''Size'''
+
! Size
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | '''Description'''
+
! Description
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x40000
+
| 0x40000
| 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 partitions in the disc
+
| Total partitions in the disc
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x40004
+
| 0x40004
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Partition info table offset, Address is (value << 2)
+
| Partition info table offset, Address is (value << 2)
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x40008
+
| 0x40008
| 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 2nd partitions in the disc (optional)
+
| Total 2nd partitions in the disc (optional)
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x4000C
+
| 0x4000C
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Partition info table offset, Address is (value << 2)
+
| Partition info table offset, Address is (value << 2)
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x40010
+
| 0x40010
| 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 3rd partitions in the disc (optional)
+
| Total 3rd partitions in the disc (optional)
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x40014
+
| 0x40014
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Partition info table offset, Address is (value << 2)
+
| Partition info table offset, Address is (value << 2)
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x40018
+
| 0x40018
| 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 4th partitions in the disc (optional)
+
| Total 4th partitions in the disc (optional)
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x4001C
+
| 0x4001C
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Partition info table offset, Address is (value << 2)
+
| Partition info table offset, Address is (value << 2)
 
|}
 
|}
  
 
==== Partition table entry ====
 
==== Partition table entry ====
  
{| 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: #ded;" | '''Start'''
+
! Start
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | '''Size'''
+
! Size
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | '''Description'''
+
! Description
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x0
+
| 0x0
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Partition offset, Address is (value << 2)
+
| Partition offset, Address is (value << 2)
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x4
+
| 0x4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Partition type: 1 for an update partition, 0 otherwise.
+
| Type: 0 for a Data partition, 1 for an Update partition, 2 for a Channel installer. The demonstration VC titles on Super Smash Brothers Brawl use the Ascii title ID.
 
|}
 
|}
 
Each partition starts with a [[Ticket]] followed by the TMD followed by [[Certificate chain | three certifications]].
 
 
Offset 0x00000000 is considered as the start of the partition.
 
  
 
=== Region setting ===
 
=== Region setting ===
 
   
 
   
{| 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: #ded;" | '''Start'''
+
! Start
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | '''Size'''
+
! Size
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | '''Name'''
+
! Name
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | '''Description'''
+
! Description
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x4E000
+
| 0x4E000
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 4
+
| 4
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Region byte
+
| Region byte
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | 0 = JAP, 1 = USA, 2 = EUR, 4 = KOR
+
| 0 = JAP/CHT (Taiwan), 1 = USA, 2 = PAL, 4 = KOR
|- style="background-color: #ddd;"
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x4E010
+
| 0x4E004
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
+
| 12
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Region JAP byte
+
|
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Set to zero if 'Region byte' is set to 0
+
|-
|- style="background-color: #ddd;"
+
| 0x4E010
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x4E011
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
+
| Japan/Taiwan
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Region USA byte
+
| rowspan="2" | Age Rating byte. Indicates the Age Rating for a Wiidisc
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Set to zero if 'Region byte' is set to 1
+
|-
|- style="background-color: #ddd;"
+
| 0x4E011
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x4E014
+
| 1
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 1
+
| USA
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #eed;" | Region EUR byte
+
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | Set to zero if 'Region byte' is set to 2
+
| 0x4E012
 +
| 1
 +
|
 +
|-
 +
| 0x4E013
 +
| 1
 +
| Germany
 +
| rowspan="7" | Age Rating byte. Indicates the Age Rating for a Wiidisc
 +
|-
 +
| 0x4E014
 +
| 1
 +
| PEGI
 +
|-
 +
| 0x4E015
 +
| 1
 +
| Finland
 +
|-
 +
| 0x4E016
 +
| 1
 +
| Portugal
 +
|-
 +
| 0x4E017
 +
| 1
 +
| Britain
 +
|-
 +
| 0x4E018
 +
| 1
 +
| Australia
 +
|-
 +
| 0x4E019
 +
| 1
 +
| Korea
 +
|-
 +
| 0x4E01A
 +
| 6
 +
|
 
|}
 
|}
 +
 +
== Partition ==
 +
 +
Each partition starts with a [[Ticket]] followed by the TMD followed by [[Certificate chain|three certifications]].
 
   
 
   
Note : Blanking all 'Region JAP byte', 'Region USA byte' and 'Region EUR byte' will work too.
+
Offset 0x00000000 is considered as the start of the partition.
  
=== [[TMD]] and [[Certificate chain]] ===
+
The offset of the actual partition data is 0x00020000 for normal discs and 0x00008000 for unencrypted discs (discs where 0x61 in the header is non-zero).
 
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| '''Start'''
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;"| '''Size'''
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| '''Description'''
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x00000000
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>0x2A4</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| [[Ticket]]
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x000002A4
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>4</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| TMD size
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x000002A8
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>4</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| TMD offset >> 2
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x000002AC
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>4</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| Cert chain size
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x000002B0
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>4</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| Cert chain offset >> 2
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x000002B4
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>4</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| Offset to the H3 table >> 2 (size is always 0x18000)
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x000002B8
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>4</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| Data offset >> 2
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x000002BC
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>4</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| Data size >> 2
 
|- style="background-color: #ddd;"
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;"| 0x000002C0
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" align="center" | <tt>varies</tt>
 
|style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;"| [[TMD]]
 
  
 +
{| class="wikitable"
 +
! Start
 +
! Size
 +
! Description
 +
|-
 +
| 0x00000000
 +
| <tt>0x2A4</tt>
 +
| [[Ticket]]
 +
|-
 +
| 0x000002A4
 +
| <tt>4</tt>
 +
| TMD size
 +
|-
 +
| 0x000002A8
 +
| <tt>4</tt>
 +
| TMD offset >> 2
 +
|-
 +
| 0x000002AC
 +
| <tt>4</tt>
 +
| Cert chain size
 +
|-
 +
| 0x000002B0
 +
| <tt>4</tt>
 +
| Cert chain offset >> 2
 +
|-
 +
| 0x000002B4
 +
| <tt>4</tt>
 +
| Offset to the H3 table >> 2 (size is always 0x18000)
 +
|-
 +
| 0x000002B8
 +
| <tt>4</tt>
 +
| Data offset >> 2
 +
|-
 +
| 0x000002BC
 +
| <tt>4</tt>
 +
| Data size >> 2
 +
|-
 +
| 0x000002C0
 +
| <tt>varies</tt>
 +
| [[TMD]]
 +
|-
 +
| <tt>varies</tt>
 +
| <tt>varies</tt>
 +
| Partition Data
 
|}
 
|}
  
== Partition Data ==
+
=== Partition Data ===
  
Partition data is encrypted using a key, which can be obtained from the partition header and the master key. The actual partition data starts at offset 0x20000 in the partition, and it is formatted in "clusters" of size 0x8000 (32k). Each one of these blocks consists of 0x400 bytes of encrypted SHA-1 hash data, followed by 0x7C00 bytes of encrypted user data. The 0x400 bytes SHA-1 data is encrypted using AES-128-CBC, with the partition key and a null (all zeroes) IV. Clusters are aggregated into subgroups of 8 clusters, and 8 subgroups are aggregated into one group of 64 clusters. The plaintext format is as follows:
+
===== Encrypted =====
  
{| style="border-collapse: collapse; padding: 0.2em 0.2em 0.2em 0.2em;"
+
For discs where 0x61 in the disc header is non-zero, skip this section and go to [[#Decrypted]]. (Such discs don't work on retail consoles.)
|- style="background-color: #ddd;"
+
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | '''Start'''
+
Partition data is encrypted using a key, which can be obtained from the partition header and the master key. The actual partition data starts at an offset into the partition (normally 0x20000), and it is formatted in "clusters" of size 0x8000 (32k). Each one of these blocks consists of 0x400 bytes of encrypted SHA-1 hash data, followed by 0x7C00 bytes of encrypted user data. The 0x400 bytes SHA-1 data is encrypted using AES-128-CBC, with the partition key and a null (all zeroes) IV. Clusters are aggregated into subgroups of 8 clusters, and 8 subgroups are aggregated into one group of 64 clusters. The plaintext format is as follows:
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | '''End'''
+
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | '''Length'''
+
{| class="wikitable"
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | '''Description'''
+
|-
|- style="background-color: #ddd;"
+
! Start
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x000
+
! End
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x26B
+
! Length
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x26C
+
! Description
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | 31 SHA-1 hashes ("H0", 20 bytes each), one for each block of 0x400 bytes of the decrypted user data for this cluster.
+
|-
|- style="background-color: #ddd;"
+
| 0x000
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x26C
+
| 0x26B
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x27F
+
| 0x26C
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x014
+
| 31 SHA-1 hashes ("H0", 20 bytes each), one for each block of 0x400 bytes of the decrypted user data for this cluster.
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | 20 bytes of 0x00 padding
 
|- style="background-color: #ddd;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x280
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x31F
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x0A0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | 8 SHA-1 hashes ("H1"), one for each cluster in this subgroup. Each hash is of the 0x000-0x26B bytes, that is, of the 31 hashes above. This means that each cluster carries a hash of the data cluster hashes for each of the clusters in its subgroup. Every cluster in the subgroup has identical data in this section.
 
|- style="background-color: #ddd;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x320
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x33F
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x020
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | 32 bytes of 0x00 padding
 
|- style="background-color: #ddd;"
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x340
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x3DF
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x0A0
 
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | 8 SHA-1 hashes("H2"), one for each subgroup in this group. Each hash is of the 0x280-0x31F bytes above. This means that each cluster carries a hash of the subgroup hash data for each of the subgroups in its group. All 64 clusters in a group have identical data in this section. Bytes 0x3D0-0x3DF here, when encrypted, serve as the IV for the user data.
 
 
|-
 
|-
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ded;" | 0x3E0
+
| 0x26C
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #dde;" | 0x3FF
+
| 0x27F
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #ddd;" | 0x020
+
| 0x014
| style="border: 1px solid #ccc; padding: 0.2em; background-color: #edd;" | 32 bytes of 0x00 padding
+
| 20 bytes of 0x00 padding
 +
|-
 +
| 0x280
 +
| 0x31F
 +
| 0x0A0
 +
| 8 SHA-1 hashes ("H1"), one for each cluster in this subgroup. Each hash is of the 0x000-0x26B bytes, that is, of the 31 hashes above. This means that each cluster carries a hash of the data cluster hashes for each of the clusters in its subgroup. Every cluster in the subgroup has identical data in this section.
 +
|-
 +
| 0x320
 +
| 0x33F
 +
| 0x020
 +
| 32 bytes of 0x00 padding
 +
|-
 +
| 0x340
 +
| 0x3DF
 +
| 0x0A0
 +
| 8 SHA-1 hashes("H2"), one for each subgroup in this group. Each hash is of the 0x280-0x31F bytes above. This means that each cluster carries a hash of the subgroup hash data for each of the subgroups in its group. All 64 clusters in a group have identical data in this section. Bytes 0x3D0-0x3DF here, when encrypted, serve as the IV for the user data.
 +
|-
 +
| 0x3E0
 +
| 0x3FF
 +
| 0x020
 +
| 32 bytes of 0x00 padding
 
|}
 
|}
  
Line 319: Line 367:
 
Finally, the global hash table ("H3"; which the partition header points to) contains the SHA-1 hash of the last table of each group in the partition. This table is not encrypted, but it is signed. To build it, take bytes 0x340-0x3DF from any sector in each group in the partition, apply SHA-1, and simply store all of the resulting hashes consecutively. All in all, each sector includes enough information to trace itself back to the master SHA-1 hash table. As a result, the entire partition is effectively signed. If anything is changed, the Wii will immediately crash (if the master hash table has been updated), or it will crash when it reads any sector in the modified group (if the group tables have been updated), any sector in the modified subgroup (if the subgroup tables have been updated), or any modified sector if no SHA-1s were updated.
 
Finally, the global hash table ("H3"; which the partition header points to) contains the SHA-1 hash of the last table of each group in the partition. This table is not encrypted, but it is signed. To build it, take bytes 0x340-0x3DF from any sector in each group in the partition, apply SHA-1, and simply store all of the resulting hashes consecutively. All in all, each sector includes enough information to trace itself back to the master SHA-1 hash table. As a result, the entire partition is effectively signed. If anything is changed, the Wii will immediately crash (if the master hash table has been updated), or it will crash when it reads any sector in the modified group (if the group tables have been updated), any sector in the modified subgroup (if the subgroup tables have been updated), or any modified sector if no SHA-1s were updated.
  
The signature is stored in the [[Tmd_file_structure|TMD]]. The TMDs for the partition always have one content. The type of that content seems to be always 3, and the SHA1 hash is the SHA1 of the entire 0x18000 bytes of the hash table.
+
The signature is stored in the [[Tmd file structure|TMD]]. The TMDs for the partition always have one content. The type of that content seems to be always 3, and the SHA1 hash is the SHA1 of the entire 0x18000 bytes of the hash table.
The [[Tmd_file_structure|TMD]] is signed using Nintendo private key. That makes basically impossible to run modified discs. Trucha Signer uses the [[Signing_bug|signing bug]] to bypass the [[Tmd_file_structure|TMD]] signature checking, so the SHA1 hash of the master table can be updated, and modified discs can be booted.
+
The [[Tmd file structure|TMD]] is signed using Nintendo private key. That makes basically impossible to run modified discs. Trucha Signer uses the [[signing bug]] to bypass the [[Tmd file structure|TMD]] signature checking, so the SHA1 hash of the master table can be updated, and modified discs can be booted.
  
 
To decrypt the user data at 0x0400-0x7FFF, again use the partition key, but this time take the IV from bytes 0x3D0-0x3DF in the '''encrypted''' SHA-1 block.
 
To decrypt the user data at 0x0400-0x7FFF, again use the partition key, but this time take the IV from bytes 0x3D0-0x3DF in the '''encrypted''' SHA-1 block.
  
==Known Wii discs==
+
===== Decrypted =====
  
On the [[Title_Database|Title Database]] you can find some info about different game discs
+
Once the Partition Data is decrypted (or if it was stored unencrypted to begin with), it follows the same formatting as a Gamecube disc for the most part.
 +
 
 +
{| class="wikitable"
 +
|-
 +
! Start
 +
! Size
 +
! Description
 +
|-
 +
| 0x00000
 +
| 1024
 +
| Same format as the main disc header, except bytes 0x60 and 0x61 are set to 0x01.
 +
|-
 +
| 0x00420
 +
| 4
 +
| Pointer to the Main Dolphin, Address is (value << 2)
 +
|-
 +
| 0x00424
 +
| 4
 +
| Pointer to the File System start, Address is (value << 2)
 +
|-
 +
| 0x00428
 +
| 4
 +
| File System Size
 +
|-
 +
| 0x0042C
 +
| 4
 +
| Max File System Size
 +
|-
 +
| 0x02440
 +
| 4
 +
| Pointer to the App Loader
 +
|}
 +
 
 +
 
 +
== Known Wii discs ==
 +
 
 +
On the [[Title Database]] you can find some info about different game discs
  
 
== Methods to boot a disc ==
 
== Methods to boot a disc ==
Line 337: Line 421:
  
 
The [[Wii BootMe]] tool (created by CorteX) lets you change the way wii images boot.
 
The [[Wii BootMe]] tool (created by CorteX) lets you change the way wii images boot.
[[Category:Wii_Software]]
+
 
 +
[[Category:File formats]]

Latest revision as of 21:20, 22 March 2021

This article describes the logical layout of data on a Wii disc.

"System Area"

Start Size Name Description
0x00000 1024 header
0x40000 >=120 Partitions information
0x4E000 32 Region setting
0x4FFFC 4 Magic (0xC3F81A8E)

Header

The first 0x400 bytes are like the GameCube disc header format.

Start Size Name Typical Value Description
0x000 1 Disc ID Wiidisc IDs
0x001 2 Game code
0x003 1 Region code 'D' = German ; 'E' = USA ; 'F' = France ; 'I' = Italy ; 'J' = Japan ; 'K' = Korea ; 'P' = PAL ; 'R' = Russia ; 'S' = Spanish ; 'T' = Taiwan ; 'U' = Australia
0x004 2 Maker code
0x006 1 Disc number 0x00 Used in multi-disc games
0x007 1 Disc version
0x008 1 Audio streaming 0 0: Streaming disabled, nonzero: streaming enabled. No Wii game uses streaming.[check]
0x009 1 Streaming buffer size 0 Buffer size for audio streaming, only used when streaming is enabled. 0 uses the default value, which is 10.
0x00A 14 0x00 unused?
0x018 4 Wii Magicword 0x5D1C9EA3 Identifies Disc as Wii. Present on Wii discs, zero on Gamecube discs.
0x01C 4 Gamecube Magicword 0xC2339F3D Identifies Disc as Gamecube. Present on Gamecube discs, zero on Wii discs.
0x020 64 Game title though most docs claim it to be 0x400 the Wii only reads 0x44 which will be padded by the DI driver to 0x60
0x060 1 Disable hash verification. On retail consoles, this makes all disc reads fail even before they reach the DVD drive.
0x061 1 Disable disc encryption and h3 hash table loading and verification. On retail consoles, this effectively also makes all disc reads fail because the h2 hashes won't be able to verify against "something" that will be in the memory of the h3 hash table. None of these two bytes will allow unsigned code on retail consoles.
0x080 380 Padding 0x00

Partitions information

The Wii disc format uses partitions, mostly one is used for updates (the 1st) and the 2nd for the game.

Start Size Description
0x40000 4 Total partitions in the disc
0x40004 4 Partition info table offset, Address is (value << 2)
0x40008 4 Total 2nd partitions in the disc (optional)
0x4000C 4 Partition info table offset, Address is (value << 2)
0x40010 4 Total 3rd partitions in the disc (optional)
0x40014 4 Partition info table offset, Address is (value << 2)
0x40018 4 Total 4th partitions in the disc (optional)
0x4001C 4 Partition info table offset, Address is (value << 2)

Partition table entry

Start Size Description
0x0 4 Partition offset, Address is (value << 2)
0x4 4 Type: 0 for a Data partition, 1 for an Update partition, 2 for a Channel installer. The demonstration VC titles on Super Smash Brothers Brawl use the Ascii title ID.

Region setting

Start Size Name Description
0x4E000 4 Region byte 0 = JAP/CHT (Taiwan), 1 = USA, 2 = PAL, 4 = KOR
0x4E004 12
0x4E010 1 Japan/Taiwan Age Rating byte. Indicates the Age Rating for a Wiidisc
0x4E011 1 USA
0x4E012 1
0x4E013 1 Germany Age Rating byte. Indicates the Age Rating for a Wiidisc
0x4E014 1 PEGI
0x4E015 1 Finland
0x4E016 1 Portugal
0x4E017 1 Britain
0x4E018 1 Australia
0x4E019 1 Korea
0x4E01A 6

Partition

Each partition starts with a Ticket followed by the TMD followed by three certifications.

Offset 0x00000000 is considered as the start of the partition.

The offset of the actual partition data is 0x00020000 for normal discs and 0x00008000 for unencrypted discs (discs where 0x61 in the header is non-zero).

Start Size Description
0x00000000 0x2A4 Ticket
0x000002A4 4 TMD size
0x000002A8 4 TMD offset >> 2
0x000002AC 4 Cert chain size
0x000002B0 4 Cert chain offset >> 2
0x000002B4 4 Offset to the H3 table >> 2 (size is always 0x18000)
0x000002B8 4 Data offset >> 2
0x000002BC 4 Data size >> 2
0x000002C0 varies TMD
varies varies Partition Data

Partition Data

Encrypted

For discs where 0x61 in the disc header is non-zero, skip this section and go to #Decrypted. (Such discs don't work on retail consoles.)

Partition data is encrypted using a key, which can be obtained from the partition header and the master key. The actual partition data starts at an offset into the partition (normally 0x20000), and it is formatted in "clusters" of size 0x8000 (32k). Each one of these blocks consists of 0x400 bytes of encrypted SHA-1 hash data, followed by 0x7C00 bytes of encrypted user data. The 0x400 bytes SHA-1 data is encrypted using AES-128-CBC, with the partition key and a null (all zeroes) IV. Clusters are aggregated into subgroups of 8 clusters, and 8 subgroups are aggregated into one group of 64 clusters. The plaintext format is as follows:

Start End Length Description
0x000 0x26B 0x26C 31 SHA-1 hashes ("H0", 20 bytes each), one for each block of 0x400 bytes of the decrypted user data for this cluster.
0x26C 0x27F 0x014 20 bytes of 0x00 padding
0x280 0x31F 0x0A0 8 SHA-1 hashes ("H1"), one for each cluster in this subgroup. Each hash is of the 0x000-0x26B bytes, that is, of the 31 hashes above. This means that each cluster carries a hash of the data cluster hashes for each of the clusters in its subgroup. Every cluster in the subgroup has identical data in this section.
0x320 0x33F 0x020 32 bytes of 0x00 padding
0x340 0x3DF 0x0A0 8 SHA-1 hashes("H2"), one for each subgroup in this group. Each hash is of the 0x280-0x31F bytes above. This means that each cluster carries a hash of the subgroup hash data for each of the subgroups in its group. All 64 clusters in a group have identical data in this section. Bytes 0x3D0-0x3DF here, when encrypted, serve as the IV for the user data.
0x3E0 0x3FF 0x020 32 bytes of 0x00 padding

If you're having trouble seeing how this works, here's the algorithm:

  • For every 0x400 bytes of user data (plaintext), apply SHA-1. Store the resulting table of hashes.
  • Aggregate 8 clusters. Apply SHA-1 to the table of data hashes that you've just created above for every cluster, and build a table of the resulting 8 hashes. Store this table in each of the 8 clusters.
  • Aggregate 8 subgroups (64 clusters). Apply SHA-1 to the table of hashes of each subgroup (note that every cluster in the subgroup shares this, so you only compute the SHA-1 once per subgroup). Build a table, and store a copy of this table into every one of the 64 clusters.

Finally, the global hash table ("H3"; which the partition header points to) contains the SHA-1 hash of the last table of each group in the partition. This table is not encrypted, but it is signed. To build it, take bytes 0x340-0x3DF from any sector in each group in the partition, apply SHA-1, and simply store all of the resulting hashes consecutively. All in all, each sector includes enough information to trace itself back to the master SHA-1 hash table. As a result, the entire partition is effectively signed. If anything is changed, the Wii will immediately crash (if the master hash table has been updated), or it will crash when it reads any sector in the modified group (if the group tables have been updated), any sector in the modified subgroup (if the subgroup tables have been updated), or any modified sector if no SHA-1s were updated.

The signature is stored in the TMD. The TMDs for the partition always have one content. The type of that content seems to be always 3, and the SHA1 hash is the SHA1 of the entire 0x18000 bytes of the hash table. The TMD is signed using Nintendo private key. That makes basically impossible to run modified discs. Trucha Signer uses the signing bug to bypass the TMD signature checking, so the SHA1 hash of the master table can be updated, and modified discs can be booted.

To decrypt the user data at 0x0400-0x7FFF, again use the partition key, but this time take the IV from bytes 0x3D0-0x3DF in the encrypted SHA-1 block.

Decrypted

Once the Partition Data is decrypted (or if it was stored unencrypted to begin with), it follows the same formatting as a Gamecube disc for the most part.

Start Size Description
0x00000 1024 Same format as the main disc header, except bytes 0x60 and 0x61 are set to 0x01.
0x00420 4 Pointer to the Main Dolphin, Address is (value << 2)
0x00424 4 Pointer to the File System start, Address is (value << 2)
0x00428 4 File System Size
0x0042C 4 Max File System Size
0x02440 4 Pointer to the App Loader


Known Wii discs

On the Title Database you can find some info about different game discs

Methods to boot a disc

As far as we know there are 2 methods to boot a game.

Method 1 is R (manual boot)
Method 2 is 0 (autoboot)


The Wii BootMe tool (created by CorteX) lets you change the way wii images boot.