The result of a blogging accident

Trackmania Disassembler Updated (1.2), and some musings

I’ve updated my [Trackmania Disassembler][tmdisasm] to support Trackmania Nations Forever and Trackmania United Forever. And it seems Nadeo have finally gone off their weak XOR password obfuscation algorithm. The previous part of the file that held the password is now always blank - wether there is a password there or not, and the password seems to be buried somewhere in the data block.

Seeing as the algorithm has been now changed, I thought I’d document how the old password algorithm worked.

1. The first three bytes are 31, 180, 229. (`1F B4 E5`) 2. The 5 bytes of the password are XOR’d with 94, 36, 240, 15, 90. (`5E 24 F0 0F 5A`) 3. Go back to step 2 until the end of the password string.

As an example, say my password is “passwd”. That means the encrypted form of my password is `1F B4 E5 2E 45 83 7C 2D 3A`.

XOR for password obfuscation is trivial to decode. If you know the original text and the encoded text, you can determine the cipher text. (Original XOR Encoded = Cipher) Once you know the ciper text, you can then encode or decode text freely. (Original XOR Cipher = Encoded; Encoded XOR Cipher = Original)

The size of the password stored the old way is variable, so a long password will take more bytes to store than a short one.

There’s more about the [XOR cipher on Wikipedia][xor].

So far, looking at the Trackmania Forever stuff, I’ve noticed:

* The thumbnail introduced in Trackmania United changes on each save, due to the lighting and clouds changing in that frame. As a result, the file size will change slightly because of the nature of JPEG. * The same password on two identical tracks (same UID and name) means the data block is the same. So the password encoding doesn’t have a random element to it. * The password for the same track is stored in a way that the size is constant. At the moment, I’m thinking there is a hash of the password being stored, meaning the password storage algorithm may be very difficult to break, apart from dictionary attacks (computationally expensive to do). * I think that the password is stored near the end of the data block, after all the other data.

[tmdisasm]: /tmn/disasm/ [xor]: http://en.wikipedia.org/wiki/XOR_cipher