Created
October 20, 2017 16:44
-
-
Save andwn/5a9cbcea24700eb9d6f2335a57340968 to your computer and use it in GitHub Desktop.
Revisions
-
andwn created this gist
Oct 20, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,90 @@ // Compile // gcc flax.c -o flax // Usage // ./flax <input file> // Outputs decompressed data to <input file>.out #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // Based on disassembled Glover.exe sub_4C6E40 int flax(uint8_t *src, uint8_t *dest) { int outSize = 0; uint8_t ring[0x1000]; uint16_t ringPos = 0; memset(ring, 0, 0x1000); uint8_t command; LABEL_2: command = *src++; for(int i = 0; ; ++i) { if(i == 8) goto LABEL_2; if(!(command & 0x80)) { uint8_t val = *src++; *dest++ = val; ++outSize; ring[ringPos] = val; ringPos = (ringPos + 1) & 0xFFF; command *= 2; continue; } uint8_t dataLen = *src; if(!dataLen) break; uint8_t *dataPtr = src + 1; int16_t dataRingPos = 4096 - (*dataPtr + 16 * (dataLen & 0xF0)); src = dataPtr + 1; for(int j = (dataLen & 0xF) + 2; j; --j) { uint8_t val = ring[(ringPos + dataRingPos) & 0xFFF]; *dest++ = val; ++outSize; ring[ringPos] = val; ringPos = (ringPos + 1) & 0xFFF; } command *= 2; } return outSize; } int main(int argc, char *argv[]) { uint8_t buffer[0x400000]; // 4MB decompression buffer if(argc != 2) { printf("Usage: flax <input file>\n"); return EXIT_SUCCESS; } FILE *file = fopen(argv[1], "rb"); if(!file) { printf("FATAL: Failed to read input file '%s'.\n", argv[1]); return EXIT_FAILURE; } fseek(file, 0, SEEK_END); int size = ftell(file); fseek(file, 0, SEEK_SET); uint8_t *fla = malloc(size); fread(fla, 1, size, file); fclose(file); printf("Loaded %d byte file.\n", size); if(fla[0]=='F' && fla[1]=='L' && fla[2]=='A' && fla[3]=='2') { int decSize = flax(&fla[8], buffer); printf("%d bytes extracted.\n", decSize); char fn[256]; sprintf(fn, "%s.out", argv[1]); file = fopen(fn, "wb"); if(!file) { printf("\nERROR: Unable to write output file '%s'.\n", fn); } else { fwrite(buffer, 1, decSize, file); fclose(file); } } else { printf("...but it's not FLA compressed.\n"); } free(fla); return EXIT_SUCCESS; }