There are two sets of .dat files in this game; system files (replay\qprpy_%d2.rpy, config.dat, stag.dat, stag2.dat) which are encrypted and asset files (stag[3-6].dat) which are blobs containing various DirectX compatible image assets
The asset file starts with an 8 byte header followed by the below structure for each asset. The game has a function that loads assets by archive and file name which literally just scans the archive byte-by-byte for the filename
struct {
char filename[16];
uint32_t width;
uint32_t height;
uint32_t flags; // not 100%
uint32_t size;
char data[size];
} asset;
The system files are encrypted with the below XOR cipher. The first uint32_t of the file is the length of the file minus the field itself and this is validated within the game as a very basic tamper check
bool DecryptDat(char *filepath, void *output_buffer, int expected_size)
{
int index;
FILE *file_ptr;
char val;
int size;
bool success;
success = 0;
index = 0;
size = 0;
file_ptr = fopen(filepath, 'rb');
if ( !file_ptr )
return 0;
// read first uin32_t size field
fread(&size, 4u, 1u, file_ptr);
if ( size == expected_size )
{
while ( index < expected_size )
{
val = fgetc(file_ptr);
val = size++ ^ (16 * val | (val >> 4) & 0xF);
output_buffer[index++] = val;
}
success = 1;
}
fclose(file_ptr);
return success;
}
Hope this helps