MIX Format (Westwood)

From ModdingWiki
Jump to navigation Jump to search
MIX Format (Westwood)
Format typeArchive
Max files65,536
File Allocation Table (FAT)Beginning
Filenames?No
Metadata?None
Supports compression?No
Supports encryption?Yes
Supports subdirectories?No
Hidden data?Yes
Games

Westwood's MIX Format is a simple group file used in their games from 1995-2001. It only stores file name hashes, so some file names will result in the same hash and can thus not both be read from mix archives unless the game only reads specific files from specific mix archives. Position and size of files are stored in the header, so the size does not need to be inferred. The format does not support compression.

There are two versions of the header; basic and advanced. The basic one only stores the file count, the total data size and the files index. The advanced one has a flags field before the main header which contains info on whether the header and file index are encrypted, and whether the file has an SHA1 checksum tailer to verify the data integrity.

The hash algorithm used for the file names is a rolling hash in Command & Conquer, Red Alert and Sole Survivor. It was was replaced with the less collision-prone CRC32 in Tiberian Sun and later games. There is no data in the file format itself to indicate which hash scheme is used. Other games may use other hash methods.

Apart from the original Command & Conquer, all the games can read both types of header, provided the hash format is correct for that game.

File format

Signature

MIX files have no signature. Usually they will have the extension .mix

File Header

The header consists of an optional flags section 4 bytes in size. The first 2 bytes are 0 in this case, to distinguish between mix files with and without feature flags. The ones that don't have the flags immediately start with the next piece of data, which is the file count as UNIT16LE. Since empty archives are pointless, this makes the two types easy to distinguish. The flags are stored in the 3rd byte as a bit field, with bit 0 indicating a checksum is present, and bit 1 indicating that the header is encrypted.

If the flags indicate encryption, an 80-byte block follows the flag section. This block is encrypted with an RSA private key with the public key used to decrypt being embedded in the games code. This block decrypts to a 56-byte Blowfish key that is used to decrypt the rest of the header.

The standard header follows, with first the file count, and then the size of the actual file data behind the header. C&C games use this when caching a mix file. XCC uses this to validate the format and can be abused by making it larger to prevent XCC reading it correctly at the cost of the games reading additional garbage when caching them. This is used in so called "protection" schemes some mods use to prevent others using their assets.

Data type Name Description
UINT32LE Flags An optional field that specifies additional optional features that the archive uses.
BYTE[80] Key An optional 80 byte block containing an RSA encrypted Blowfish key to use to decode the rest of the header.
UINT16LE FileCount The number of files in the archive. Can be used to calculate the size of the file entry index.
UINT32LE DataSize Size of the data section, behind the files header.

File Entry

The indexes file entries contain a hash of the filename, the offset of the file within the data section (header size needs to be added for absolute position in the archive) and the size of the file in bytes.

Data type Name Description
INT32LE Id Hash of the filename. Hash algorithm varies between games.
UINT32LE Offset File's starting offset within the data section.
UINT32LE Size File's size.

In order to quickly locate files from their file name hashes, the index is sorted according to the hashes taken as signed integers.

Encryption

Header encryption can be detected by checking Flags & 0x00020000 does not equal zero. If it doesn't, then the next 80 bytes are two RSA encrypted blocks that need to be decrypted with the Westwood public key. For the purposes of the RSA algorithm, the blocks should be treated as 2 40 byte "big" integers in little endian byte order. 0x10001 should be used as the public exponent for the decryption.

The result is a 56 byte block padded with zeros to use with the Blowfish algorithm in ECB mode. Blocks are 8 bytes long and you need to decode the first block to get the standard header. From that you can calculate the length of the index and thus how many additional blocks you need to decode to get the rest of the index. If the header and index together are not perfectly divisible by 8, then it is padded with zeros since blowfish operates on 8 byte blocks.

Creating an encrypted header is the reverse of this process, a Blowfish key is generated somehow and used to encrypt the header and index and is itself padded with zeros and encrypted using the Westwood private key.

The public key is encoded in the game binaries while the private key was leaked in the form of keys.ini included in one of the Tiberian Sun MIX files. Presumably this was a mistake as it cannot be used from that location. The full contents of the file are as follows.

[PublicKey]
1=AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V

[PrivateKey]
1=AigKVje8mROcR8QixnxUEF5b29Curkq01DNDWCdOG99XBqH79OaCiTCB

The keys are Base64 encoded and DER encoded big endian "big" integers and represent the modulus and the private exponent respectively in the RSA encryption scheme. The DER format header "02 28" on both values defines them as being integer blocks of 40-bytes long.

Checksum

Data checksum presence can be detected by checking Flags & 0x00010000 does not equal zero. If it doesn't, then the last 20 bytes of the file are a SHA1 hash of the data contents of the file, not including the header.

Tools

The following tools are able to work with files in this format.

Name PlatformExtract files? Decompress on extract? Create new? Modify? Compress on insert? Access hidden data? Edit metadata? Notes
XCC Mixer WindowsYesN/AYesYesN/ANoN/A
Mix Manager DOSYesN/AYesYesN/ANoN/A
RAMIX DOSYesN/AYesYesN/ANoN/A
OpenRA Utility Windows, Linux, MacYesN/ANoNoN/ANoN/A