beanieaxolotl Posted August 28 Share Posted August 28 (edited) Figured this was the best place to post this: my original post is here. I am currently having difficulty on trying to decompress the LZO data from a .ghx2 file, or the original project file for music made with the GAX Sound Engine. I would like to be able to decompress the data so I can easily reverse-engineer the sequence data format. The only known "decompressors" I can find readily available are GAXPlay.exe and GAX.ocx. I could not find any matching LZO algorithms for the data; QuickBMS didn't find any matches (even with brute-forcing). The few LZO decompression executables that I could find didn't even know what to do. The LZO data is unheadered (i.e no LZOD header). I have separated the relevant data into a .bin file. ghx2_lzo.zip Edited September 7 by beanieaxolotl Small correction Link to comment Share on other sites More sharing options...
beanieaxolotl Posted August 31 Author Share Posted August 31 (edited) I managed to find a portion of the uncompressed sample data stream in GAXPlay's memory (via Cheat Engine), and found a corresponding portion in the raw LZO stream. I ripped both of these from the .ghx2 project file for Tak - The Great Juju Challenge (tak_3_04.ghx2). compressed.bin is from the file data itself, and uncompressed.bin was ripped from GAXPlay's memory. The samples are formatted in an uncompressed signed 16-bit PCM stream, if this helps. tak_examples.zip Edited August 31 by beanieaxolotl Clarification, and fixed silly error 1 Link to comment Share on other sites More sharing options...
Solution barncastle Posted December 13 Solution Share Posted December 13 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! 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now