// Kong bigfile unpacker // (c) th0mas 2006 // th0mas.sixbit.org@gmail.com #include #include typedef unsigned char uint8_t; typedef unsigned int uint32_t; typedef struct { uint32_t offset; uint32_t unknown; } __attribute__((packed)) offset_t; typedef struct { uint32_t unk1; // unknown meaning uint32_t size; uint32_t unk2[4]; // unknown, although I think the last one is maybe directory entry? unsigned char fileName[64]; } __attribute__((packed)) fileinfo_t; // also at 0x08, don't know if they're always the exact same.. #define NUMFILES_OFFSET 0x2c // these seem to be the same for all 2 of the bf files I have #define OFFSETS_START 0x44 #define FILENAMES_START 0x138c0 #define BUF_SIZE 4096 int ripFile(FILE *in, uint32_t start, uint32_t dataleft, char *outputFile, uint8_t *buf) { fseek(in, start, SEEK_SET); FILE *out = fopen(outputFile, "wb"); if (!out) return 1; while (dataleft >= BUF_SIZE) { fread(buf, sizeof(uint8_t), BUF_SIZE, in); // makes bad assumption of no file read errors fwrite(buf, sizeof(uint8_t), BUF_SIZE, out); dataleft -= BUF_SIZE; } if (dataleft) { fread(buf, sizeof(uint8_t), dataleft, in); fwrite(buf, sizeof(uint8_t), dataleft, out); } fclose(out); } int main(int argc, char **argv) { uint8_t *buf; uint32_t numFiles; char nameBuf[128]; offset_t *fileOffsets; fileinfo_t *fileInfos; FILE *in; int i; if (argc != 3) { printf("Usage: %s \n", argv[1]); return 1; } // read bigfile header in = fopen(argv[1], "rb"); fseek(in, NUMFILES_OFFSET, SEEK_SET); fread(&numFiles, sizeof(uint32_t), 1, in); fileOffsets = (offset_t *) malloc(sizeof(offset_t) * numFiles); memset(fileOffsets, 0x00, sizeof(offset_t) * numFiles); fileInfos = (fileinfo_t *) malloc(sizeof(fileinfo_t) * numFiles); memset(fileInfos, 0x00, sizeof(fileinfo_t) * numFiles); // read in offset entries fseek(in, OFFSETS_START, SEEK_SET); fread(fileOffsets, sizeof(offset_t) * numFiles, 1, in); // read in filename entries fseek(in, FILENAMES_START, SEEK_SET); fread(fileInfos, sizeof(fileinfo_t) * numFiles, 1, in); for (i = 0; i < numFiles; i++) { // correct offset since it points to filesize, followed by payload fileOffsets[i].offset += 4; printf("0x%08x 0x%08x %s\n", fileInfos[i].size, fileOffsets[i].offset, (char *) fileInfos[i].fileName); } buf = (uint8_t *) malloc(sizeof(uint8_t) * BUF_SIZE); for (i = 0; i < numFiles; i++) { printf("Ripping %s...\n", (char *) fileInfos[i].fileName); sprintf(nameBuf, "%s/%s", argv[2], fileInfos[i].fileName); ripFile(in, fileOffsets[i].offset, fileInfos[i].size, nameBuf, buf); } fclose(in); }