BNK Format (Halloween Harry)
Format type | Archive |
---|---|
Max files | Unlimited |
File Allocation Table (FAT) | Embedded + External |
Filenames? | Yes, 8.3 |
Metadata? | None |
Supports compression? | No |
Supports encryption? | No |
Supports subdirectories? | No |
Hidden data? | Yes |
Games |
The BNK (Bank) archive format is the format used by Halloween Harry to store a number of related game files. The format is trivial, being a collection of concurrent file chunks. Each BNK file has an associated FAT (File Allocation Table) file that provides quick access to the filenames, offset in the BNK file and size of the files stored in the BNK file. The FAT file however is usually not necessary to read data from the BNK file, all required information can be obtained by simply scanning said BNK file.
Files in the BNK file may or may not be compressed. This depends on what version of the BNK format is being used.
File format
Signature
Each file entry begins with a signature, so the very first file entry's signature can be used to verify the main file in in .BNK format. This means at offset zero, there should be a character of code 0x04, followed by the four characters "-ID-" (see file entry below for more details.)
Data type | Name | Description |
---|---|---|
BYTE[5] | signature | "\x04-ID-" (not null-terminated) |
Note that there are two versions of the .BNK format - the original Halloween Harry version (with no compression) and the later Alien Carnage version (with compression.) The version can be detected by using the following method:
- Read in the first file header (see file entry below), in Halloween Harry format (i.e. pretend the iDecompressedSize field was not present.)
- Use that information to jump to the second file within the main .BNK file.
- Check for the "-ID-" signature at the start of the second file entry. If it's there (at the expected offset), then it's a non-compressed Halloween Harry .BNK file.
- If the "-ID-" signature is missing, try again four bytes further in (making up for the iDecompressedSize field that we ignored in the first step.)
- If the "-ID-" signature is now present, it's a compressed Alien Carnage .BNK file.
- If the "-ID-" signature still can't be found, it's not a valid .BNK file.
If there is a .FAT file and it is a multiple of 21, then it is in Halloween Harry format. Alien Carnage no longer uses the .FAT file.
FAT format
For Halloween Harry (not Alien Carnage), an external file (with the same name as the BNK file but with a .FAT extension) stores a summary of the files in the BNK file. It also stores file offsets for quick access. This file is not necessary to read the BNK archive (since the filenames are stored in both places) however it can provide a faster alternative for listing files compared to scanning through the entire BNK file. Of course if a BNK file is to be modified, then the FAT file will also need to be updated.
Alien Carnage no longer uses the FAT file. ! Is this data stored somewhere else instead or is it no longer required?
A FAT entry consists of a filename, offset and size.
Data type | Name | Description |
---|---|---|
UINT8 | lenName | Length of the filename |
char[12] | filename | Filename, 12 chars long, but the name itself is only lenName characters long. Not null-terminated, but null-padded if needed. |
UINT32LE | fileOffset | Offset of the file from the start of the BNK |
UINT32LE | fileSize | Size of the file in bytes |
The very first file entry is at offset zero, and the above structure is repeated back-to-back until there are no more files. The offset given for each file is to the start of the file data itself, just after the header (in other words, the offset points to cData in the structure below.)
File entry
Each file entry in the BNK is similar to the entry in the external FAT file, with the addition of a signature and the omission of the offset, and of course the actual file data as well.
Data type | Name | Description |
---|---|---|
BYTE[5] | signature | "\x04-ID-" (not NULL-terminated) |
UINT8 | lenName | Length of the filename |
char[12] | filename | Filename, 12 chars long, but the name itself is only lenName characters long. Not null-terminated, but null-padded if needed. |
UINT32LE | fileSize | Size of the file in bytes |
UINT32LE | decompressedSize | Alien Carnage only: Size of the file in bytes, once it has been decompressed (this field is not present in Halloween Harry) |
BYTE[iFileSize] | data | File data |
The very first file entry is at offset zero, and the above structure is repeated back-to-back until there is no more data in the .BNK file.
Compression format
The files are compressed with the PKWare DCL Implode algorithm. Note that this is different to the PKZip Implode algorithm.
Sample code:
- Go
- blast (compress and decompress)
- C
- ACXTRACT
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 |
---|---|---|---|---|---|---|---|---|---|
ACXTRACT | Any | Yes | Yes | No | No | No | N/A | N/A | Algorithm is decompiled so only works on little-endian machines |
Camoto | Linux/Windows | Yes | No | Yes | Yes | No | N/A | N/A | |
Camoto/gamearchive.js | Any | Yes | No | Yes | Yes | No | N/A | N/A | |
Wombat | Windows | Yes | Yes | No | No | No | N/A | N/A |
Credits
This file format 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!)