The .RFF File Format

Ok, what is this you ask? Well the answer to that question is invariably: If you have to ask, the answer isn't going to make sense to you anyway. Just as the .art files hold all the textures and sprites, the .RFF file format is used in Blood to store the game's resources like maps (.map) and sounds (.raw and .mid).

From Matt Saettler's Notes and memory.

The file format is a basic multi-file container. As such, it has a header for version #, etc, a list of files in a 'directory' and the actual file data.

For the initial shareware release, the file data was just copied into the RFF file. After we noticed that there were readily available hacking programs available to extract file by type (by recognizing the signature bytes for that file format (for example, WAV files), I decided to encrypt the start of each file to prevent this from happening. Also, the dictionary is encrypted.

There were two versions of BARF compiled from the same source. one for external release and one for internal only release. The internal release allowed the creation of encrypted files and marked the RFF as 'Monolith approved'. I believe that when a 'non-approved' map file was run, the monolith logo showed in the top right of the screen.

The internal release also allows full extraction of all files. The external version only extracts files that we thought were likely to be modified by MOD makers.

The first thing in the file is the header block. It consists of a signature block, version #, # of files and offset to the first 'directory' structure. There might be some other stuff in there. It is never encrypted.

The directory block is an array of structures. I don't believe that sub-directories were allowed. The structure contains the information about each file. Info will be: Name, extension, flags, fileoffset, filesize, time (for update). There might be a few other things in the structure.

Encryption. The older RFF file format did not use encryption. I believe that this was only in the shareware, but I'm not sure. It might have actually been used in the shipping Blood. Later version (and certainly all patches) used the encryption. The encryption is a simple XOR of each byte with a moving value starting at a given starting value. The starting value was variable based on file offset (I think). Getting this starting value will be the tough part.

To reverse engineer the starting 'key', create a simple RFF file with a single file named AAAAAA.AAA. This sequence should be easy to find since there will be an increasing sequence of bytes in the file. You should be able to figure out the starting XOR from what the sequence is at.

The first 256 (or maybe 255) bytes of files were also compressed (based on a flag in the directory struct). The key was probably constant to allow moving the file without having to re-crypt the data. Use the same trick to reverse engineer to find the starting key. Use a file with all zeros for easiest finding.

Here is the crypt routine that I've often used. I'm pretty sure this is what I also used in Blood. (note this this is a two-way routine; it encrypts and decrypts; the beauty of XOR...)

void crypt(unsigned char *buf, int len, long startpos)
{
long curpos=startpos;
int i;
for(i=0;i<len;i++)
{
buf[i] ^= (unsigned char) ((unsigned short) curpos/2);
curpos++;
}
}
Barf is driven by a 'script'-like language that defines the files to be included and their file flags, etc. This file also allows the generation of an .H file (hmm.. the files also have an ID that is used in a #define, so the id is probably in the directory structure).

Barf will generate a script file from an RFF file. But the external version will not extract the protected files...I don't remember which files we considered 'protected'.... It should be obvious by what doesn't get extracted.... :)

I think that's pretty much it.

Copyright (c) 2000, Matt Saettler. All Rights Reserved
-------------
Matt Saettler
matts@saettler.com
http://www.saettler.com