Jump to content

barncastle

Members
  • Posts

    3
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

barncastle's Achievements

Newbie

Newbie (1/14)

  • Dedicated
  • Week One Done
  • First Post

Recent Badges

1

Reputation

1

Community Answers

  1. 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
  2. You'll probably need to write your own script. CAS is designed to be read as a whole (root manifest -> encoding -> index -> data) which is why all the tools and libraries require a full installation/Blizz's CDN to work Simc have a python implementation for reading the CAS containers including BLTE parsing you could reference - casc_extract source
  3. I've written a C# script that reimplements the decompression algorithm here, this is reversed from the GAX.ocx library Some random bits I noted whilst working on this: - The "LoadFile" library call reassigns the decompressed data to an in-memory format which differs from the decompressed format you're documenting - The checksum is a variant of Fletcher 32 that processes in 0x15B0 byte blocks (also reimplemented). It is calculated on the compressed data which begins after the LZOD "Compressed Data Size" field - "0153" is a version string. The version of GAX.ocx I was reversing throws an exception if this is less than "0110" - All chunks have a 4 character magic/signature followed by a uint32_t size field - Your "EXP" chunk documentation isn't quite right; there are two chunks, "EXPP" and "AUTH". "EXPP" appears to be referenced when exporting (I didn't fully reverse it's use), and "AUTH" contains the author's name struct { uint32_t magic; // "EXPP" uint32_t size; char value[size]; } EXPP struct { uint32_t magic; // "AUTH" uint32_t size; char author[size]; } AUTH - There is no footer, the last chunk (usually WAVE) goes to EOF Hope this helps!
×
×
  • Create New...