RFF Format

From ModdingWiki
Jump to: navigation, search
RFF Format
Format typeArchive
Max files4,294,967,295
File Allocation Table (FAT)End
Filenames?Yes, 8.3
Metadata?None
Supports compression?No
Supports encryption?Yes
Supports subdirectories?No
Hidden data?Yes
Games

The RFF format is used by Blood, instead of the typical GRP Format used by other Build engine games. Later versions of the format encrypt the start of each file to avoid extraction by ripping utilities.

File format

Signature

All files begin with the four bytes "RFF" followed by EOF (0x1A)

Header

The header is never encrypted.

Data type Name Description
char[4] signature "RFF\x1A"
UINT16LE version Format revision
UINT16LE unknown ! Unknown - v3.1 has 0x0000 here, v2.0 has 0x0001 here
UINT32LE offFAT Offset of FAT
UINT32LE numFiles Number of files
UINT32LE unknown1 ! Unknown
UINT32LE unknown2 ! Unknown
UINT32LE unknown3 ! Unknown
UINT32LE unknown4 ! Unknown

Known versions

  • 0x0200 - shareware 0.99 (CD version) - FAT is not encrypted
  • 0x0300 - ! Reported seen, but where?
  • 0x0301 - registered version and later shareware releases. FAT is encrypted

File entry

At offFAT, the following structure is repeated numFiles times. When version == 0x301, the entire FAT is encrypted.

Data type Name Description
BYTE[16] unknown ! Unknown, fill with 0x00
UINT32LE offset Offset of file's data, relative to start of archive file
UINT32LE size File size
UINT32LE unknown2 ! Unknown, always 0
UINT32LE time Last modified time (in seconds since the UNIX epoch)
UINT8 flags File state flags
char[11] filename Filename (see below for arrangement)
UINT32LE unknown3 ! Unknown, always 0

The filename field contains a standard 8.3 filename, but with no dot and the extension first. For example HELLO.TXT would appear as TXTHELLO, padded up to 11 characters with nulls - but note that a full length filename won't have a null at the end.

When flags & 0x10, the first 256 bytes of the file are encrypted.

The time is stored in seconds since midnight, January 1st 1970. One quick example of use is the PHP code echo date('Y-m-d', time);

! How are filenames with short extensions stored? Is CODE.H stored as H\0\0CODE?

Encryption

FAT

The encryption algorithm for the FAT only applies to files of version 3.1 or presumably newer (version >= 0x301). It is an 8-bit XOR cipher, with the key incrementing by one every two bytes. The tricky part is that the initial value for the key is the lower 8-bits of the FAT offset, so if the FAT moves for any reason it will need to be re-encrypted.

Example code:

// En/de-crypt the FAT
if (version >= 0x301) {
  uint8_t key = fatOffset & 0xFF;
  for (int i = 0; i < lenFAT; i += 2) {
    fat[i    ] ^= key;
    fat[i + 1] ^= key;
    key++;  // will wrap from 255 back to 0
  }
}

Since it is an XOR cipher, the same code applies to both encrypt and decrypt the FAT.

Files

If the flags value in the FAT entry has the fifth bit set (0x10) then the file is encrypted. The algorithm is a variation on that used for the FAT. The key is half the offset into the file (i.e. it is offset >> 1, which will cause it to start at zero for all files.) Only the first 256 bytes of each file are encrypted, the rest of the data is unchanged.

Example code:

// En/de-crypt a file
if (flags & 0x10) {
  for (int i = 0; i < 256; i++) {
    data[i] ^= (i >> 1);
  }
}

Again since it is an XOR cipher, the same code applies to both encrypt and decrypt the FAT.

Hidden data

Because there is much redundancy in the way the RFF format records the locations of files, there are a number of different ways that data can be hidden within the RFF that would not normally be visible.

As the FAT is located at an arbitrary location within the RFF file (although by convention at the end) it is possible to hide data by inserting it between the end of the last file and the start of the FAT. Although no known files or utilities store the FAT anywhere else except at the end of the file, it would be technically possible to store the FAT in the middle of the file, which would allow data to be hidden both before and after the FAT.

Due to the FAT storing both an offset and a size for each file, it is also trivial to store data in between files. This could be most easily accomplished by adding files as normal, then simply removing some entries from the FAT. The data will remain in the file but will be invisible to most utilities, and the other files will be unaffected by the change.

Tools

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

Name PlatformExtract files? Decompress on extract?Decrypt? Create new? Modify? Compress on insert?Encrypt? Access hidden data? Edit metadata? Notes
Camoto Linux/WindowsYesN/AYesYesYesN/AYesNoN/A

External links

Credits

This file format was documented here by following the source code of the Rebuild project's RFF utility.