In den Title-Metadaten (Title Metadata) werden Informationen über einen Titel (Spiele, Kanäle, IOS, Systemsoftware, etc.) und alle installierten Inhalte gespeichert. Sie dient vereinfacht gesagt auch als eine Art Inhaltsverzeichnis, denn sie zeigt alle zugehörigen Inhalte inklusive ihrer Position, Größe und SHA1-Hash an. Sie können vom Nintendo-Update-Server heruntergeladen werden (bspw. http://nus.cdn.shop.wii.com/ccs/download/000000010000003A/tmd für die TMD des IOS58).

Struktur

Header

Start Länge Beschreibung
0x000 4 Signaturtyp
0x004 256 Signatur
0x104 60 Padding modulo 64
0x140 64 Aussteller
0x180 1 Version
0x181 1 ca_crl_version
0x182 1 signer_crl_version
0x183 1 Padding modulo 64
0x184 8 Benötigtes IOS
0x18C 8 Title ID
0x194 4 Title-Typ
0x198 2 Gruppen-ID
0x19A 62 reserviert
0x1D8 4 Zugriffsrechte (Flags für DVD-Video- und vollem PPC-Hardware-Zugriff)
0x1DC 2 Version
0x1DE 2 Anzahl der Inhalte
0x1E0 2 Boot-Index
0x1E2 2 Padding modulo 64
0x1E4 36*Anzahl der Inhalte Inhalte

Inhalt

Start Länge Beschreibung
0x00 4 Inhalts-ID
0x04 2 Index
0x06 2 Typ
0x08 8 Größe
0x10 20 SHA1-Hash

Zertifikate

Start Länge Beschreibung
0x000 4 Signatur-Typ
0x004 256 Signatur
0x104 64 Aussteller
0x124 4 Tag
0x128 64 Name
0x168 Schlüssel

Anwendungsbeispiel

Dieses Code-Beispiel in Python 3 parst eine TMD.

from binascii import hexlify
from struct import unpack

def parse_tmd(tmd):
    # Title ID
    tmd.seek(0x18C)
    titleid = tmd.read(8)
    print("Title ID: " + hexlify(titleid).decode())

    # Title Version
    tmd.seek(0x1DC)
    tmd_title_version = unpack('>H', tmd.read(2))[0]
    print("Title version: " + str(tmd_title_version))

    # Number of Contents
    tmd.seek(0x1DE)
    count = unpack(">H", tmd.read(2))[0]
    print("Content count: " + str(count))

    # Contents
    tmd.seek(0x1E4)
    # Loop over every content
    info = []
    for i in range(count):
        # This will extract content id, index, type, size and SHA1 hash and store them in a list
        # https://docs.python.org/3/library/struct.html#format-characters ("IHHQ": 4, 2, 2, 8)
        data = [a for a in unpack(">IHHQ", tmd.read(16))]
        data.append(hexlify(tmd.read(20)))
        info.append(data)

        print("%08X" % data[0] + ": " + str(data[3]) + " bytes")
    return info  # List with every content

Gibt für das IOS58 auf der Konsole aus:

Title ID: 000000010000003A
Title version: 6176
Content count: 19
00000018: 64 bytes
...

Gibt die info-Liste zurück:

[24, 0, 1, 64, b'bcd51d83d9479e44c622c92ebf49bb2c6529d695']
...

wobei 24 im Hexadezimalsystem = 18, durch "%08X" % 24 werden Nullen vorangestellt (das X bedeutet Hexadezimal, vgl. StackOverflow). Vorlage:WiiTopicon Vorlage:DSiTopicon Vorlage:WiiUTopicon