Packlist.dat

packlist.dat is a file in the "Packs" folder in the TrackMania installation directory. It contains the encryption keys for the .pak files there.

File structure

 * byte version (currently 1)
 * byte numPacks
 * uint32 crc32 (zero)
 * uint32 salt
 * PackEntry[numPacks]
 * byte flags
 * byte nameLength (must be < 32)
 * byte encryptedName[nameLength]
 * byte encryptedKeyString[0x20]
 * byte signature[0x10]

Reading the pack entries
The name and the key of each entry are decrypted as follows.

nameKey = md5("6611992868945B0B59536FC3226F3FD0" + sprintf("%u", salt)); for (int i = 0; i < nameLength; i++) name[i] = encryptedName[i] ^ nameKey[i % 16];

keyStringKey = md5(name + sprintf("%u", salt) + "B97C1205648A66E04F86A1B5D5AF9862") for (int i = 0; i < 0x20; i++) keyString[i] = encryptedKeyString[i] ^ keyStringKey[i % 16];

key = md5(keyString + "NadeoPak")

"name" corresponds to the name of a .pak file, minus the extension. "key" is the 16-byte key used during Blowfish decryption of the .pak file.

Signature verification
packlist.dat has a 16-byte signature at the end for integrity checking. It is verified as follows:

md5In = md5("E3554B5828AF14F11AA42A5EAF0AEFC8" + sprintf("%u", salt)); md5Xor36 = pad(md5In, 0x40, '\0');  // Append 0x30 '00' bytes md5Xor5C = pad(md5In, 0x40, '\0'); for (int i = 0; i < 0x40; i++) {    md5Xor36[i] ^= 0x36; md5Xor5C[i] ^= 0x5C; } signature = md5(md5Xor5C + md5(md5Xor36 + fileContent))  // fileContent is everything in packlist.dat except the signature

The calculated signature must match the signature in the file, or TrackMania will not accept the file.