GLB Format (Raptor)
Format type | Archive |
---|---|
Max files | 231-1 (~2 billion) |
File Allocation Table (FAT) | Beginning |
Filenames? | Yes, 15 chars |
Metadata? | None |
Supports compression? | No |
Supports encryption? | Yes |
Supports subdirectories? | No |
Hidden data? | Yes |
Games |
The GLB Format is used by Raptor to store all the game data files. Most files are not encrypted, but those the author deemed easily identifiable (such as text files) are.
Signature
Due to the encryption, and the fact that the first four bytes are always zero (after decryption), the file will always start with the byte sequence 64 9B D1 09.
Beyond this, the usual checks of valid file offsets and sizes will work.
File format
The File Allocation Table (FAT), which lists the filename, size and offset of each file within the archive, is encrypted. The FAT begins at offset 0 and the first entry (28 bytes) must be decrypted to obtain a count of the number of files in the archive. After decryption, the FAT is in the following structure:
Data type | Name | Description |
---|---|---|
UINT32LE | flags | 0=normal, 1=encrypted |
UINT32LE | offset | Offset of the file data, relative to the start of the archive |
UINT32LE | length | Size of the file data, in bytes |
char | filename[16] | Null-terminated filename (15 chars + terminating null) |
The very first entry is not a real file, but is a header. The offset field of this entry contains the number of files in the FAT (not including this header entry itself.) The rest of the fields are unused and should be set to zero.
The first file's data begins directly after the FAT, which will also be the offset value of the second FAT entry.
Filenames are not unique. Images making up a sprite set can be identified by their filename, which will be the same for all sprites in that set.
Encryption algorithm
The encryption key is the string "32768GLB".
For each byte in the file:
- Subtract the character value from the current position in the encryption key (i.e. if the current position is 0, subtract 0x33, the character code for "3")
- Advance the position in the encryption key by one (i.e. go to the next letter)
- If the end of the encryption key has been reached, go back to the first character
- Subtract the value of the previous byte read (note the previous byte *read*, not the decrypted version of that byte)
- Logical AND with 0xFF to limit the result to 0-255
- This byte is now decoded, move on to the next
Before performing the above loop, the initial state is as such:
- The position in the encryption key (step 1) does not start at 0. Instead, it starts at 25 % <length of key>. In the case of the "32768GLB" key, the length is 8, so 25 mod 8 == 1, so the encryption key starts at position 1 (i.e. the first character of the key is skipped on the first run.) After the end of the encryption key is reached, it loops back to position 0 again.
- The very first "previous byte read" value (step 4) is the actual key character at the initial position. As per the previous item in this list, if the initial key position is 1, this is key character "2", so the first "previous byte read" is the character "2" (hex 0x32).
Be aware:
- The game only decrypts one FAT entry at a time, so after 28 bytes the key and "previous byte read" must be set back to the initial state. Failure to do this has the effect of making every second FAT entry appear as random characters.
- When decrypting file content, the whole file is decrypted in one go, so the previous point does not apply - the state variables are not reset to their initial state at any point during the decryption.
- The pilot files apparently (! untested) use the same encryption algorithm with the key "CASTLE" instead. They also decrypt in blocks of 88 bytes and 24 bytes, instead of the FAT's 28 bytes.
Tools
The following tools are able to work with files in this format.
Name | Platform | Extract files? | Decompress on extract? | Create new? | Modify? | Compress on insert? | Access hidden data? | Edit metadata? | Notes |
---|---|---|---|---|---|---|---|---|---|
Camoto | Linux/Windows | Yes | N/A | Yes | Yes | N/A | No | N/A | |
Camoto/gamearchive.js | Any | Yes | N/A | Yes | Yes | N/A | No | N/A | |
GLBExt | Windows | Yes | N/A | No | No | N/A | No | N/A |
Credits
This file format, including the decryption algorithm, was reverse engineered by Malvineous. If you find this information helpful in a project you're working on, please give credit where credit is due. (A link back to this wiki would be nice too!)