ref: caba3c6ab89bf631a0c12eab72d51d0353e0f782
dir: /src/wisescript.h/
/* This file is part of REWise. * * REWise is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * REWise is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ /* DISCLAIMER ---------- The way the data is interpreted may be very wrong! It is the result of many hours of puzzling with ImHex and this is what made the most sense to me with the data (different installer executables) available at this time. Also what most values represent inside a operation struct is still a mystery. Another source of getting insight on how the Wise installer handles this would be to disassemble wise0132.dll, I have done this with Cutter and its Ghidra plugin but it was very hard since I couldn't rename about half of the variables, which is a known issue of Cutter + the Ghidra plugin (at this time), but it gave some hints. INSEPCTED INSTALLERS -------------------- NAME MD5 FILE ---- --- ---- HL:CS (CD) 43cd9aff74e04fa1b59321b898d9a6bd counter-strike.exe HLGOTY (CD) f5b8b35ca02beeeb146e62a63a0273a6 SETUP.EXE CS15 eedcfcf6545cef92f26fb9a7fdd77c42 csv15full.exe RTCW (CD) f2d9e3e1eaaed66047210881d130384f Setup.exe ET 5cc104767ecdf0feb3a36210adf46a8e WolfET.exe The way this program currently interprets the binary Wise script file is as follows: 1. Read 'struct WiseScriptHeader' 2. Read 'struct WiseScriptTexts' 3. Read one byte as operation code, we use this value to determine what struct to read, after that struct is read, continue this step (read one operation byte again etc..) Operation codes: 0x00 // Custom deflate file header 0x03 // ? 0x04 // Form data? 0x05 // .ini file, section-name and values for that section 0x06 // Deflated file just used by the installer? (No filename) 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D // Skip this byte? 0x0F // Start form data? 0x10 // End form data? 0x11 0x12 // File on install medium (CD/DVD), to copy? 0x14 // Deflated file just used by the installer? (No filename) 0x15 0x16 // Temp filename? 0x17 0x18 // Skip this byte? ET suggests to skip all tailing zeros 0x23 0x24 // Skip this byte? Only seen in RTCW 0x25 // Skip this byte? Only seen in RTCW 0x1B // Skip this byte? 0x1C 0x1E */ #ifndef H_WISESCRIPT #define H_WISESCRIPT #include <stdio.h> #include <stdint.h> #include "errors.h" #define WIN_PATH_MAX 260 /* WiseScriptHeader */ typedef struct { unsigned char unknown_44[44]; char * logPath; // \0 terminated string char * font; // \0 terminated string unsigned char unknown_14[14]; } WiseScriptHeader; /* WiseScriptTexts */ typedef struct { // 56 \0 terminated strings char * installTexts[56]; } WiseScriptTexts; /* 0x00 WiseScriptFileHeader */ typedef struct { unsigned char unknown_2[2]; // seen: 0x8000, 0x8100, 0x0000, 0x9800 0xA100 uint32_t deflateStart; uint32_t deflateEnd; uint16_t date; uint16_t time; uint32_t inflatedSize; unsigned char unknown_40[20]; uint32_t crc32; char * destFile; // \0 terminated string char * fileText; // \0 terminated string unsigned char terminator; // always \0? terminator? } WiseScriptFileHeader; /* WiseScriptUnknown0x03 */ typedef struct { unsigned char unknown_1; // unknown char * unknownString_1; // \0 terminated string char * unknownString_2; // \0 terminated string } WiseScriptUnknown0x03; /* WiseScriptUnknown0x04 Form data? */ typedef struct { unsigned char no; // read this struct again until 'no' == 0 ? char * dataString; // \0 terminated string } WiseScriptUnknown0x04; /* WiseScriptUnknown0x05 Something with .ini file */ typedef struct { // write .ini file? char * file; // open for writing in append mode char * section; // ini section text char * values; // multiline string containing values. } WiseScriptUnknown0x05; /* WiseScriptUnknown0x06 deflated Wise file? */ typedef struct { unsigned char unknown[6]; uint32_t deflateStart; uint32_t deflateEnd; uint32_t inflatedSize; unsigned char unknown1; // terminator? } WiseScriptUnknown0x06; /* WiseScriptUnknown0x07 */ typedef struct { unsigned char unknown_1; char * unknownString_1; char * unknownString_2; char * unknownString_3; } WiseScriptUnknown0x07; /* WiseScriptUnknown0x08 */ typedef struct { unsigned char unknown_1; } WiseScriptUnknown0x08; /* WiseScriptUnknown0x09 */ typedef struct { unsigned char unknown_1; unsigned char unknown_2; // only when NOT 0x0901 or 0x0920 char * unknownString_1; char * unknownString_2; char * unknownString_3; char * unknownString_4; char * unknownString_5; // only when 0x0901 or 0x0920 } WiseScriptUnknown0x09; /* WiseScriptUnknown0x0A */ typedef struct { unsigned char unknown_2[2]; // 0x0200 char * unknownString_1; char * unknownString_2; char * unknownString_3; } WiseScriptUnknown0x0A; /* WiseScriptUnknown0x0B */ typedef struct { unsigned char unknown_1; char * unknownString_1; } WiseScriptUnknown0x0B; /* WiseScriptUnknown0x0C */ typedef struct { unsigned char unknown_1; char * unknownString_1; char * unknownString_2; } WiseScriptUnknown0x0C; /* WiseScriptUnknown0x11 */ typedef struct { char * unknownString_1; } WiseScriptUnknown0x11; /* WiseScriptUnknown0x12 File on install medium (CD/DVD) */ typedef struct { unsigned char unknown_1; // 0C unsigned char unknown_41[41]; char * sourceFile; char * unknownString_1; char * unknownString_2; char * destFile; } WiseScriptUnknown0x12; /* WiseScriptUnknown0x14 Wise script file? */ typedef struct { uint32_t deflateStart; uint32_t deflateEnd; uint32_t inflatedSize; char * name; char * message; } WiseScriptUnknown0x14; /* WiseScriptUnknown0x15 */ typedef struct { unsigned char unknown_1; char * unknownString_1; char * unknownString_2; } WiseScriptUnknown0x15; /* WiseScriptUnknown0x16 (TempFileName) */ typedef struct { char * name; } WiseScriptUnknown0x16; /* WiseScriptUnknown0x17 */ typedef struct { unsigned char unknown_1; unsigned char unknown_4[4]; char * unknownString_1; } WiseScriptUnknown0x17; /* WiseScriptUnknown0x1C */ typedef struct { char * unknownString_1; } WiseScriptUnknown0x1C; /* WiseScriptUnknown0x1E */ typedef struct { unsigned char unknown_2[2]; } WiseScriptUnknown0x1E; /* WiseScriptUnknown0x23 */ typedef struct { unsigned char unknown_1; char * unknownString_1; char * unknownString_2; } WiseScriptUnknown0x23; REWError readWiseScriptHeader(FILE * fp, WiseScriptHeader * header); REWError readWiseScriptTexts(FILE * fp, WiseScriptTexts * texts); REWError readWiseScriptFileHeader(FILE * fp, WiseScriptFileHeader * data); REWError readWiseScriptUnknown0x03(FILE * fp, WiseScriptUnknown0x03 * data); REWError readWiseScriptUnknown0x04(FILE * fp, WiseScriptUnknown0x04 * data); REWError readWiseScriptUnknown0x05(FILE * fp, WiseScriptUnknown0x05 * data); REWError readWiseScriptUnknown0x06(FILE * fp, WiseScriptUnknown0x06 * data); // no-free (no strings) REWError readWiseScriptUnknown0x07(FILE * fp, WiseScriptUnknown0x07 * data); REWError readWiseScriptUnknown0x08(FILE * fp, WiseScriptUnknown0x08 * data); // no-free (no strings) REWError readWiseScriptUnknown0x09(FILE * fp, WiseScriptUnknown0x09 * data); REWError readWiseScriptUnknown0x0A(FILE * fp, WiseScriptUnknown0x0A * data); REWError readWiseScriptUnknown0x0B(FILE * fp, WiseScriptUnknown0x0B * data); REWError readWiseScriptUnknown0x0C(FILE * fp, WiseScriptUnknown0x0C * data); REWError readWiseScriptUnknown0x11(FILE * fp, WiseScriptUnknown0x11 * data); REWError readWiseScriptUnknown0x12(FILE * fp, WiseScriptUnknown0x12 * data); REWError readWiseScriptUnknown0x14(FILE * fp, WiseScriptUnknown0x14 * data); REWError readWiseScriptUnknown0x15(FILE * fp, WiseScriptUnknown0x15 * data); REWError readWiseScriptUnknown0x16(FILE * fp, WiseScriptUnknown0x16 * data); REWError readWiseScriptUnknown0x17(FILE * fp, WiseScriptUnknown0x17 * data); REWError readWiseScriptUnknown0x1C(FILE * fp, WiseScriptUnknown0x1C * data); REWError readWiseScriptUnknown0x1E(FILE * fp, WiseScriptUnknown0x1E * data); // no-free (no strings) REWError readWiseScriptUnknown0x23(FILE * fp, WiseScriptUnknown0x23 * data); void freeWiseScriptHeader(WiseScriptHeader * header); void freeWiseScriptTexts(WiseScriptTexts * texts); void freeWiseScriptFileHeader(WiseScriptFileHeader * data); void freeWiseScriptUnknown0x03(WiseScriptUnknown0x03 * data); void freeWiseScriptUnknown0x04(WiseScriptUnknown0x04 * data); void freeWiseScriptUnknown0x05(WiseScriptUnknown0x05 * data); void freeWiseScriptUnknown0x07(WiseScriptUnknown0x07 * data); void freeWiseScriptUnknown0x09(WiseScriptUnknown0x09 * data); void freeWiseScriptUnknown0x0A(WiseScriptUnknown0x0A * data); void freeWiseScriptUnknown0x0B(WiseScriptUnknown0x0B * data); void freeWiseScriptUnknown0x0C(WiseScriptUnknown0x0C * data); void freeWiseScriptUnknown0x11(WiseScriptUnknown0x11 * data); void freeWiseScriptUnknown0x12(WiseScriptUnknown0x12 * data); void freeWiseScriptUnknown0x14(WiseScriptUnknown0x14 * data); void freeWiseScriptUnknown0x15(WiseScriptUnknown0x15 * data); void freeWiseScriptUnknown0x16(WiseScriptUnknown0x16 * data); void freeWiseScriptUnknown0x17(WiseScriptUnknown0x17 * data); void freeWiseScriptUnknown0x1C(WiseScriptUnknown0x1C * data); void freeWiseScriptUnknown0x23(WiseScriptUnknown0x23 * data); // For debugging void printWiseScriptHeader(WiseScriptHeader * header); void printWiseScriptTexts(WiseScriptTexts * texts); void printWiseScriptFileHeader(WiseScriptFileHeader * data); void printWiseScriptUnknown0x03(WiseScriptUnknown0x03 * data); void printWiseScriptUnknown0x04(WiseScriptUnknown0x04 * data); void printWiseScriptUnknown0x05(WiseScriptUnknown0x05 * data); void printWiseScriptUnknown0x06(WiseScriptUnknown0x06 * data); void printWiseScriptUnknown0x07(WiseScriptUnknown0x07 * data); void printWiseScriptUnknown0x08(WiseScriptUnknown0x08 * data); void printWiseScriptUnknown0x09(WiseScriptUnknown0x09 * data); void printWiseScriptUnknown0x0A(WiseScriptUnknown0x0A * data); void printWiseScriptUnknown0x0B(WiseScriptUnknown0x0B * data); void printWiseScriptUnknown0x0C(WiseScriptUnknown0x0C * data); void printWiseScriptUnknown0x11(WiseScriptUnknown0x11 * data); void printWiseScriptUnknown0x12(WiseScriptUnknown0x12 * data); void printWiseScriptUnknown0x14(WiseScriptUnknown0x14 * data); void printWiseScriptUnknown0x15(WiseScriptUnknown0x15 * data); void printWiseScriptUnknown0x16(WiseScriptUnknown0x16 * data); void printWiseScriptUnknown0x17(WiseScriptUnknown0x17 * data); void printWiseScriptUnknown0x1C(WiseScriptUnknown0x1C * data); void printWiseScriptUnknown0x1E(WiseScriptUnknown0x1E * data); void printWiseScriptUnknown0x23(WiseScriptUnknown0x23 * data); typedef struct { void (*cb_header)(WiseScriptHeader*); void (*cb_texts)(WiseScriptTexts*); void (*cb_0x00)(WiseScriptFileHeader*); void (*cb_0x03)(WiseScriptUnknown0x03*); void (*cb_0x04)(WiseScriptUnknown0x04*); void (*cb_0x05)(WiseScriptUnknown0x05*); void (*cb_0x06)(WiseScriptUnknown0x06*); void (*cb_0x07)(WiseScriptUnknown0x07*); void (*cb_0x08)(WiseScriptUnknown0x08*); void (*cb_0x09)(WiseScriptUnknown0x09*); void (*cb_0x0A)(WiseScriptUnknown0x0A*); void (*cb_0x0B)(WiseScriptUnknown0x0B*); void (*cb_0x0C)(WiseScriptUnknown0x0C*); void (*cb_0x0F)(void); // start form data? void (*cb_0x10)(void); // end form data? void (*cb_0x11)(WiseScriptUnknown0x11*); void (*cb_0x12)(WiseScriptUnknown0x12*); void (*cb_0x14)(WiseScriptUnknown0x14*); void (*cb_0x15)(WiseScriptUnknown0x15*); void (*cb_0x16)(WiseScriptUnknown0x16*); void (*cb_0x17)(WiseScriptUnknown0x17*); void (*cb_0x1C)(WiseScriptUnknown0x1C*); void (*cb_0x1E)(WiseScriptUnknown0x1E*); void (*cb_0x23)(WiseScriptUnknown0x23*); } WiseScriptCallbacks; typedef struct { size_t totalInflatedSize; size_t inflatedSize0x00; size_t inflatedSize0x06; size_t inflatedSize0x14; // Deflated files described in the WiseScript have a offset to the deflated // data, but this offset also has a offset which we can be found by iterating // through all file structs and note the largest end-deflate offset, use that // to subtract from the filesize. // // PE_filesize - largestEndDeflate // // This offset needs to be added to the offset described in the WiseScript to // get to the real offset of the deflated data. uint32_t inflateStartOffset; } WiseScriptParsedInfo; void initWiseScriptCallbacks(WiseScriptCallbacks * callbacks); REWError parseWiseScript(const char * filepath, WiseScriptCallbacks * callbacks); void stopWiseScriptParse(void); WiseScriptParsedInfo * wiseScriptGetParsedInfo(const char * filepath); // Debug print the parsed WiseScript structures REWError wiseScriptDebugPrint(const char * filepath); char * wiseScriptParsePath(char * path); #endif