Changes

Jump to: navigation, search

Title metadata

1,969 bytes added, 01:25, 6 November 2018
no edit summary
/**************************************************************/ // // Nintendo Wii Virtual Console tmd-file structure // // v.0.1 // // by Lockhool for #wiidev at efnet // 14.12.2007 /**************************************************************/ // Common labels '''Title metadata''' is a format used in this file: // magicnum - control ints or shorts found in all tmds // zeros - bytes all filled with zeros // undef - non-zero data of unknown purpose // sign - zero-terminated string padded to 64 bytes // probably used in the signing process // hash - probably 20, 512 or 1024 byte hashes // // # in fornt of store information about a comment signifies entires that are // the same in each tmd-files the author checked // // ! Remember the Wii has title (a LITTLE-ENDIAN processor. When ! // ! working with ints or shorts on none-LE machines ! // ! (esingle standalone game, channel, etc.g. PPC Mac) you need to swap the byteorderand all its installed contents, including which contents they consist of and their SHA1 hashes. !
Many operations are done in terms of 64-byte blocks, which means you will often see padding out to the nearest 64-byte boundary at the end of a field.
 
== Structure ==
=== Header ===
{| class="wikitable"
|- style="background-color: #ddd;"
! Start
! Length
! Description
|-
| 0x000
| 4
| Signature type
|-
| 0x004
| 256
| Signature
|-
| 0x104
| 60
| Padding modulo 64
|-
| 0x140
| 64
| Issuer
|-
| 0x180
| 1
| Version
|-
| 0x181
| 1
| ca_crl_version
|-
| 0x182
| 1
| signer_crl_version
|-
| 0x183
| 1
| Padding modulo 64
|-
| 0x184
| 8
| System Version (the ios that the title needs)
|-
| 0x18C
| 8
| Title ID
|-
| 0x194
| 4
| Title type
|-
| 0x198
| 2
| Group ID
|-
| 0x19A
| 2
| Zero
|-
| 0x19C
| 2
| Region
|-
| 0x19E
| 16
| Ratings
|-
| 0x1AE
| 12
| Reserved
|-
| 0x1BA
| 12
| IPC Mask
|-
| 0x1C6
| 18
| Reserved
|-
| 0x1D8
| 4
| Access rights (flags for [[DVDX|DVD-video access]] and [http://hackmii.com/2009/08/of-tmds-and-hardware/ full PPC hardware access])
|-
| 0x1DC
| 2
| Title version
|-
| 0x1DE
| 2
| Number of contents (nbr_cont)
|-
| 0x1E0
| 2
| boot index
|-
| 0x1E2
| 2
| Padding modulo 64
|-
| 0x1E4
| 36*nbr_cont
| Contents
|}
 
=== Content ===
{| class="wikitable"
|-
! Start
! Length
! Description
|-
| 0x00
| 4
| Content ID
|-
| 0x04
| 2
| Index
|-
| 0x06
| 2
| Type
|-
| 0x08
| 8
| Size
|-
| 0x10
| 20
| SHA1 hash
|}
 
=== Certificates ===
{| class="wikitable"
|-
! Start
! Length
! Description
|-
| 0x000
| 4
| Signature type
|-
| 0x004
| 256
| Signature
|-
| 0x104
| 64
| Issuer
|-
| 0x124
| 4
| Tag
|-
| 0x128
| 64
| Name
|-
| 0x168
|
| Key
|}
 
== Example code application ==
<source lang="c">
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32; /* On a 32bit system, long is only 4 bytes- use long long instead */ typedef unsigned long u64; </source><source lang="c"> typedef struct { u32 cid; // content id u16 index; // # number of the file u16 type; // normal: 0x0001; shared: 0x8001 u64 size; u8 hash [20]; // SHA1 hash content } content_record; // size: 0x24 bytes</source><source lang="c">enum sig_type { RSA_2048 = 0x00010001, RSA_4096 = 0x00010000}; // High 32 bits of the title IDenum title_type : u32 { System = 0x00000001, Game = 0x00010000, Channel = 0x00010001, SystemChannel = 0x00010002, GameWithChannel = 0x00010004, DLC = 0x00010005, HiddenChannel = 0x00010008,}; // title_type (offset 0x194)enum title_flags { // All official titles have this flag set. Default = 0x1, Unknown_0x4 = 0x4, // Used for DLC titles. Data = 0x8, Unknown_0x10 = 0x10, // Seems to be used for WFS titles. Maybe_WFS = 0x20, Unknown_CT = 0x40,};</source><source lang="c"> typedef struct { u32 sig_type; u8 sig[256]; u8 fill1[60]; u8 issuer[64]; // Root-CA%08x-CP%08x u8 version; u8 ca_crl_version; u8 signer_crl_version; u8 fill2; u64 sys_version; u64 title_id; u32 title_type; u16 group_id; // publisher u8 reserved[62]; u32 access_rights; u16 title_version; u16 num_contents; u16 boot_index; u16 fill3; content_record contents[num_contents]; } tmd;</source>The tmd is then followed by a chain of certificates, where each certificate is of the general form<source lang="c"> u32 sig_type; // u8 sig[256]; // 256 for RSA_2048, 512 for RSA_4096 u8 issuer[32]; u32 tag; // identifies what is being signed u8 name[64]; // name of thing being signed u8 key[...];</source> There is also a structure called a TmdView which is select sections of the Tmd. It has a length of 0x60+0x10*number_of_contents. The structure is somewhat like this [as returned by ES_GetTmdView] :<source lang="c">struct tmd_view_content_t{ uint32_t id; uint16_t index; uint16_t type; uint64_t size;};
typedef structtmd_view_t{ u32 file uint8_t version; // 0x0000; uint8_t filler[0x13]; uint64_t ios_title_id; // name of the file to download0x0004 u16 num [0x1] uint64_t title_id; // 0x00c uint32_t title_type; // # number of the file0x0014 u8 undef0 [0x1] uint16_t group_id; // might be 0x00 or 0x800x0018 u8 undef1 uint8_t reserved[0x10x3e]; // # 0x010x001a this is the same reserved 0x3e bytes from the tmd u8 zeros0 [0x4] uint16_t title_version; // # 00x0058 u32 length [0x1] uint16_t number_contents; // non-padded filelength0x005a u8 hash tmd_view_content_t contents[0x14]; // ? maybe SHA1-hash0x005c }VC_TMD_FILE; /</ size: 0x30 bytessource>
typedef struct{ u32 magicnum0 [0x1]; // # 0x00010001 u8 hash0 [0x100]; // ? u8 zeros0 [0x3C]; // # 0 u8 sign0 [0x40]; // # Root-CA-CP u8 undef0 [0x10]; // # ? u8 code [0x4]; // game code in ascii u32 magicnum1 [0x1]; // # 0x00000001 u8 publ [0x2]; // publisher id u8 zeros1 [0x2]; // # 0 u8 undef1 [0x4]; // ? u8 undef2 [0xE]; // ? 0x80 u8 zeros2 [0x2E]; // # 0 u8 undef3 [0x8]; // ? VC_TMD_FILE files[7]; // 7 file entries u32 magicnum2 [0x1]; // # 0x00010001 u8 hash1 [0x100]; // # ? u8 zeros3 [0x3C]; // # 0 u8 sign1 [0x40]; // # Root-CA u32 magicnum3 [0x1]; // # 0x00000001 u8 sign2 [0x40]; // # CP u8 hash2 [0x104]; // # ? u32 magicnum4 [0x1]; // # 0x00010001 u8 zeros4 [0x34]; // # 0 u32 magicnum5 [0x1Category:File formats]; // # 0x00100000 u8 hash3 [0x200]; // # ? u8 zeros5 [0x3C]; // # 0 u8 sign3 [0x40]; // # Root u32 magicnum6 [0x1]; // # 0x00000001 u8 sign4 [0x40]; // # CA u8 hash4 [0x104]; // # ? u32 magicnum7 [0x1]; // # 0x00010001 u8 zeros6 [0x34]; // # 0 }VC_TMD; // size: 09E0 bytes
35
edits

Navigation menu