Painkiller PAK
Choose archive extension:
Contents
PAK
- Format Type : Archive
- Endian Order : Little Endian
Format Specifications
byte {1} - IsArchiveCompressed - determines if archive files are Zlib compressed. 0 - uncompressed, not zero - compressed
uint32 {4} - position to seek to get the file list described below
// File list
uint32 {4} - Number Of Entries
// for each entry
- uint32 {4} - ns, Name length
- char {ns} - Filename encrypted (directory or file in Painkiller), takes as many bytes as previously read length. String has no termination, length directly depends on ns. See the C++ function to crypt filenames.
- uint32 {4} - UncompressedFileSize, size of original file
- uint32 {4} - CompressedFileSize, how much of space it takes inside PAK archive
- uint32 {4} - file offset
// end of loop
Must-read: Notes and Comments
Encryption
Filenames are encrypted
EncryptedStringCharacter(n) = OriginalStringCharacter XOR FileIndex + NameLength % 5 + 2 * (n + NameLength); (Where n starts at character position 0)
C++ function to crypt (decrypt or encrypt) file names:
/* Two-way algorithm. Encoding a string two times will leave it decoded. */ void CryptFilename(char *EntryName, BYTE NameLength, char FileIndex) { BYTE n = 0; while ( n < NameLength ) EntryName[n++] ^= FileIndex + NameLength % 5 + 2 * (n + NameLength); }
MultiEx BMS
- A plugin processes these archives
Notes and Comments
If uncompressed file size is 0, then it's directory reserved for entries such as "Classes/Entities/". Files may be compressed using Zlib library. If archive is uncompressed - compressed and uncompressed file sizes are equal. In that case you can directly read content of file by seeking into file offset and reading as many bytes as specified in CompressedFileSize or UncompressedFileSize (they are equal anyway). If archive is compressed - read content of file with size CompressedFileSize and decompress it using ZLib inflate function. CompressedFileSize will be useful in such a condition when you plan to allocate memory (malloc) to read input file from PAK archive. UncompressedFileSize will be useful if you allocate memory to decompress file.
Supported by Programs