Daniel's page
The mi4code tool
Rockbox SanDisk Connection Sansa e200 Pics Hacking Devboard e200tool mi4 File Format mi4code AMS Sansas Sansa View
mi4code

mi4code.c (view it) is the (de/en)coder source code provided by MrH (Version 1.1.2, uploaded April 2008)

All use of this code is entirely on your own risk. Everything just might explode and there's no one but yourself to blame.

Rockbox and mi4

The Rockbox build system now uses the "standard" scramble tool with the mi4.c file, for building mi4 firmwares, since it doesn't need all the fancy abilities of mi4code.

Compile the Tool

mi4code is the single source file that can be compiled to a single executable with:

 gcc -o mi4code mi4code.c -lgcrypt

(gcrypt is used for DSA and you can edit the source to disable DSA support and thus remove the dependency on this lib.)

Windows binaries

0.9.33 (outdated!)

The Commands

mi4code has a few main commands that tells it what to do:

All commands take -h to display help, -v to add verbosity and starting in 0.9.26 -q to make it more quiet.

There's a small howto at the bottom of this page describing how to combine the use of these commands when upgrading to your own firmware.

Decrypt
  mi4code decrypt [options] <infile> <outfile> [keyid]
 
  mi4code decrypt [options] <infile> <outfile> [k1] [k2] [k3] [k4]

Decrypt (using TEA) an existing encrypted mi4 file. This command can be told to use one of the existing built-in keys, you can tell it explicitly what key to use or it will try all known internal keys. Use decrypt -l to list all known keys.

Note that using -s to strip off the header can be useful if you want the binary blob to be understandable by a dissassembler at once or similar, but you want to keep the header if you intend to re-encrypt it into a mi4 file again.

options:

Encrypt
  mi4code encrypt [options] <infile> <outfile> <keyid>
 
  mi4code encrypt [options] <infile> <outfile> <k1> <k2> <k3> <k4>

Encrypt (using TEA) a binary file into a proper mi4 file. This command can be told to use one of the existing built-in keys or you can tell it what key to use for encryption. Use encrypt -l to list all known keys.

Note that this command doesn't add an mi4 header, but assumes that the binary file you pass as input already have one.

options

Build
  mi4code build [options] <infile> <outfile> [offs_id]

This commands builds an mi4 file out of a binary lump. It means it creates the necessary mi4 header, pads its correctly, adds the magic in the end etc.

The offs_id is a magic number used in the mi4 and it must be correct for the bootloader to accept the mi4. (added in 0.9.33)

options

Keyscan
  mi4code keyscan [options] <infile> <keyfile>

Scans for possible TEA encryption keys for infile within the keyfile. The infile is typically an mi4 file, and the keyfile its corresponding BL file.

Sign
  mi4code sign [options] <infile> <outfile> [keyid]

mi4 files are signed with DSA keys. Using this command you can sign your mi4 file with one of a few selectable keys. Use -l to list what keys that are available.

NOTE: the bootloader will check that the mi4 file is "legimitately" signed.

options

Verify
  mi4code verify [options] <infile> [keyid]

Verifies the DSA signatures within the given mi4 file, or if not given with all known built-in keys.

options

blpatch
  mi4code blpatch [options] <infile> <outfile> [keyid]

Patch a bootloader (BL*.rom file) with a custom DSA key to make it accept an mi4 file using the corresponding DSA signature.

Hexdecode
  mi4code hexdecode [options] <infile> <outfile> <keyid>

Decodes a 'hex' bootloader file. 'hex' here being the hex format that iriver H10 models use for their BL files.

options

Hexencode
  mi4code hexencode [options] <infile> <outfile> <keyid>

Encodes a 'hex' bootloader file. 'hex' here being the hex format that iriver H10 models use for their BL files.

options

How To Upgrade Your mi4-based Player

1. Get an upgrade firmware image. This should be an mi4 file and (possibly) a BL file.

2. Figure out what key to use for decrypting the mi4 file. mi4code already knows a bunch, but it can also scan for keys in BL files (using 'keyscan'). Decrypt the mi4 to a raw bin file. (If the BL file is hex encoded, as some iriver H10 ones are, then you need to first 'hexdecode' the BL file before you can scan for encryption keys). The key used to decrypt this will be used again later in step 4. Example:

 mi4code decrypt PP5022.mi4 PP5022.raw sansa

3. Edit the bin file accordingly.

4. Generate a new mi4 file again by running mi4code encrypt using the same key as before. Example:

 mi4code encrypt PP5022.raw PP5022-new.mi4 sansa

5. If the mi4 uses a 010301 version, you must also run mi4code 'sign' to write a suitable DSA key in the file. SanDisk Sansa and iriver H10 are known to work when signed with the default key. Trying to sign a 010201 header version should still be ok and just not do anything. Example:

 mi4code sign PP5022-new.mi4 PP5022-signed.mi4 dummy

6. Now rename the output file (named PP5022-signed.mi4 if you signed it like the example above) to the original file name and put it on the player as your ordinary upgrade procedure dictates. It probably also involves copying a BL file to it. Then the upgrade procedure should be performed just like normal...

Updated: December 28, 2009 17:21 (Central European, Stockholm Sweden)

daniel at haxx dot .se