From 53c9f28674b718c25cc915ac1c784e49bf2e5a39 Mon Sep 17 00:00:00 2001 From: Abaresk Date: Sun, 3 Apr 2022 13:07:52 +0000 Subject: [PATCH 1/5] Decompile compstatic tool --- Makefile | 2 +- common.mk | 7 +- tools/compstatic/.gitignore | 1 + tools/compstatic/Makefile | 16 ++ tools/compstatic/component.c | 189 +++++++++++++++ tools/compstatic/component.h | 10 + tools/compstatic/compress.c | 352 +++++++++++++++++++++++++++ tools/compstatic/compress.h | 11 + tools/compstatic/digest.c | 376 +++++++++++++++++++++++++++++ tools/compstatic/digest.h | 19 ++ tools/compstatic/files.c | 154 ++++++++++++ tools/compstatic/files.h | 12 + tools/compstatic/global.h | 77 ++++++ tools/compstatic/main.c | 135 +++++++++++ tools/compstatic/misc.c | 55 +++++ tools/compstatic/misc.h | 10 + tools/compstatic/overlay_defs.c | 88 +++++++ tools/compstatic/overlay_defs.h | 17 ++ tools/compstatic/overlay_modules.c | 151 ++++++++++++ tools/compstatic/overlay_modules.h | 12 + tools/compstatic/overlay_table.c | 80 ++++++ tools/compstatic/overlay_table.h | 12 + tools/compstatic/print.c | 22 ++ tools/compstatic/print.h | 7 + tools/compstatic/static_module.c | 77 ++++++ tools/compstatic/static_module.h | 12 + tools/compstatic/str.c | 53 ++++ tools/compstatic/str.h | 7 + 28 files changed, 1961 insertions(+), 3 deletions(-) create mode 100644 tools/compstatic/.gitignore create mode 100644 tools/compstatic/Makefile create mode 100644 tools/compstatic/component.c create mode 100644 tools/compstatic/component.h create mode 100644 tools/compstatic/compress.c create mode 100644 tools/compstatic/compress.h create mode 100644 tools/compstatic/digest.c create mode 100644 tools/compstatic/digest.h create mode 100644 tools/compstatic/files.c create mode 100644 tools/compstatic/files.h create mode 100644 tools/compstatic/global.h create mode 100644 tools/compstatic/main.c create mode 100644 tools/compstatic/misc.c create mode 100644 tools/compstatic/misc.h create mode 100644 tools/compstatic/overlay_defs.c create mode 100644 tools/compstatic/overlay_defs.h create mode 100644 tools/compstatic/overlay_modules.c create mode 100644 tools/compstatic/overlay_modules.h create mode 100644 tools/compstatic/overlay_table.c create mode 100644 tools/compstatic/overlay_table.h create mode 100644 tools/compstatic/print.c create mode 100644 tools/compstatic/print.h create mode 100644 tools/compstatic/static_module.c create mode 100644 tools/compstatic/static_module.h create mode 100644 tools/compstatic/str.c create mode 100644 tools/compstatic/str.h diff --git a/Makefile b/Makefile index d217c26fa..d55700696 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ libsyscall: $(MAKE) -C lib/syscall all install INSTALL_PREFIX=$(abspath $(WORK_DIR)/$(BUILD_DIR)) GAME_CODE=$(GAME_CODE) $(SBIN_LZ): $(BUILD_DIR)/component.files - $(WINE) $(COMPSTATIC) -9 -c -f $< + $(COMPSTATIC) -9 -c -f $< $(BUILD_DIR)/component.files: main ; diff --git a/common.mk b/common.mk index bdc21608d..6c27499ec 100644 --- a/common.mk +++ b/common.mk @@ -25,7 +25,6 @@ MAKEROM := $(TOOLSDIR)/bin/makerom.exe MAKELCF := $(TOOLSDIR)/bin/makelcf.exe MAKEBNR := $(TOOLSDIR)/bin/makebanner.exe NTRCOMP := $(TOOLSDIR)/bin/ntrcomp.exe -COMPSTATIC := $(TOOLSDIR)/bin/compstatic.exe export LM_LICENSE_FILE := $(TOOLSDIR)/mwccarm/license.dat @@ -40,6 +39,9 @@ ASPATCH := $(TOOLSDIR)/mwasmarm_patcher/mwasmarm_patcher$(EXE) CSV2BIN := $(TOOLSDIR)/csv2bin/csv2bin$(EXE) MKFXCONST := $(TOOLSDIR)/gen_fx_consts/gen_fx_consts$(EXE) +# Decompiled NitroSDK tools +COMPSTATIC := $(TOOLSDIR)/compstatic/compstatic$(EXE) + NTRMERGE := $(TOOLSDIR)/ntr_merge_elf/ntr_merge_elf.sh NATIVE_TOOLS := \ @@ -51,7 +53,8 @@ NATIVE_TOOLS := \ $(MSGENC) \ $(ASPATCH) \ $(CSV2BIN) \ - $(MKFXCONST) + $(MKFXCONST) \ + $(COMPSTATIC) TOOLDIRS := $(foreach tool,$(NATIVE_TOOLS),$(dir $(tool))) diff --git a/tools/compstatic/.gitignore b/tools/compstatic/.gitignore new file mode 100644 index 000000000..0ccf76ad4 --- /dev/null +++ b/tools/compstatic/.gitignore @@ -0,0 +1 @@ +compstatic diff --git a/tools/compstatic/Makefile b/tools/compstatic/Makefile new file mode 100644 index 000000000..5fefbbec2 --- /dev/null +++ b/tools/compstatic/Makefile @@ -0,0 +1,16 @@ +CC := gcc +CFLAGS := -O3 + +SRCS = $(wildcard *.c) +INCLUDES = $(wildcard *.h) + +.PHONY: all clean + +all: compstatic + @: + +compstatic: $(SRCS) $(INCLUDES) + $(CC) $(CFLAGS) -o $@ $^ + +clean: + $(RM) compstatic compstatic.exe diff --git a/tools/compstatic/component.c b/tools/compstatic/component.c new file mode 100644 index 000000000..ab8f337f9 --- /dev/null +++ b/tools/compstatic/component.c @@ -0,0 +1,189 @@ +#include +#include +#include "component.h" +#include "compress.h" +#include "global.h" +#include "overlay_defs.h" +#include "overlay_modules.h" +#include "overlay_table.h" +#include "print.h" +#include "static_module.h" +#include "str.h" + +static bool ReadComponent(Component *component, char *a1, char *a2, char *overlayTable); +static bool WriteComponent(Component *component); +static bool ComponentAddSuffix(Component *component, char *suffix); +static void FreeComponent(Component *component); +static void DebugPrintComponent(Component *component); + +bool ConvertComponent(Options *options, char *staticModule, char *overlayDefs, char *overlayTable) { + bool finalSuccess = false; + Component component; + memset(&component, 0, sizeof(component)); + + bool success = ReadComponent(&component, staticModule, overlayDefs, overlayTable); + if (success) { + DebugPrintComponent(&component); + if (!options->overlayModules || CompressOverlayModules(&component)) { + if (!options->overlayDigest || CalculateHMAC_OverlayModules(&component, options->unk10, options->digestKey)) { + if (!options->staticModule || CompressStaticModule(&component, options->headerSize)) { + if (options->outSuffix == NULL || ComponentAddSuffix(&component, options->outSuffix)) { + DebugPrintComponent(&component); + finalSuccess = WriteComponent(&component); + } + } + } + } + } + + FreeComponent(&component); + return finalSuccess; +} + +static bool ReadComponent(Component *component, char *staticModule, char *overlayDefs, char *overlayTable) { + bool finalSuccess = false; + + bool success = ReadOverlayDefs(component, overlayDefs); + if (success) { + success = ReadStaticModule(component, staticModule); + if (success) { + success = ReadOverlayTable(component, overlayTable); + if (success) { + finalSuccess = ReadOverlayModules(component); + } + } + } + + return finalSuccess; +} + +static bool WriteComponent(Component *component) { + bool finalSuccess = false; + + bool success = WriteOverlayDefs(component); + if (success) { + success = WriteStaticModule(component); + if (success) { + success = WriteOverlayTable(component); + if (success) { + finalSuccess = WriteOverlayModules(component); + } + } + } + + return finalSuccess; +} + +static bool ComponentAddSuffix(Component *component, char *suffix) { + if (suffix == NULL || suffix == "") return true; + + bool finalSuccess = false; + bool success = AddSuffixOverlayDefs(component, suffix); + if (success) { + success = AddSuffixStaticModule(component, suffix); + if (success) { + success = AddSuffixOverlayTable(component, suffix); + if (success) { + finalSuccess = AddSuffixOverlayModules(component, suffix); + } + } + } + + return finalSuccess; +} + +static void FreeComponent(Component *component) { + FreeOverlayDefs(component); + FreeStaticModule(component); + FreeOverlayTable(component); + FreeOverlayModules(component); + component->numOverlays = 0; +} + +static void DebugPrintComponent(Component *component) { + int i; + char *filename; + char c; + uint staticParamsOffset = *(uint *)(component->staticModule.footerContent + 4); + + DebugPrintf("-------------------------------------------------------------\n"); + + // TODO: Replace offsets with constants! + DebugPrintf("static.buffer.filename = %s\n" + " .ptr = %p\n" + " .size = %p %9d\n" + " .compressed = %p %9d\n" + " .footerSize = %p %9d\n" + " .footer = %p\n" + " .footer.magicNumber = %08x %9s\n" + " .staticParamsOffset = %p %9d\n" + " .digestParamsOffset = %p %9d\n", + component->staticModule.fileInfo.filename, + component->staticModule.fileInfo.content, + component->staticModule.fileInfo.fileSize, component->staticModule.fileInfo.fileSize, + component->staticModule.fileInfo.unkC, component->staticModule.fileInfo.unkC, + component->staticModule.footerSize, component->staticModule.footerSize, + component->staticModule.footerContent, + *(uint *)(component->staticModule.footerContent), (*(uint *)(component->staticModule.footerContent) == 0xDEC00621) ? "NITROCODE" : "UNKNOWN!!", + *(uint *)(component->staticModule.footerContent + 4), *(uint *)(component->staticModule.footerContent + 4), + *(uint *)(component->staticModule.footerContent + 8), *(uint *)(component->staticModule.footerContent + 8)); + + // TODO: Replace offsets with constants! + DebugPrintf("static.Params = %p\n" + " .Params.autoloadList = %p\n" + " .Params.autoloadListEnd = %p\n" + " .Params.autoloadStart = %p\n" + " .Params.staticBssStart = %p\n" + " .Params.staticBssEnd = %p\n" + " .Params.compressedStatic = %p\n", + component->staticModule.fileInfo.content + staticParamsOffset, + *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset), + *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 4), + *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 8), + *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 12), + *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 16), + *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 20)); + + DebugPrintf("-------------------------------------------------------------\n"); + DebugPrintf("numOverlays = %d\n", component->numOverlays); + DebugPrintf("-------------------------------------------------------------\n"); + + // TODO: Replace offsets with constants! + DebugPrintf("ovdefs.buffer.filename = %s\n" + " .ptr = %p\n" + " .size = %p %9d\n" + " .compressed = %p %9d\n" + " .header = %p\n" + " .header.loadAddress = %p\n" + " .header.entryAddress = %p\n" + " .header.moduleSize = %p %9d\n" + " .header.autoloadDone = %p\n" + " .dirname = %s\n", + component->overlayDefs.fileInfo.filename, + component->overlayDefs.fileInfo.content, + &component->overlayDefs.fileInfo.fileSize, component->overlayDefs.fileInfo.fileSize, + &component->overlayDefs.fileInfo.unkC, component->overlayDefs.fileInfo.unkC, + component->overlayDefs.content_dup, + *(uint *)(component->overlayDefs.content_dup + 0), + *(uint *)(component->overlayDefs.content_dup + 4), + component->overlayDefs.content_dup + 8, *(uint *)(component->overlayDefs.content_dup + 8), + *(uint *)(component->overlayDefs.content_dup + 12), + component->dirName); + + filename = component->overlayFilenames; + for (i = 0; i < component->numOverlays; i++) { + DebugPrintf(" .filename[%2d] = %s\n", i, filename); + do { + c = *filename; + filename++; + } while (c != '\0'); + } + + DebugPrintf("-------------------------------------------------------------\n"); + DebugPrintf("-------------------------------------------------------------\n"); +} + +void ConvertFinal(Options *options) { + options->digestKey = StrDup(options->digestKey, NULL); + options->outSuffix = StrDup(options->outSuffix, NULL); +} diff --git a/tools/compstatic/component.h b/tools/compstatic/component.h new file mode 100644 index 000000000..51226f8d0 --- /dev/null +++ b/tools/compstatic/component.h @@ -0,0 +1,10 @@ +#ifndef COMPONENT_H +#define COMPONENT_H + +#include +#include "global.h" + +bool ConvertComponent(Options *options, char *a1, char *a2, char *overlayTable); +void ConvertFinal(Options *options); // TODO: Remove if this goes unused + +#endif // COMPONENT_H diff --git a/tools/compstatic/compress.c b/tools/compstatic/compress.c new file mode 100644 index 000000000..5986b216b --- /dev/null +++ b/tools/compstatic/compress.c @@ -0,0 +1,352 @@ +#include +#include +#include +#include "component.h" +#include "compress.h" +#include "digest.h" +#include "global.h" +#include "misc.h" +#include "print.h" + +static int Compress(char *content, int size); +static int LZCompressRV(char *uncompressed, int uncompressedSize, char *compressed, int compressedSize); +static int FindMatched(char *chunk, int chunkSize, char *remainder, int remainderSize, int *optimalRemainderIdx); +static int HowManyMatched(char *buffer1, char *buffer2, int size); +static int CheckOverwrite(int sourceSize, char *compressed, int compressedSize, int *newSourceSize, int *newCompressedSize); + +bool CompressOverlayModules(Component *component) { + OverlayModule *overlayModule = component->overlayModules; + char *contentDup = component->overlayTable.content_dup; + DebugPrintf("Compressing OverlayModules\n"); + if (component->numOverlays == 0 || overlayModule == NULL || contentDup == NULL) { + DebugPrintf("No overlay to compress\n"); + } else { + for (int i = 0; i < component->numOverlays; i++) { + // TODO: Replace offset with a constant! + if ((contentDup[0x1f] & 1) == 0) { + // TODO: Replace offset with a constant! Seems to be file size from overlay table + // TODO: Do I need to use (uint)?? + if ((uint)overlayModule->fileInfo.fileSize < *(uint *)(contentDup + 8)) { + ErrorPrintf("Overlay module file is shorter than the size reported in the overlay table\n" + "FileSize=%d InOverlayTable=%d\n", overlayModule->fileInfo.fileSize, *(uint *)(contentDup + 8)); + return false; + } + // TODO: Try making this an int!! + uint compressResult = Compress(overlayModule->fileInfo.content, *(int *)(contentDup + 8)); + if ((int)compressResult < 0) { + if ((int)compressResult == -2 || (int)compressResult != -1) return false; + + printf("OverlayModule[%02d]. Not compressed %9d (enlarged or same size as before)\n", i, overlayModule->fileInfo.fileSize); + } else { + if ((int)compressResult > 0x00ffffff) { + ErrorPrintf("Compressed file size too large (over 24bit wide)\n"); + } + printf("OverlayModule[%02d]. Compressed ... %9d -> %9d\n", i, overlayModule->fileInfo.fileSize, compressResult); + // TODO: Replace offset with a constant! + *(uint *)(contentDup + 0x1c) = (*(uint *)(contentDup + 0x1c) & 0xff000000) | (compressResult & 0x00ffffff); + overlayModule->fileInfo.unkC = compressResult & 0x00ffffff; + overlayModule->fileInfo.unkC = compressResult & 0x00ffffff; + contentDup[0x1f] |= 1; + overlayModule->fileInfo.unk10 = 1; + component->overlayTable.fileInfo.unk10 = 1; + } + } else { + printf("OverlayModule[%02d]. Already compressed\n", i); + } + overlayModule++; + contentDup += 0x20; + } + } + return true; +} + +bool CompressStaticModule(Component *component, int headerSize) { + bool success; + + // TODO: Make sure integer parsing works with big and little endian! + int footerPtr = *(int *)(component->staticModule.footerContent + 4); + char *content = component->staticModule.fileInfo.content; + // TODO: Replace offset with a constant! + if (*(int *)(content + footerPtr + 0x14) == 0 && + component->staticModule.fileInfo.unkC == 0) { + if (headerSize < 0) { + ErrorPrintf("Specified header size is less than 0 (=%d)\n", headerSize); + success = false; + } else if (component->staticModule.fileInfo.fileSize < headerSize) { + printf("StaticModule ..... Not compressed (Module is smaller than the header [%d bytes])\n", headerSize); + success = true; + } else { + int compressResult = + Compress(component->staticModule.fileInfo.content + headerSize, + component->staticModule.fileInfo.fileSize - headerSize); + if (compressResult < 0) { + if (compressResult == -2 || compressResult != -1) { + success = false; + } else { + printf("StaticModule ..... Not compressed (enlarged or same size as before)\n"); + success = true; + } + } else { + component->staticModule.fileInfo.unkC = compressResult + headerSize; + // TODO: Double-check the first arg! + printf("StaticModule ..... Compressed ... %9d -> %9d\n", + component->staticModule.fileInfo.fileSize, component->staticModule.fileInfo.unkC); + // TODO: Figure out what this var is (a header?) + int *unknown = (int *)component->overlayDefs.content_dup; + unknown[2] = component->staticModule.fileInfo.unkC; + // TODO: Replace offset with a constant! + *(int *)(content + footerPtr + 0x14) = component->staticModule.fileInfo.unkC + unknown[0]; + CopyBuffer(component->staticModule.footerContent, + // TODO: Consider making a macro: #define ALIGN_4(x) ((x + 3) & 0xfffffffc) + component->staticModule.fileInfo.content + ((component->staticModule.fileInfo.unkC + 3U) & 0xfffffffc), + component->staticModule.footerSize); + component->overlayDefs.fileInfo.unk10 = 1; + component->staticModule.fileInfo.unk10 = 1; + success = true; + } + } + } else { + printf("StaticModule ..... Already compressed\n"); + success = true; + } + return success; +} + +bool CalculateHMAC_OverlayModules(Component *component, int a1, char *digestKey) { + bool success; + + OverlayModule *overlayModule = component->overlayModules; + char *contentDup = component->overlayTable.content_dup; + int numOverlays = component->numOverlays; + if (numOverlays == 0 || overlayModule == NULL || contentDup == NULL) { + DebugPrintf("No overlay to calculate HMAC\n"); + success = true; + } else { + bool initDigestSuccess = Init_Digest(a1, digestKey); + if (!initDigestSuccess) { + ErrorPrintf("Cannot setup digest library\n"); + success = false; + } else { + DebugPrintf("Calculating HMAC for OverlayModules\n"); + // TODO: Fill in all the unknown vars and offsets below! + // NOTE TO SELF: Replaced `initDigestSuccess` re-use with new var `unknown3`. + int unknown3 = *(int *)(component->staticModule.footerContent + 8); + char *content = component->staticModule.fileInfo.content; + char *unknown1 = component->staticModule.fileInfo.content + *(int *)(component->staticModule.footerContent + 8); + for (int i = 0; i < numOverlays; i++) { + if (contentDup[0x1f] & 2U != 0) { + printf("OverlayModule[%02d]: HMAC already calculated - do it again.\n", i); + } + if ((uint)overlayModule->fileInfo.fileSize < *(uint *)(contentDup + 8)) { + ErrorPrintf("Overlay module file is shorter than the size reported in overlay table\n" + " File size=%d InOverlayTabe=%d\n", overlayModule->fileInfo.fileSize, *(uint *)(contentDup + 8)); + return false; + } + uint unknown2 = *(uint *)(contentDup + 0x1c) & 0x00ffffff; + if (unknown2 == 0) { + unknown2 = *(uint *)(contentDup + 8); + } + + printf("OverlayModule[%02d]", i); + Calc_Digest(overlayModule->fileInfo.content, unknown2, unknown1, 0); + contentDup[0x1f] |= 2; + component->staticModule.fileInfo.unk10 = 1; + component->overlayTable.fileInfo.unk10 = 1; + unknown1 += 0x14; + overlayModule++; + contentDup += 0x20; + } + printf("OverlayTable "); + Calc_Digest(component->overlayTable.content_dup, numOverlays << 5, content + unknown3 - 0x14, 1); + success = true; + } + } + return success; +} + +static int Compress(char *content, int size) { + int ret; + int sourceOffset; + int compressedOffset; + + char *compressed = malloc(size); + char *compressedCpy = compressed; + if (compressed == NULL) { + ErrorPrintf("Cannot allocate memory size=%d\n", size); + ret = -2; + } else if (((size_t)content % 4) == 0) { // CLEAN UP: Replaced (uint) cast with (size_t) cast + char *contentCpy = content; + int sizeCpy = size; + int compressedSize = size; + int lzResult = LZCompressRV(content, size, compressed, size); + if (lzResult < 0) { + DebugPrintf("Compressed buffer size exceeds original data size.\n"); + free(compressedCpy); + ret = -1; + } else { + compressedSize -= lzResult; + compressed += lzResult; + DebugPrintf("1: source size = %d compressed = %d\n", size, compressedSize); + // CLEAN UP: Replaced `lzResult` with `overWriteResult` + int overwriteResult = CheckOverwrite(sizeCpy, compressed, compressedSize, &sourceOffset, &compressedOffset); + if (overwriteResult == 0) { + contentCpy += sourceOffset; + sizeCpy -= sourceOffset; + compressed += compressedOffset; + compressedSize -= compressedOffset; + DebugPrintf(" !! Shrink back Compressed region to avoid overwriting.\n" + " !! Expand non-compressed region = +%d\n" + "2: source size = %d compressed = %d\n", sourceOffset, sizeCpy, compressedSize); + } + // CLEAN UP: Replaced `lzResult` with `compressedEnd` + int compressedEnd = compressedSize + sourceOffset; + uint compressedEndAligned = (compressedEnd + 3) & 0xfffffffc; + ret = compressedEndAligned + 8; + if (ret < size) { + CopyBuffer(compressed, contentCpy, compressedSize); + free(compressedCpy); + for (int i = compressedEnd; i < (int)compressedEndAligned; i++) { + content[i] = -1; + } + char *contentEnd = content + compressedEndAligned; + *(uint *)contentEnd = (*(uint *)contentEnd & 0xff000000) | (ret - sourceOffset) & 0xffffff; + char compressedEndU8 = (char)compressedEnd; + char retU8 = (char)ret; + *(contentEnd + 3) = retU8 - compressedEndU8; + *(int *)(contentEnd + 4) = size - ret; + } else { + DebugPrintf("Compressed buffer size exceeds or equals original data size.\n"); + free(compressedCpy); + ret = -1; + } + } + } else { + ErrorPrintf("Top of buffer is not aligned by 4.\n"); + ret = -2; + } + return ret; +} + +// Parameters: +// - A buffer with the uncompressed byte array, and size of buffer +// - A buffer for the compressed byte array, and size of buffer +static int LZCompressRV(char *uncompressed, int uncompressedSize, char *compressed, int compressedSize) { + int optimalRemainderIdx; + ushort optimalRemainderIdx16; + int bytesLeft = uncompressedSize; + while (true) { + if (bytesLeft < 1) return compressedSize; + if (compressedSize < 1) break; + + uint bitVector = 0; + int compressedPtr = compressedSize - 1; + compressedSize = compressedPtr; + for (int i = 0; i < 8; i++) { + bitVector <<= 1; + if (bytesLeft > 0) { + char *remainder = uncompressed + bytesLeft; + int bytesRead = uncompressedSize - bytesLeft; + int chunkSize = MIN(bytesLeft, 0x12); + // CLEAN UP: Removed var `unused` + char *chunk = remainder - chunkSize; + // CLEAN UP: Replaced `bytesReadLimit` with `bytesRead` + bytesRead = MIN(bytesRead, 0x1002); + int numMatches = FindMatched(chunk, chunkSize, remainder, bytesRead, &optimalRemainderIdx); + if (numMatches < 3) { + if (compressedSize < 1) return -1; + + compressedSize--; + bytesLeft--; + compressed[compressedSize] = uncompressed[bytesLeft]; + } else { + if (compressedSize < 2) return -1; + + bytesLeft -= numMatches; + optimalRemainderIdx -= 2; + optimalRemainderIdx16 = (ushort)optimalRemainderIdx & 0xfff; + compressed[compressedSize - 1] = + (char)((ushort)(((short)numMatches - 3) * 0x1000) >> 8) | (char)(optimalRemainderIdx16 >> 8); + compressedSize -= 2; + compressed[compressedSize] = (char)optimalRemainderIdx16; + bitVector |= 1; + } + } + } + compressed[compressedPtr] = (char)bitVector; + } + return -1; +} + +// `chunk` is a pointer to a section of the uncompressed byte array +// of size `chunkSize`. `remainder` is a pointer to the remainder of the +// byte array of size `remainderSize`. +// +// This function iterates over all the bytes after the chunk to find another +// chunk with the most bytes matching `chunk`. It returns the number of +// byte-wise matches found in the optimal chunk. +// +// `optimalRemainderIdx` points to the end of the optimal chunk. +static int FindMatched(char *chunk, int chunkSize, char *remainder, int remainderSize, int *optimalRemainderIdx) { + char lastChar = chunk[chunkSize - 1]; + int maxMatches = 0; + for (int i = 0; i < remainderSize; i++) { + if (lastChar == remainder[i]) { + int bufferSize = MIN(i + 1, chunkSize); + int numMatches = HowManyMatched(chunk + chunkSize - 1, remainder + i, bufferSize); + if (numMatches > maxMatches) { + *optimalRemainderIdx = i; + maxMatches = numMatches; + } + } + } + return maxMatches; +} + +// Returns the number of consecutive bytes that match in both buffers, starting +// from the end of each buffer. +static int HowManyMatched(char *buffer1, char *buffer2, int size) { + int i = 0; + for (; i < size && *buffer1 == *buffer2; buffer1--) { + buffer2--; + i++; + } + return i; +} + +static int CheckOverwrite(int sourceSize, char *compressed, int compressedSize, int *sourceOffset, int *compressedOffset) { + // CLEAN UP: Replaced `compressedSizeCpy` and `sourceSizeCpy` with + // `compressedSize` and `sourceSize`, respectively. + do { + if (sourceSize < 1) { + *sourceOffset = 0; + *compressedOffset = 0; + return 1; + } + compressedSize--; + uint bitVector = compressed[compressedSize]; + for (int i = 0; i < 8; i++) { + if (sourceSize > 0) { + if ((bitVector & 0x80) == 0) { + compressedSize--; + sourceSize--; + } else { + int nextCompressedSize = compressedSize - 2; + sourceSize -= ((byte)compressed[compressedSize - 1] >> 4) + 3; + if (sourceSize < 0) { + ErrorPrintf("System error in CheckOverwrite???\n"); + exit(-1); + } + compressedSize = nextCompressedSize; + if (sourceSize < nextCompressedSize) { + *sourceOffset = sourceSize; + // CLEAN UP: Replaced `nextCompressedSize` with `compressedSize`. + *compressedOffset = compressedSize; + return 0; + } + } + bitVector <<= 1; + } + } + + } while (true); +} diff --git a/tools/compstatic/compress.h b/tools/compstatic/compress.h new file mode 100644 index 000000000..140d495fc --- /dev/null +++ b/tools/compstatic/compress.h @@ -0,0 +1,11 @@ +#ifndef COMPRESS_H +#define COMPRESS_H + +#include +#include "component.h" + +bool CompressOverlayModules(Component *component); +bool CompressStaticModule(Component *component, int headerSize); +bool CalculateHMAC_OverlayModules(Component *component, int a1, char *digestKey); + +#endif // COMPRESS_H diff --git a/tools/compstatic/digest.c b/tools/compstatic/digest.c new file mode 100644 index 000000000..8fd38198c --- /dev/null +++ b/tools/compstatic/digest.c @@ -0,0 +1,376 @@ +#include +#include +#include +#include +#include +#include "digest.h" +#include "files.h" +#include "global.h" +#include "misc.h" +#include "print.h" + +typedef struct { + uint unk0; + uint unk4; + uint unk8; + uint unkC; + uint unk10; + uint unk14; + uint unk18; + int unk1C; + char unk20[0x40]; + uint unk60; + uint unk64; + char unk68[0xC]; +} HashWork; + +typedef bool (*Hash2ResetCb)(HashWork *hashWork); +typedef uint (*Hash2SetSourceCb)(HashWork *hashWork, char *digestKey, int digestKeySize); +typedef uint (*Hash2GetDigestCb)(HashWork *hashWork, char *digestBuffer); + +typedef struct { + int unk0; + int blockSize; + HashWork *hashWork; + char *unkC; + Hash2ResetCb hash2Reset; + Hash2SetSourceCb hash2SetSource; + Hash2GetDigestCb hash2GetDigest; +} HmacParam; + +static void DGT_Hash2CalcHmac(char *hash, char *content, int a2, char *a3, int a4); +static int DGT_SetOverlayTableMode(int mode); +static bool DGT_Hash2Reset(HashWork *hashWork); +static uint DGT_Hash2SetSource(HashWork *hashWork, char *digestKey, int digestKeySize); +static uint DGT_Hash2GetDigest(HashWork *hashWork, char *digestBuffer); +static void DGT_Hash2SetPadding(HashWork *hashWork); +static void DGT_Hash2DoProcess(HashWork *hashWork); +static void HmacCalc(char *hash, char *a1, int a2, char *digestKey, int digestKeySize, HmacParam *param); + +// Set default DigestFunc +DigestFunc gDigestFunc = DGT_Hash2CalcHmac; + +static DigestFunc sDigestFuncs[] = { NULL, DGT_Hash2CalcHmac }; +static char sDefaultDigestKey[] = { + 0x21, 0x06, 0xc0, 0xde, 0xba, 0x98, 0xce, 0x3f, 0xa6, 0x92, 0xe3, 0x9d, + 0x46, 0xf2, 0xed, 0x01, 0x76, 0xe3, 0xcc, 0x08, 0x56, 0x23, 0x63, 0xfa, + 0xca, 0xd4, 0xec, 0xdf, 0x9a, 0x62, 0x78, 0x34, 0x8f, 0x6d, 0x63, 0x3c, + 0xfe, 0x22, 0xca, 0x92, 0x20, 0x88, 0x97, 0x23, 0xd2, 0xcf, 0xae, 0xc2, + 0x32, 0x67, 0x8d, 0xfe, 0xca, 0x83, 0x64, 0x98, 0xac, 0xfd, 0x3e, 0x37, + 0x87, 0x46, 0x58, 0x24, +}; + +bool Init_Digest(uint digestType, char *digestKey) { + bool success; + + if (digestType < 1 || digestType > 2) { + ErrorPrintf("Unknown digest type\n"); + success = false; + } else { + DigestFunc digestFunc = sDigestFuncs[digestType - 1]; + if (digestFunc == NULL) { + ErrorPrintf("Unsupported digest\n"); + success = false; + } else { + gDigestFunc = digestFunc; + if (gDigestKey != NULL) { + free(gDigestKey); + gDigestKey = NULL; + } + if (digestKey == NULL) { + gDigestKey = calloc(1, DIGEST_KEY_SIZE); + if (gDigestKey == NULL) { + ErrorPrintf("Cannot allocate memory.\n"); + return false; + } + memcpy(gDigestKey, sDefaultDigestKey, DIGEST_KEY_SIZE); + gDigestKeySize = DIGEST_KEY_SIZE; + } else { + gDigestKeySize = ReadFile(digestKey, &gDigestKey); + if (gDigestKeySize < 0) { + return false; + } + if (gDigestKeySize < DIGEST_KEY_SIZE) { + ErrorPrintf("Key file size should be >= %d bytes\n", DIGEST_KEY_SIZE); + return false; + } + } + success = true; + } + } + return success; +} + +void Calc_Digest(char *content, int a1, char *a2, int a3) { + byte hash[40]; // CLEAN UP: Called `local_2c` in Ghidra + + int overlayTableMode = DGT_SetOverlayTableMode(a3); + gDigestFunc(hash, content, a1, gDigestKey, gDigestKeySize); + DGT_SetOverlayTableMode(overlayTableMode); + int iCpy = 0; + // CLEAN UP: Initialized as 0, but OG uses *(gDigestFunc + 4). + for (int i = 0; i < 20; i++) { + hash[i] = hash[iCpy + 1] ^ hash[iCpy]; + iCpy++; + } + printf(": Digest "); + for (int i = 0; i < 20; i++) { + printf("%02X", hash[i]); + } + // CLEAN UP: Is (long int) cast necessary? Is `int` not 32 bits? If so, + // that's a problem... + printf(" %8ld\n", (long int)a1); + CopyBuffer(hash, a2, 20); +} + +static void DGT_Hash2CalcHmac(char *hash, char *content, int a2, char *digestKey, int digestKeySize) { + HashWork hashWork; + char unkBuffer1[0x20]; + // CLEAN UP: OG has a loop that initializes each field to 0. + HmacParam param = {0}; + + param.unk0 = 20; + param.blockSize = DIGEST_KEY_SIZE; + param.hashWork = &hashWork; + param.unkC = unkBuffer1; + param.hash2Reset = DGT_Hash2Reset; + param.hash2SetSource = DGT_Hash2SetSource; + param.hash2GetDigest = DGT_Hash2GetDigest; + HmacCalc(hash, content, a2, digestKey, digestKeySize, ¶m); +} + +static int DGT_SetOverlayTableMode(int mode) { + int oldMode = gOverlayTableMode; + gOverlayTableMode = mode; + return oldMode; +} + +static bool DGT_Hash2Reset(HashWork *hashWork) { + if (hashWork != NULL) { + hashWork->unk14 = 0; + hashWork->unk18 = 0; + hashWork->unk1C = 0; + hashWork->unk0 = 0x67452301; + hashWork->unk4 = 0xefcdab89; + hashWork->unk8 = 0x98badcfe; + hashWork->unkC = 0x10325476; + hashWork->unk10 = 0xc3d2e1f0; + hashWork->unk60 = 0; + hashWork->unk64 = 0; + } + return hashWork == NULL; +} + +static uint DGT_Hash2SetSource(HashWork *hashWork, char *digestKey, int digestKeySize) { + uint ret; + + if (digestKeySize == 0) { + ret = 0; + } else if (hashWork == NULL || digestKey == NULL) { + ret = 1; + } else if (hashWork->unk60 = 0) { + if (hashWork->unk64 == 0) { + while (digestKeySize -= 1, digestKeySize != -1 && hashWork->unk64 == 0) { + hashWork->unk20[hashWork->unk1C] = *digestKey; + hashWork->unk1C += 1; + hashWork->unk14 += 8; + if (hashWork->unk1C == 0 && (hashWork->unk18 += 1, hashWork->unk18 == 0)) { + hashWork->unk64 = 1; + } + if (hashWork->unk1C == 0x40) { + DGT_Hash2DoProcess(hashWork); + } + digestKey++; + } + ret = 0; + } else { + ret = hashWork->unk64; + } + } else { + hashWork->unk64 = 3; + ret = 3; + } + return ret; +} + +static uint DGT_Hash2GetDigest(HashWork *hashWork, char *digestBuffer) { + uint ret; + + if (hashWork == NULL || digestBuffer == NULL) { + ret = 1; + } else if (hashWork->unk64 == 0) { + if (hashWork->unk60 == 0) { + DGT_Hash2SetPadding(hashWork); + for (int i = 0; i < 0x40; i++) { + hashWork->unk20[i] = '\0'; + } + hashWork->unk14 = 0; + hashWork->unk18 = 0; + hashWork->unk60 = 1; + } + for (int i = 0; i < 20; i++) { + // CLEAN UP: Replaced byte literals with unsigned ints (e.g. 3u, 8u). + digestBuffer[i] = (char)(*(uint *)(hashWork->unk20 + (i >> 2) * 4 + -0x20) >> ((3u - ((byte)i % 4)) * 8u & 0x1f)); + } + ret = 0; + } else { + ret = hashWork->unk64; + } + return ret; +} + +static void DGT_Hash2SetPadding(HashWork *hashWork) { + if (hashWork->unk1C < 0x38) { + hashWork->unk20[hashWork->unk1C] = -0x80; + hashWork->unk1C += 1; + while (hashWork->unk1C < 0x38) { + hashWork->unk20[hashWork->unk1C] = '\0'; + hashWork->unk1C += 1; + } + } else { + hashWork->unk20[hashWork->unk1C] = -0x80; + hashWork->unk1C += 1; + while (hashWork->unk1C < 0x40) { + hashWork->unk20[hashWork->unk1C] = '\0'; + hashWork->unk1C += 1; + } + DGT_Hash2DoProcess(hashWork); + while (hashWork->unk1C < 0x38) { + hashWork->unk20[hashWork->unk1C] = '\0'; + hashWork->unk1C += 1; + } + } + hashWork->unk20[0x38] = (char)(hashWork->unk18 >> 0x18); + hashWork->unk20[0x39] = (char)(hashWork->unk18 >> 0x10); + hashWork->unk20[0x3a] = (char)(hashWork->unk18 >> 8); + hashWork->unk20[0x3b] = *(char *)(&hashWork->unk18); + hashWork->unk20[0x3c] = (char)(hashWork->unk14 >> 0x18); + hashWork->unk20[0x3d] = (char)(hashWork->unk14 >> 0x10); + hashWork->unk20[0x3e] = (char)(hashWork->unk14 >> 8); + hashWork->unk20[0x3f] = *(char *)(&hashWork->unk14); + DGT_Hash2DoProcess(hashWork); +} + +// SHA hash +static void DGT_Hash2DoProcess(HashWork *hashWork) { + uint temp; + int temp2; + uint buffer[99]; + int i, idx; + + if (gOverlayTableMode != 0) { + buffer[10] = *(uint *)(hashWork->unk20 + 0x18); + buffer[9] = *(uint *)(hashWork->unk20 + 0x38); + *(uint *)(hashWork->unk20 + 0x18) = 0; + *(uint *)(hashWork->unk20 + 0x38) = 0; + } + for (i = 0; i < 0x10; i++) { + buffer[i + 0x10] = (uint)(byte)hashWork->unk20[i * 4] << 0x18; + buffer[i + 0x10] = (uint)(byte)hashWork->unk20[i * 4 + 1] << 0x10 | buffer[i + 0x10]; + buffer[i + 0x10] = (uint)(byte)hashWork->unk20[i * 4 + 2] << 8 | buffer[i + 0x10]; + buffer[i + 0x10] = (uint)(byte)hashWork->unk20[i * 4 + 3] | buffer[i + 0x10]; + } + for (i = 0x10; i < 0x50; i++) { + temp = buffer[i + 0xd] ^ buffer[i + 8] ^ buffer[i + 2] ^ buffer[i]; + buffer[i + 0x10] = temp << 1 | (uint)((int)temp < 0); + } + buffer[14] = hashWork->unk4; + buffer[13] = hashWork->unk8; + buffer[12] = hashWork->unkC; + buffer[11] = hashWork->unk10; + buffer[15] = hashWork->unk0; + for (i = 0; i < 0x14; i++) { + temp2 = (~buffer[14] & buffer[12] | buffer[14] & buffer[13]) + + (buffer[15] << 5 | buffer[15] >> 0x1b) + buffer[11]; + idx = i + 0x10; + buffer[11] = buffer[12]; + buffer[12] = buffer[13]; + buffer[13] = buffer[14] << 0x1e | buffer[14] >> 2; + buffer[14] = buffer[15]; + buffer[15] = buffer[idx] + temp2 + 0x5a827999; + } + for (i = 0x14; i < 0x28; i = i + 1) { + temp2 = (buffer[13] ^ buffer[14] ^ buffer[12]) + (buffer[15] << 5 | buffer[15] >> 0x1b) + + buffer[11]; + idx = i + 0x10; + buffer[11] = buffer[12]; + buffer[12] = buffer[13]; + buffer[13] = buffer[14] << 0x1e | buffer[14] >> 2; + buffer[14] = buffer[15]; + buffer[15] = buffer[idx] + temp2 + 0x6ed9eba1; + } + for (i = 0x28; i < 0x3c; i++) { + temp2 = (buffer[12] & buffer[13] | (buffer[12] | buffer[13]) & buffer[14]) + + (buffer[15] << 5 | buffer[15] >> 0x1b) + buffer[11]; + idx = i + 0x10; + buffer[11] = buffer[12]; + buffer[12] = buffer[13]; + buffer[13] = buffer[14] << 0x1e | buffer[14] >> 2; + buffer[14] = buffer[15]; + buffer[15] = buffer[idx] + temp2 + 0x8f1bbcdc; + } + for (i = 0x3c; i < 0x50; i++) { + temp2 = (buffer[13] ^ buffer[14] ^ buffer[12]) + (buffer[15] << 5 | buffer[15] >> 0x1b) + + buffer[11]; + idx = i + 0x10; + buffer[11] = buffer[12]; + buffer[12] = buffer[13]; + buffer[13] = buffer[14] << 0x1e | buffer[14] >> 2; + buffer[14] = buffer[15]; + buffer[15] = buffer[idx] + temp2 + 0xca62c1d6; + } + hashWork->unk0 = buffer[15] + hashWork->unk0; + hashWork->unk4 = buffer[14] + hashWork->unk4; + hashWork->unk8 = buffer[13] + hashWork->unk8; + hashWork->unkC = buffer[12] + hashWork->unkC; + hashWork->unk10 = buffer[11] + hashWork->unk10; + hashWork->unk1C = 0; + if (gOverlayTableMode != 0) { + *(uint *)(hashWork->unk20 + 0x18) = buffer[10]; + *(uint *)(hashWork->unk20 + 0x38) = buffer[9]; + } +} + +static void HmacCalc(char *hash, char *content, int a2, char *digestKey, int digestKeySize, HmacParam *param) { + byte digestBuffer[0x4C]; + byte *key; + int keySize; + char innerKey[0x48]; + char outerKey[0x40]; + int i; + + if (hash != NULL && content != NULL && a2 != 0 && digestKey != NULL && + digestKeySize != 0 && param != NULL) { + if (param->blockSize < digestKeySize) { + param->hash2Reset(param->hashWork); + param->hash2SetSource(param->hashWork, digestKey, digestKeySize); + param->hash2GetDigest(param->hashWork, digestBuffer); + key = digestBuffer; + keySize = param->unk0; + } else { + key = digestKey; + keySize = digestKeySize; + } + for (i = 0; i < keySize; i++) { + innerKey[i] = key[i] ^ 0x36; + } + for (; i < param->blockSize; i++) { + innerKey[i] = 0x36; + } + param->hash2Reset(param->hashWork); + param->hash2SetSource(param->hashWork, innerKey, param->blockSize); + param->hash2SetSource(param->hashWork, content, a2); + param->hash2GetDigest(param->hashWork, param->unkC); + + for (i = 0; i < keySize; i++) { + outerKey[i] = key[i] ^ 0x5c; + } + for (; i < param->blockSize; i++) { + outerKey[i] = 0x5c; + } + param->hash2Reset(param->hashWork); + param->hash2SetSource(param->hashWork, outerKey, param->blockSize); + param->hash2SetSource(param->hashWork, param->unkC, param->unk0); + param->hash2GetDigest(param->hashWork, hash); + } +} diff --git a/tools/compstatic/digest.h b/tools/compstatic/digest.h new file mode 100644 index 000000000..ebb292a1d --- /dev/null +++ b/tools/compstatic/digest.h @@ -0,0 +1,19 @@ +#ifndef DIGEST_H +#define DIGEST_H + +#include +#include "global.h" + +#define DIGEST_KEY_SIZE (0x40) + +typedef void (*DigestFunc)(char *a0, char *content, int a2, char *digestKey, int digestKeySize); + +DigestFunc gDigestFunc; +char *gDigestKey; +int gDigestKeySize; +int gOverlayTableMode; + +bool Init_Digest(uint digestType, char *digestKey); +void Calc_Digest(char *content, int a1, char *a2, int a3); + +#endif // DIGEST_H diff --git a/tools/compstatic/files.c b/tools/compstatic/files.c new file mode 100644 index 000000000..d754171ea --- /dev/null +++ b/tools/compstatic/files.c @@ -0,0 +1,154 @@ +#include +#include +#include +#include +#include +#include +#include +#include "files.h" +#include "global.h" +#include "print.h" +#include "str.h" + +char *GetDirName(char *filename) { + char *dirName; + + int i = strlen(filename); + while (true) { + i--; + if (i < 0) { + dirName = strdup("."); + return dirName; + } + if (filename[i] == '/' || filename[i] == '\\') break; + if (filename[i] == ':') { + // TODO: Slightly adjusted logic to remove `prev_i` + dirName = malloc(i + 3); + if (dirName != NULL) { + strncpy(dirName, filename, i); + strcpy(dirName + i, ":."); + } + return dirName; + } + } + + // Same size as filename, but has null-character after directory name. + dirName = strdup(filename); + if (dirName == NULL) { + return NULL; + } + dirName[i] = '\0'; + return dirName; +} + +bool GetFiles(char *responseFile, SourceFiles *sourceFiles) { + char *filename; + bool success; + int numWords; + int wordStart; + char *content; + + char *dirName = GetDirName(responseFile); + int bytesRead = ReadFile(responseFile, &content); + if (bytesRead < 0) { + success = false; + } else { + numWords = 0; + // TODO: I added this variable to get StrCat to work + wordStart = 0; + for (int i = 0; i < bytesRead; i++) { + if (content[i] == '\0') { + filename = StrCat(3, dirName, "/", &content[wordStart]); + sourceFiles->filenames[numWords] = filename; + + wordStart = i + 1; + numWords++; + if (numWords == NUM_SOURCE_FILES) break; + } + } + free(content); + free(dirName); + if (numWords == NUM_SOURCE_FILES) { + success = true; + } else { + while (numWords > 0) { + numWords--; + free(sourceFiles->filenames[numWords]); + } + ErrorPrintf("%s wrong format", responseFile); + success = false; + } + } + return success; +} + +// Returns size of file. +// TODO: Double-check that `content` is char ** +// NOTE: There were 3 args that weren't read at all. Removed. +int ReadFile(char *filename, char **content) { + int bytesRead; + struct stat fileInfo; + FILE *fp = NULL; + *content = NULL; + + if (filename == NULL) { + ErrorPrintf("Not specified filename\n"); + } else { + // TODO: I think OG does a mode_t check? Probably not necessary, and can be removed. + int error = stat(filename, &fileInfo); + if ((error == 0) && (fp = fopen(filename, "rb"), fp != NULL)) { + *content = malloc(fileInfo.st_size); + if (*content == NULL) { + ErrorPrintf("Cannot allocate memory size=%d\n", fileInfo.st_size); + } else { + bytesRead = fread(*content, 1, fileInfo.st_size, fp); + if (bytesRead == fileInfo.st_size) { + DebugPrintf("%p %8d bytes ReadFile \'%s\'\n", *content, fileInfo.st_size, filename); + fclose(fp); + return fileInfo.st_size; + } + ErrorPrintf("Cannot read file \'%s\'\n", filename); + } + } + ErrorPrintf("Cannot read file \'%s\'\n", filename); + } + + if (*content != NULL) { + free(content); + } + if (fp != NULL) { + fclose(fp); + } + return -1; +} + +// Returns number of bytes written. +int WriteFile(char *filename, char *content, int size) { + FILE *fp = NULL; + int ret; + + DebugPrintf("%p %8d bytes WriteFile \'%s\'\n", content, size, filename); + fp = fopen(filename, "wb"); + if (fp == NULL) { + ErrorPrintf("Cannot open file \'%s\'\n", filename); + ret = -1; + } else { + int sizeWritten = fwrite(content, 1, size, fp); + if (size == sizeWritten) { + int closeResult = fclose(fp); + if (closeResult < 0) { + ErrorPrintf("Cannot close file \'%s\'\n", filename); + unlink(filename); + ret = -1; + } else { + ret = sizeWritten; + } + } else { + ErrorPrintf("Cannot write file \'%s\'\n", filename); + fclose(fp); + unlink(filename); + ret = -1; + } + } + return ret; +} diff --git a/tools/compstatic/files.h b/tools/compstatic/files.h new file mode 100644 index 000000000..44ea43fce --- /dev/null +++ b/tools/compstatic/files.h @@ -0,0 +1,12 @@ +#ifndef FILES_H +#define FILES_H + +#include +#include "global.h" + +char *GetDirName(char *filename); +bool GetFiles(char *responseFile, SourceFiles *sourceFiles); +int ReadFile(char *filename, char **content); // TODO: Double-check: it passes a bunch of stack variables.. +int WriteFile(char *filename, char *content, int size); + +#endif // FILES_H diff --git a/tools/compstatic/global.h b/tools/compstatic/global.h new file mode 100644 index 000000000..dc31af15b --- /dev/null +++ b/tools/compstatic/global.h @@ -0,0 +1,77 @@ +#ifndef GLOBAL_H +#define GLOBAL_H + +#include + +typedef unsigned char byte; +typedef unsigned short ushort; +typedef unsigned int uint; + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) + +// NOTE TO SELF: All the fields are ints in the original! +typedef struct { + bool staticModule; + int headerSize; // size in bytes + bool overlayModules; + bool overlayDigest; + int unk10; + char *digestKey; + char *outSuffix; + int unk1C; // stack allocated but unitialized - delete? + int unk20; // stack allocated but unitialized - delete? +} Options; + +#define SOURCE_FILES_STATIC_MODULE 0 +#define SOURCE_FILES_OVERLAY_DEFS 1 +#define SOURCE_FILES_OVERLAY_TABLE 2 +#define NUM_SOURCE_FILES 3 + +typedef struct { + char *filenames[NUM_SOURCE_FILES]; +} SourceFiles; + +bool gDebugMode; + +typedef struct { + char *filename; + char *content; + int fileSize; + int unkC; + int unk10; +} FileInfo; // sizeof == 0x14 + +typedef struct { + FileInfo fileInfo; + char *footerContent; + uint footerSize; +} StaticModule; // sizeof == 0x1c + +typedef struct { + FileInfo fileInfo; + char *content_dup; +} OverlayDefs; // sizeof == 0x18 + +typedef struct { + FileInfo fileInfo; +} OverlayModule; // sizeof == 0x14 + +// TODO: Size seems to be 0x18 from ReadOverlayTable(). Make sure this is +// consistent with other usages. +typedef struct { + FileInfo fileInfo; + char *content_dup; +} OverlayTable; // sizeof == 0x18 + +typedef struct { + StaticModule staticModule; + int numOverlays; + OverlayDefs overlayDefs; + char *overlayFilenames; + char *dirName; + OverlayTable overlayTable; + OverlayModule *overlayModules; +} Component; // size: 0x5c + +#endif // GLOBAL_H diff --git a/tools/compstatic/main.c b/tools/compstatic/main.c new file mode 100644 index 000000000..b46d6e903 --- /dev/null +++ b/tools/compstatic/main.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include "component.h" +#include "files.h" +#include "global.h" +#include "print.h" +#include "str.h" + +// Global vars +bool gDebugMode = false; + +void InitializeOptions(Options *options) { + options->staticModule = false; + options->headerSize = 0x4000; + options->overlayModules = false; + options->overlayDigest = false; + options->unk10 = 2; + options->digestKey = StrDup(NULL, NULL); + options->outSuffix = StrDup(NULL, "_LZ"); +} + +void usage(void) { + printf("NDS Development Tool - compstatic - Compress static module\n\n" + "Usage: compstatic [-sHSIZE|-9|-7] [-c] [-a[FILE]]\n" + " [-F] [-eSUFFIX] [-fRESFILE] [-d] [-h]\n" + " [STATICMODULE OVERLAYDEFS [OVERLAYTABLE]]\n\n" + " Compress component modules\n\n" + " -sHSIZE Compress STATICMODULE\n" + " without header region specified by HSIZE(bytes)\n" + " -9 Compress as ARM9 static module (HEADER_SIZE = 16k)\n" + " -7 Compress as ARM7 static module (HEADER_SIZE = 1k)\n" + " -c Compress overlay modules\n" + " -a[FILE] Generate overlay digest code with FILE as key\n" + " -F Overwrite original component files\n" + " -eSUFFIX SUFFIX for output file (default:\"_LZ\")\n" + " -fRESFILE Use response file to specify source files\n" + " -d Show debug messages (for test purpose)\n" + " -h Show this message\n\n"); +} + +int main(int argc, char *argv[]) { + int opt; + int useResponseFile = false; + int argsLeft; + char **remainingArgs; + char *overlayTable; + bool success; + SourceFiles sourceFiles; + Options options; + + InitializeOptions(&options); + while ((opt = getopt(argc, argv, "s:ca::A:97Fe:fdhv")) != -1) { + switch (opt) { + case '7': + options.staticModule = true; + options.headerSize = 0x400; + break; + case '9': + options.staticModule = true; + options.headerSize = 0x4000; + break; + // Not referenced in usage + case 'A': + options.unk10 = atoi(optarg); + break; + case 'F': + options.outSuffix = StrDup(options.outSuffix, NULL); // TODO: Check if NULL or "" + break; + case 'a': + options.overlayDigest = true; + options.digestKey = StrDup(options.digestKey, optarg); + break; + case 'c': + options.overlayModules = true; + break; + case 'd': + gDebugMode = true; + break; + case 'e': + options.outSuffix = strdup(optarg); + break; + case 'f': + useResponseFile = true; + break; + case 's': + options.staticModule = true; + options.headerSize = atoi(optarg); + break; + default: + usage(); + break; + } + DebugPrintf("option -%c: %s\n", opt, (optarg == NULL) ? "No ARG" : optarg); + } + + argsLeft = argc - optind; + remainingArgs = &argv[optind]; + + DebugPrintf("argc=%d optind=%d\n", argsLeft, optind); + for (int i = 0; i < argsLeft; i++) { + DebugPrintf("argv[%d] = [%s]\n", i, argv[optind + i]); + } + + if (!useResponseFile || argsLeft != 1) { + if (!useResponseFile && (argsLeft == 2 || argsLeft == 3)) { + overlayTable = (argsLeft == 3) ? remainingArgs[2] : NULL; + success = ConvertComponent(&options, remainingArgs[0], remainingArgs[1], overlayTable); + } else { + usage(); + } + } else { + success = GetFiles(remainingArgs[0], &sourceFiles); + if (success) { + printf("StaticModule = %s\n", sourceFiles.filenames[SOURCE_FILES_STATIC_MODULE]); + printf("OverlayDefs = %s\n", sourceFiles.filenames[SOURCE_FILES_OVERLAY_DEFS]); + printf("OverlayTable = %s\n", sourceFiles.filenames[SOURCE_FILES_OVERLAY_TABLE]); + + success = ConvertComponent(&options, sourceFiles.filenames[SOURCE_FILES_STATIC_MODULE], sourceFiles.filenames[SOURCE_FILES_OVERLAY_DEFS], sourceFiles.filenames[SOURCE_FILES_OVERLAY_TABLE]); + free(sourceFiles.filenames[SOURCE_FILES_STATIC_MODULE]); + free(sourceFiles.filenames[SOURCE_FILES_OVERLAY_DEFS]); + free(sourceFiles.filenames[SOURCE_FILES_OVERLAY_TABLE]); + } + } + + ConvertFinal(&options); + if (!success) { + ErrorPrintf("exit...\n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/tools/compstatic/misc.c b/tools/compstatic/misc.c new file mode 100644 index 000000000..d6837efc1 --- /dev/null +++ b/tools/compstatic/misc.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include "global.h" +#include "misc.h" +#include "print.h" + +void CopyBuffer(char *src, char *dest, int size) { + if (dest < src) { + for (int i = 0; i < size; i++) { + dest[i] = src[i]; + } + } else { + for (int i = size - 1; i >= 0; i--) { + dest[i] = src[i]; + } + } +} + +void FreeBuffer(FileInfo *fileInfo) { + if (fileInfo->content != NULL) { + free(fileInfo->content); + fileInfo->content = NULL; + } + if (fileInfo->filename != NULL) { + free(fileInfo->filename); + fileInfo->filename = NULL; + } + fileInfo->unkC = 0; + fileInfo->fileSize = 0; + fileInfo->unk10 = 0; +} + +bool AddSuffixBuffer(FileInfo *fileInfo, char *suffix) { + bool success; + + if (fileInfo->fileSize == 0 || fileInfo->filename == NULL || suffix == NULL || *suffix == '\0') { + success = true; + } else { + int filenameLength = strlen(fileInfo->filename); + int suffixLength = strlen(suffix); + char *dest = malloc(filenameLength + suffixLength + 1); + if (dest == NULL) { + ErrorPrintf("Cannot allocate memory.\n"); + success = false; + } else { + sprintf(dest, "%s%s", fileInfo->filename, suffix); + free(fileInfo->filename); + fileInfo->filename = dest; + fileInfo->unk10 = 1; + success = true; + } + } + return success; +} diff --git a/tools/compstatic/misc.h b/tools/compstatic/misc.h new file mode 100644 index 000000000..b21351fde --- /dev/null +++ b/tools/compstatic/misc.h @@ -0,0 +1,10 @@ +#ifndef MISC_H +#define MISC_H + +#include "global.h" + +void CopyBuffer(char *src, char *dest, int size); +void FreeBuffer(FileInfo *fileInfo); +bool AddSuffixBuffer(FileInfo *fileInfo, char *suffix); + +#endif // MISC_H diff --git a/tools/compstatic/overlay_defs.c b/tools/compstatic/overlay_defs.c new file mode 100644 index 000000000..8df58de65 --- /dev/null +++ b/tools/compstatic/overlay_defs.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include "files.h" +#include "global.h" +#include "misc.h" +#include "overlay_defs.h" +#include "print.h" + +bool ReadOverlayDefs(Component *component, char *filename) { + int numWords; + int checkPtr; + bool success = false; + + DebugPrintf("Reading overlayDefs=%s\n", filename); + int fileSize = ReadFile(filename, &component->overlayDefs.fileInfo.content); // TODO: Double-check: it passes a bunch of stack variables.. + component->overlayDefs.fileInfo.fileSize = fileSize; + component->overlayDefs.fileInfo.unkC = 0; + component->overlayDefs.fileInfo.unk10 = 0; + component->overlayDefs.fileInfo.filename = strdup(filename); + + if (component->overlayDefs.fileInfo.fileSize < 0) { + success = false; + } else if (component->overlayDefs.fileInfo.fileSize < MIN_OVERLAY_DEFS_FILE_SIZE) { + ErrorPrintf("Overlaydefs is too small (size=%d). Must be >= %d\n", component->overlayDefs.fileInfo.fileSize, MIN_OVERLAY_DEFS_FILE_SIZE); + success = false; + } else { + component->overlayDefs.content_dup = component->overlayDefs.fileInfo.content; + component->overlayFilenames = component->overlayDefs.content_dup + OVERLAY_DEFS_FILENAMES_OFFSET; + component->dirName = GetDirName(filename); + if (component->dirName == NULL) { + success = false; + } else { + // Count the number of words in the footer. Once two '\0' chars + // appear back-to-back, stop checking. + numWords = 0; + checkPtr = 0; + for (int i = 0; i < component->overlayDefs.fileInfo.fileSize - OVERLAY_DEFS_FILENAMES_SIZE; i++) { + if (component->overlayFilenames[i] == '\0') { + if (checkPtr == i) break; + numWords++; + checkPtr = i + 1; + } + } + component->numOverlays = numWords; + success = true; + } + } + + return success; +} + +bool WriteOverlayDefs(Component *component) { + int sizeWritten; + bool success; + + OverlayDefs *overlayDefs = &component->overlayDefs; + if (overlayDefs->fileInfo.unk10 == 0) { + success = true; + } else { + DebugPrintf("Writing overlayDefs=%s\n", overlayDefs->fileInfo.filename); + if (overlayDefs->fileInfo.unkC == 0) { + // CLEAN UP: I re-wrote this from (success := ~sizeWriten >> 0x1f) + sizeWritten = WriteFile(overlayDefs->fileInfo.filename, overlayDefs->fileInfo.content, overlayDefs->fileInfo.fileSize); + success = sizeWritten >= 0; + } else { + ErrorPrintf("Don\'t support compressed overlaydefs\n"); + success = false; + } + } + return success; +} + +bool AddSuffixOverlayDefs(Component *component, char *suffix) { + DebugPrintf("Adding suffix overlayDefs=%s\n", suffix); + return AddSuffixBuffer(&component->overlayDefs.fileInfo, suffix); +} + +void FreeOverlayDefs(Component *component) { + DebugPrintf("Releasing overlayDefs\n"); + FreeBuffer(&component->overlayDefs.fileInfo); + component->overlayDefs.content_dup = NULL; + component->overlayFilenames = NULL; + if (component->dirName != NULL) { + free(component->dirName); + component->dirName = NULL; + } +} diff --git a/tools/compstatic/overlay_defs.h b/tools/compstatic/overlay_defs.h new file mode 100644 index 000000000..dab23540d --- /dev/null +++ b/tools/compstatic/overlay_defs.h @@ -0,0 +1,17 @@ +#ifndef OVERLAY_DEFS_H +#define OVERLAY_DEFS_H + +#include +#include "global.h" + +#define MIN_OVERLAY_DEFS_FILE_SIZE 0x10 +#define OVERLAY_DEFS_FOOTER_OFFSET 0x8 +#define OVERLAY_DEFS_FILENAMES_OFFSET 0x10 +#define OVERLAY_DEFS_FILENAMES_SIZE 0x10 + +bool ReadOverlayDefs(Component *component, char *filename); +bool WriteOverlayDefs(Component *component); +bool AddSuffixOverlayDefs(Component *component, char *suffix); +void FreeOverlayDefs(Component *component); + +#endif // OVERLAY_DEFS_H diff --git a/tools/compstatic/overlay_modules.c b/tools/compstatic/overlay_modules.c new file mode 100644 index 000000000..ccd764068 --- /dev/null +++ b/tools/compstatic/overlay_modules.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include "files.h" +#include "global.h" +#include "misc.h" +#include "overlay_modules.h" +#include "print.h" + +bool ReadOverlayModules(Component *component) { + bool success; + char c; + OverlayModule *overlayModules; + + char *overlayFilenames = component->overlayFilenames; + char *dirName = component->dirName; + int dirNameLength = strlen(dirName); + + if (component->numOverlays == 0) { + DebugPrintf("No overlay to read\n"); + component->overlayModules = NULL; + success = true; + } else { + overlayModules = calloc(component->numOverlays, sizeof(OverlayModule)); + if (overlayModules == NULL) { + ErrorPrintf("Cannot allocate memory.\n"); + success = false; + } else { + component->overlayModules = overlayModules; + for (int i = 0; i < component->numOverlays; i++) { + int filenameLength = strlen(overlayFilenames); + overlayModules->fileInfo.filename = malloc(filenameLength + dirNameLength + 2);; + if (overlayModules->fileInfo.filename == NULL) { + ErrorPrintf("Cannot allocate memory\n"); + return false; + } + // TODO: Make sure that this copies only the current filename + // and not the whole `overlayFilenames` string! + sprintf(overlayModules->fileInfo.filename, "%s/%s", dirName, overlayFilenames); + DebugPrintf("Reading overlay[%d]=%s\n", i, overlayModules->fileInfo.filename); + + int fileSize = ReadFile(overlayModules->fileInfo.filename, &overlayModules->fileInfo.content); + overlayModules->fileInfo.fileSize = fileSize; + overlayModules->fileInfo.unkC = 0; + overlayModules->fileInfo.unk10 = 0; + if (overlayModules->fileInfo.fileSize < 0) return false; + + overlayModules++; + do { + c = *overlayFilenames; + overlayFilenames++; + } while (c != '\0'); + } + success = true; + } + } + return success; +} + +bool WriteOverlayModules(Component *component) { + OverlayModule *overlayModule = component->overlayModules; + int i = 0; + + do { + if (i >= component->numOverlays) { + return true; + } + if (overlayModule->fileInfo.unk10 != 0) { + DebugPrintf("Writing overlay[%d]=%s\n", i, overlayModule->fileInfo.filename); + int overlaySize = overlayModule->fileInfo.unkC ? overlayModule->fileInfo.unkC : overlayModule->fileInfo.fileSize; + int sizeWritten = WriteFile(overlayModule->fileInfo.filename, overlayModule->fileInfo.content, overlaySize); + if (sizeWritten < 0) { + return false; + } + } + overlayModule++; + i++; + } while (true); +} + +bool AddSuffixOverlayModules(Component *component, char *suffix) { + bool success; + + OverlayModule *overlayModule = component->overlayModules; + if (component->numOverlays == 0 || overlayModule == NULL) { + DebugPrintf("No overlay to add suffix\n"); + success = true; + } else if (suffix == NULL || *suffix == '\0') { + success = true; + } else { + int suffixLength = strlen(suffix); + int fileSize = suffixLength * component->numOverlays + component->overlayDefs.fileInfo.fileSize; + char *buffer = malloc(fileSize); + if (buffer == NULL) { + ErrorPrintf("Cannot allocate memory\n"); + success = false; + } else { + uint *contentDup32 = (uint *)component->overlayDefs.content_dup; + *(uint *)buffer = contentDup32[0]; + *(uint *)(buffer + 4) = contentDup32[1]; + *(uint *)(buffer + 8) = contentDup32[2]; + *(uint *)(buffer + 0xc) = contentDup32[3]; + + char *contentPtr = buffer + 0x10; + char *ovFilename = component->overlayFilenames; + for (int i = 0; i < component->numOverlays; i++) { + DebugPrintf("Adding suffix overlay[%d]\n", i); + strcpy(contentPtr, ovFilename); + strcat(contentPtr, suffix); + + int length = strlen(ovFilename); + ovFilename += length + 1; + length = strlen(contentPtr); + contentPtr += length + 1; + + bool addSuffixSuccess = AddSuffixBuffer(&overlayModule->fileInfo, suffix); + if (!addSuffixSuccess) { + return false; + } + overlayModule++; + } + CopyBuffer(ovFilename, contentPtr, fileSize - ((size_t)contentPtr - (size_t)buffer)); + free(component->overlayDefs.fileInfo.content); + component->overlayDefs.fileInfo.content = buffer; + component->overlayDefs.fileInfo.fileSize = fileSize; + component->overlayDefs.fileInfo.unk10 = 1; + component->overlayDefs.content_dup = buffer; + component->overlayFilenames = buffer + 0x10; + success = true; + } + } + return success; +} + +void FreeOverlayModules(Component *component) { + OverlayModule *overlayModule = component->overlayModules; + if (component->numOverlays == 0 || overlayModule == NULL) { + DebugPrintf("No overlay to release\n"); + } else { + for (int i = 0; i < component->numOverlays; i++) { + DebugPrintf("Releasing overlay[%d]\n", i); + FreeBuffer(&overlayModule->fileInfo); + overlayModule++; + } + } + if (component->overlayModules != NULL) { + free(component->overlayModules); + component->overlayModules == NULL; + } +} diff --git a/tools/compstatic/overlay_modules.h b/tools/compstatic/overlay_modules.h new file mode 100644 index 000000000..e10eae9ef --- /dev/null +++ b/tools/compstatic/overlay_modules.h @@ -0,0 +1,12 @@ +#ifndef OVERLAY_MODULE_H +#define OVERLAY_MODULE_H + +#include +#include "global.h" + +bool ReadOverlayModules(Component *component); +bool WriteOverlayModules(Component *component); +bool AddSuffixOverlayModules(Component *component, char *suffix); +void FreeOverlayModules(Component *component); + +#endif // OVERLAY_MODULE_H diff --git a/tools/compstatic/overlay_table.c b/tools/compstatic/overlay_table.c new file mode 100644 index 000000000..7217f5e5e --- /dev/null +++ b/tools/compstatic/overlay_table.c @@ -0,0 +1,80 @@ +#include +#include +#include "files.h" +#include "global.h" +#include "misc.h" +#include "overlay_table.h" +#include "print.h" + +#define OVERLAY_ENTRY_SIZE (32) + +bool ReadOverlayTable(Component *component, char *filename) { + OverlayTable *overlayTable = &component->overlayTable; + if (filename == NULL || component->numOverlays < 1) { + DebugPrintf("No overlay table to read\n"); + overlayTable->fileInfo.content = NULL; + overlayTable->fileInfo.fileSize = 0; + overlayTable->fileInfo.filename = NULL; + } else { + // TODO: Removed duplicate var `ovTable2`. Clean up + DebugPrintf("Reading overlayTable=%s\n", filename); + int fileSize = ReadFile(filename, &overlayTable->fileInfo.content); + overlayTable->fileInfo.fileSize = fileSize; + overlayTable->fileInfo.filename = strdup(filename); + } + overlayTable->fileInfo.unkC = false; + overlayTable->fileInfo.unk10 = 0; + bool success = overlayTable->fileInfo.fileSize == component->numOverlays * OVERLAY_ENTRY_SIZE; + if (success) { + overlayTable->content_dup = overlayTable->fileInfo.content; + } else { + ErrorPrintf("Not matched number of overlays and size of overlay table\n"); + } + return success; +} + +bool WriteOverlayTable(Component *component) { + bool success; + OverlayTable *overlayTable = &component->overlayTable; + + if (overlayTable->fileInfo.unk10 == 0) { + success = true; + } else if (overlayTable->fileInfo.filename == NULL) { + ErrorPrintf("No filename specified for overlay table\n"); + success = false; + } else { + DebugPrintf("Writing overlayTable=%s\n", overlayTable->fileInfo.filename); + if (overlayTable->fileInfo.unkC == 0) { + // CLEAN UP: I re-wrote this from (success := ~sizeWriten >> 0x1f) + int sizeWritten = WriteFile(overlayTable->fileInfo.filename, overlayTable->fileInfo.content, overlayTable->fileInfo.fileSize); + success = sizeWritten >= 0; + } else { + ErrorPrintf("Don\'t support compressed overlay table\n"); + success = false; + } + } + return success; +} + +bool AddSuffixOverlayTable(Component *component, char *suffix) { + bool success; + + if (component->overlayTable.fileInfo.content == NULL || component->numOverlays == 0) { + DebugPrintf("No overlaytable to add suffix\n"); + success = true; + } else { + DebugPrintf("Adding suffix overlayTable=%s\n", suffix); + success = AddSuffixBuffer(&component->overlayTable.fileInfo, suffix); + } + return success; +} + +void FreeOverlayTable(Component *component) { + if (component->overlayTable.fileInfo.content == NULL) { + DebugPrintf("No overlaytable to release\n"); + } else { + DebugPrintf("Releasing overlayTable\n"); + FreeBuffer(&component->overlayTable.fileInfo); + } + component->overlayTable.content_dup = NULL; +} diff --git a/tools/compstatic/overlay_table.h b/tools/compstatic/overlay_table.h new file mode 100644 index 000000000..f649d3bfa --- /dev/null +++ b/tools/compstatic/overlay_table.h @@ -0,0 +1,12 @@ +#ifndef OVERLAY_TABLE_H +#define OVERLAY_TABLE_H + +#include +#include "component.h" + +bool ReadOverlayTable(Component *component, char *filename); +bool WriteOverlayTable(Component *component); +bool AddSuffixOverlayTable(Component *component, char *suffix); +void FreeOverlayTable(Component *component); + +#endif // OVERLAY_TABLE_H diff --git a/tools/compstatic/print.c b/tools/compstatic/print.c new file mode 100644 index 000000000..155bc7bde --- /dev/null +++ b/tools/compstatic/print.c @@ -0,0 +1,22 @@ +#include +#include +#include "global.h" +#include "print.h" + +int DebugPrintf(const char *format, ...) { + if (!gDebugMode) return 0; + + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +int ErrorPrintf(const char *format, ...) { + printf("Error: "); + + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} diff --git a/tools/compstatic/print.h b/tools/compstatic/print.h new file mode 100644 index 000000000..a17b67a4c --- /dev/null +++ b/tools/compstatic/print.h @@ -0,0 +1,7 @@ +#ifndef PRINT_H +#define PRINT_H + +int DebugPrintf(const char *format, ...); +int ErrorPrintf(const char *format, ...); + +#endif // PRINT_H diff --git a/tools/compstatic/static_module.c b/tools/compstatic/static_module.c new file mode 100644 index 000000000..72994136c --- /dev/null +++ b/tools/compstatic/static_module.c @@ -0,0 +1,77 @@ +#include +#include +#include "files.h" +#include "global.h" +#include "misc.h" +#include "overlay_defs.h" +#include "print.h" +#include "static_module.h" + +bool ReadStaticModule(Component *component, char *filename) { + bool success; + + // TODO: Note that OG makes changes on component directly. + StaticModule *staticModule = &component->staticModule; + + DebugPrintf("Reading staticModule=%s\n", filename); + int fileSize = ReadFile(filename, &staticModule->fileInfo.content); + staticModule->fileInfo.fileSize = fileSize; + staticModule->fileInfo.unkC = 0; + staticModule->fileInfo.unk10 = 0; + staticModule->fileInfo.filename = strdup(filename); + if (staticModule->fileInfo.fileSize < 0) { + success = false; + } else if (staticModule->fileInfo.fileSize % 4 == 0) { + int footerOffset = *(int *)(component->overlayDefs.content_dup + OVERLAY_DEFS_FOOTER_OFFSET); + uint footerOffsetAligned = (footerOffset + 3) & 0xfffffffc; + staticModule->footerSize = staticModule->fileInfo.fileSize - footerOffsetAligned; + staticModule->footerContent = staticModule->fileInfo.content + footerOffsetAligned; + staticModule->fileInfo.fileSize = footerOffset; + + // CLEAN UP: Consider simplifying: Make a local int variable for + // (staticModule->footerContent + 4). + if (staticModule->footerSize < 0xc || *(uint *)staticModule->footerContent != 0xDEC00621) { + ErrorPrintf("Static module is older format (No footer extension).\n"); + success = false; + } else if ((*(uint *)(staticModule->footerContent + 4) % 4 == 0) && + (*(int *)(staticModule->footerContent + 4) > -1) && + (*(int *)(staticModule->footerContent + 4) < footerOffset)) { + success = true; + } else { + ErrorPrintf("Static module is illegal format (Unknown footer format).\n"); + success = false; + } + } else { + ErrorPrintf("Static module size is illegal (size=%d). Must be aligned by 4\n"); + success = false; + } + return success; +} + +bool WriteStaticModule(Component *component) { + bool success; + StaticModule *staticModule = &component->staticModule; + + if (staticModule->fileInfo.unk10 == 0) { + success = true; + } else { + DebugPrintf("Writing staticModule=%s\n", staticModule->fileInfo.filename); + int fileSize = staticModule->fileInfo.unkC ? staticModule->fileInfo.unkC : staticModule->fileInfo.fileSize; + // CLEAN UP: I re-wrote this from (success := ~sizeWriten >> 0x1f) + int sizeWritten = WriteFile(staticModule->fileInfo.filename, staticModule->fileInfo.content, fileSize + staticModule->footerSize); + success = sizeWritten >= 0; + } + return success; +} + +bool AddSuffixStaticModule(Component *component, char *suffix) { + DebugPrintf("Adding suffix staticModule=%s\n", suffix); + return AddSuffixBuffer(&component->staticModule.fileInfo, suffix); +} + +void FreeStaticModule(Component *component) { + DebugPrintf("Releasing staticModule\n"); + FreeBuffer(&component->staticModule.fileInfo); + component->staticModule.footerContent = NULL; + component->staticModule.footerSize = 0; +} diff --git a/tools/compstatic/static_module.h b/tools/compstatic/static_module.h new file mode 100644 index 000000000..33de99ef2 --- /dev/null +++ b/tools/compstatic/static_module.h @@ -0,0 +1,12 @@ +#ifndef STATIC_MODULE_H +#define STATIC_MODULE_H + +#include +#include "global.h" + +bool ReadStaticModule(Component *component, char *filename); +bool WriteStaticModule(Component *component); +bool AddSuffixStaticModule(Component *component, char *suffix); +void FreeStaticModule(Component *component); + +#endif // STATIC_MODULE_H diff --git a/tools/compstatic/str.c b/tools/compstatic/str.c new file mode 100644 index 000000000..6bf16ea5e --- /dev/null +++ b/tools/compstatic/str.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include "print.h" +#include "str.h" + +char *StrCat(int count, ...) { + char *dest; + char *word; + int length; + + va_list args; + va_start(args, count); + va_list argsCpy; + va_copy(argsCpy, args); + + int totalLength = 0; + for (int i = 0; i < count; i++) { + word = va_arg(args, char *); + length = strlen(word); + totalLength += length; + } + va_end(args); + dest = malloc(totalLength + 1); + if (dest == NULL) { + ErrorPrintf("Cannot allocate memory\n"); + exit(1); + } + + dest[0] = '\0'; + for (int i = 0; i < count; i++) { + word = va_arg(argsCpy, char *); + length = strlen(word); + strcat(dest, word); + } + va_end(argsCpy); + return dest; +} + +char *StrDup(char *prevDest, char *src) { + if (prevDest != NULL) { + free(prevDest); + } + if (src != NULL) { + src = strdup(src); + if (src == NULL) { + ErrorPrintf("Cannot allocate memory\n"); + exit(1); + } + } + return src; +} diff --git a/tools/compstatic/str.h b/tools/compstatic/str.h new file mode 100644 index 000000000..0305660a9 --- /dev/null +++ b/tools/compstatic/str.h @@ -0,0 +1,7 @@ +#ifndef STR_H +#define STR_H + +char *StrCat(int count, ...); +char *StrDup(char *prevDest, char *src); + +#endif // STR_H From 46e885105668fe15e47a56eb834abf3243ac4d93 Mon Sep 17 00:00:00 2001 From: Abaresk Date: Mon, 25 Apr 2022 03:13:58 +0000 Subject: [PATCH 2/5] Document and clean up --- tools/compstatic/component.c | 40 +++++----- tools/compstatic/component.h | 4 +- tools/compstatic/compress.c | 123 ++++++++++++----------------- tools/compstatic/compress.h | 2 +- tools/compstatic/digest.c | 47 +++++------ tools/compstatic/digest.h | 9 ++- tools/compstatic/files.c | 5 -- tools/compstatic/files.h | 2 +- tools/compstatic/global.h | 29 +++---- tools/compstatic/main.c | 7 +- tools/compstatic/misc.c | 6 +- tools/compstatic/overlay_defs.c | 17 ++-- tools/compstatic/overlay_defs.h | 11 ++- tools/compstatic/overlay_modules.c | 24 +++--- tools/compstatic/overlay_table.c | 16 ++-- tools/compstatic/overlay_table.h | 6 ++ tools/compstatic/static_module.c | 25 +++--- tools/compstatic/static_module.h | 13 +++ 18 files changed, 183 insertions(+), 203 deletions(-) diff --git a/tools/compstatic/component.c b/tools/compstatic/component.c index ab8f337f9..7486dc75c 100644 --- a/tools/compstatic/component.c +++ b/tools/compstatic/component.c @@ -10,7 +10,7 @@ #include "static_module.h" #include "str.h" -static bool ReadComponent(Component *component, char *a1, char *a2, char *overlayTable); +static bool ReadComponent(Component *component, char *staticModule, char *overlayDefs, char *overlayTable); static bool WriteComponent(Component *component); static bool ComponentAddSuffix(Component *component, char *suffix); static void FreeComponent(Component *component); @@ -25,7 +25,7 @@ bool ConvertComponent(Options *options, char *staticModule, char *overlayDefs, c if (success) { DebugPrintComponent(&component); if (!options->overlayModules || CompressOverlayModules(&component)) { - if (!options->overlayDigest || CalculateHMAC_OverlayModules(&component, options->unk10, options->digestKey)) { + if (!options->overlayDigest || CalculateHMAC_OverlayModules(&component, options->digestType, options->digestKey)) { if (!options->staticModule || CompressStaticModule(&component, options->headerSize)) { if (options->outSuffix == NULL || ComponentAddSuffix(&component, options->outSuffix)) { DebugPrintComponent(&component); @@ -105,10 +105,10 @@ static void DebugPrintComponent(Component *component) { char *filename; char c; uint staticParamsOffset = *(uint *)(component->staticModule.footerContent + 4); + StaticParams *staticParams = (StaticParams *)(component->staticModule.fileInfo.content + staticParamsOffset); DebugPrintf("-------------------------------------------------------------\n"); - // TODO: Replace offsets with constants! DebugPrintf("static.buffer.filename = %s\n" " .ptr = %p\n" " .size = %p %9d\n" @@ -121,14 +121,13 @@ static void DebugPrintComponent(Component *component) { component->staticModule.fileInfo.filename, component->staticModule.fileInfo.content, component->staticModule.fileInfo.fileSize, component->staticModule.fileInfo.fileSize, - component->staticModule.fileInfo.unkC, component->staticModule.fileInfo.unkC, + component->staticModule.fileInfo.compressedSize, component->staticModule.fileInfo.compressedSize, component->staticModule.footerSize, component->staticModule.footerSize, component->staticModule.footerContent, - *(uint *)(component->staticModule.footerContent), (*(uint *)(component->staticModule.footerContent) == 0xDEC00621) ? "NITROCODE" : "UNKNOWN!!", - *(uint *)(component->staticModule.footerContent + 4), *(uint *)(component->staticModule.footerContent + 4), - *(uint *)(component->staticModule.footerContent + 8), *(uint *)(component->staticModule.footerContent + 8)); + *(uint *)(component->staticModule.footerContent + STATIC_FOOTER_MAGIC_OFFSET), (*(uint *)(component->staticModule.footerContent + STATIC_FOOTER_MAGIC_OFFSET) == 0xDEC00621) ? "NITROCODE" : "UNKNOWN!!", + *(uint *)(component->staticModule.footerContent + STATIC_FOOTER_STATIC_PARAM_OFFSET), *(uint *)(component->staticModule.footerContent + STATIC_FOOTER_STATIC_PARAM_OFFSET), + *(uint *)(component->staticModule.footerContent + STATIC_FOOTER_DIGEST_PARAM_OFFSET), *(uint *)(component->staticModule.footerContent + STATIC_FOOTER_DIGEST_PARAM_OFFSET)); - // TODO: Replace offsets with constants! DebugPrintf("static.Params = %p\n" " .Params.autoloadList = %p\n" " .Params.autoloadListEnd = %p\n" @@ -137,18 +136,17 @@ static void DebugPrintComponent(Component *component) { " .Params.staticBssEnd = %p\n" " .Params.compressedStatic = %p\n", component->staticModule.fileInfo.content + staticParamsOffset, - *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset), - *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 4), - *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 8), - *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 12), - *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 16), - *(uint *)(component->staticModule.fileInfo.content + staticParamsOffset + 20)); + staticParams->autoloadList, + staticParams->autoloadListEnd, + staticParams->autoloadStart, + staticParams->staticBssStart, + staticParams->staticBssEnd, + staticParams->compressedStatic); DebugPrintf("-------------------------------------------------------------\n"); DebugPrintf("numOverlays = %d\n", component->numOverlays); DebugPrintf("-------------------------------------------------------------\n"); - // TODO: Replace offsets with constants! DebugPrintf("ovdefs.buffer.filename = %s\n" " .ptr = %p\n" " .size = %p %9d\n" @@ -162,12 +160,12 @@ static void DebugPrintComponent(Component *component) { component->overlayDefs.fileInfo.filename, component->overlayDefs.fileInfo.content, &component->overlayDefs.fileInfo.fileSize, component->overlayDefs.fileInfo.fileSize, - &component->overlayDefs.fileInfo.unkC, component->overlayDefs.fileInfo.unkC, - component->overlayDefs.content_dup, - *(uint *)(component->overlayDefs.content_dup + 0), - *(uint *)(component->overlayDefs.content_dup + 4), - component->overlayDefs.content_dup + 8, *(uint *)(component->overlayDefs.content_dup + 8), - *(uint *)(component->overlayDefs.content_dup + 12), + &component->overlayDefs.fileInfo.compressedSize, component->overlayDefs.fileInfo.compressedSize, + component->overlayDefs.header, + *(uint *)(component->overlayDefs.header + OVERLAY_DEFS_HEADER_LOAD_ADDRESS_OFFSET), + *(uint *)(component->overlayDefs.header + OVERLAY_DEFS_HEADER_ENTRY_ADDRESS_OFFSET), + component->overlayDefs.header + OVERLAY_DEFS_HEADER_MODULE_SIZE_OFFSET, *(uint *)(component->overlayDefs.header + OVERLAY_DEFS_HEADER_MODULE_SIZE_OFFSET), + *(uint *)(component->overlayDefs.header + OVERLAY_DEFS_HEADER_AUTOLOAD_DONE_OFFSET), component->dirName); filename = component->overlayFilenames; diff --git a/tools/compstatic/component.h b/tools/compstatic/component.h index 51226f8d0..fdcbd3488 100644 --- a/tools/compstatic/component.h +++ b/tools/compstatic/component.h @@ -4,7 +4,7 @@ #include #include "global.h" -bool ConvertComponent(Options *options, char *a1, char *a2, char *overlayTable); -void ConvertFinal(Options *options); // TODO: Remove if this goes unused +bool ConvertComponent(Options *options, char *staticModule, char *overlayDefs, char *overlayTable); +void ConvertFinal(Options *options); #endif // COMPONENT_H diff --git a/tools/compstatic/compress.c b/tools/compstatic/compress.c index 5986b216b..7b57df2ce 100644 --- a/tools/compstatic/compress.c +++ b/tools/compstatic/compress.c @@ -6,7 +6,9 @@ #include "digest.h" #include "global.h" #include "misc.h" +#include "overlay_table.h" #include "print.h" +#include "static_module.h" static int Compress(char *content, int size); static int LZCompressRV(char *uncompressed, int uncompressedSize, char *compressed, int compressedSize); @@ -16,45 +18,41 @@ static int CheckOverwrite(int sourceSize, char *compressed, int compressedSize, bool CompressOverlayModules(Component *component) { OverlayModule *overlayModule = component->overlayModules; - char *contentDup = component->overlayTable.content_dup; + char *overlayTable = component->overlayTable.table; DebugPrintf("Compressing OverlayModules\n"); - if (component->numOverlays == 0 || overlayModule == NULL || contentDup == NULL) { + if (component->numOverlays == 0 || overlayModule == NULL || overlayTable == NULL) { DebugPrintf("No overlay to compress\n"); } else { for (int i = 0; i < component->numOverlays; i++) { - // TODO: Replace offset with a constant! - if ((contentDup[0x1f] & 1) == 0) { - // TODO: Replace offset with a constant! Seems to be file size from overlay table - // TODO: Do I need to use (uint)?? - if ((uint)overlayModule->fileInfo.fileSize < *(uint *)(contentDup + 8)) { + if ((overlayTable[OT_COMPRESSED_FLAGS_OFFSET] & 1) == 0) { + if (overlayModule->fileInfo.fileSize < *(uint *)(overlayTable + OT_FILESIZE_OFFSET)) { ErrorPrintf("Overlay module file is shorter than the size reported in the overlay table\n" - "FileSize=%d InOverlayTable=%d\n", overlayModule->fileInfo.fileSize, *(uint *)(contentDup + 8)); + "FileSize=%d InOverlayTable=%d\n", overlayModule->fileInfo.fileSize, *(uint *)(overlayTable + OT_FILESIZE_OFFSET)); return false; } - // TODO: Try making this an int!! - uint compressResult = Compress(overlayModule->fileInfo.content, *(int *)(contentDup + 8)); - if ((int)compressResult < 0) { - if ((int)compressResult == -2 || (int)compressResult != -1) return false; + int compressResult = Compress(overlayModule->fileInfo.content, *(int *)(overlayTable + OT_FILESIZE_OFFSET)); + if (compressResult < 0) { + if (compressResult == -2 || compressResult != -1) return false; printf("OverlayModule[%02d]. Not compressed %9d (enlarged or same size as before)\n", i, overlayModule->fileInfo.fileSize); } else { - if ((int)compressResult > 0x00ffffff) { + if (compressResult > 0x00ffffff) { ErrorPrintf("Compressed file size too large (over 24bit wide)\n"); } printf("OverlayModule[%02d]. Compressed ... %9d -> %9d\n", i, overlayModule->fileInfo.fileSize, compressResult); - // TODO: Replace offset with a constant! - *(uint *)(contentDup + 0x1c) = (*(uint *)(contentDup + 0x1c) & 0xff000000) | (compressResult & 0x00ffffff); - overlayModule->fileInfo.unkC = compressResult & 0x00ffffff; - overlayModule->fileInfo.unkC = compressResult & 0x00ffffff; - contentDup[0x1f] |= 1; - overlayModule->fileInfo.unk10 = 1; - component->overlayTable.fileInfo.unk10 = 1; + uint *overlayTableCompressedSize = (uint *)(overlayTable + OT_COMPRESSED_FILESIZE_OFFSET); + *overlayTableCompressedSize = (*overlayTableCompressedSize & 0xff000000) | (compressResult & 0x00ffffff); + overlayModule->fileInfo.compressedSize = compressResult & 0x00ffffff; + overlayModule->fileInfo.compressedSize = compressResult & 0x00ffffff; + overlayTable[OT_COMPRESSED_FLAGS_OFFSET] |= 1; + overlayModule->fileInfo.rewrite = true; + component->overlayTable.fileInfo.rewrite = true; } } else { printf("OverlayModule[%02d]. Already compressed\n", i); } overlayModule++; - contentDup += 0x20; + overlayTable += OVERLAY_ENTRY_SIZE; } } return true; @@ -63,12 +61,11 @@ bool CompressOverlayModules(Component *component) { bool CompressStaticModule(Component *component, int headerSize) { bool success; - // TODO: Make sure integer parsing works with big and little endian! - int footerPtr = *(int *)(component->staticModule.footerContent + 4); + int staticParamsOffset = *(int *)(component->staticModule.footerContent + 4); char *content = component->staticModule.fileInfo.content; - // TODO: Replace offset with a constant! - if (*(int *)(content + footerPtr + 0x14) == 0 && - component->staticModule.fileInfo.unkC == 0) { + StaticParams *staticParams = (StaticParams *)(content + staticParamsOffset); + if (staticParams->compressedStatic == 0 && + component->staticModule.fileInfo.compressedSize == 0) { if (headerSize < 0) { ErrorPrintf("Specified header size is less than 0 (=%d)\n", headerSize); success = false; @@ -87,21 +84,17 @@ bool CompressStaticModule(Component *component, int headerSize) { success = true; } } else { - component->staticModule.fileInfo.unkC = compressResult + headerSize; - // TODO: Double-check the first arg! + component->staticModule.fileInfo.compressedSize = compressResult + headerSize; printf("StaticModule ..... Compressed ... %9d -> %9d\n", - component->staticModule.fileInfo.fileSize, component->staticModule.fileInfo.unkC); - // TODO: Figure out what this var is (a header?) - int *unknown = (int *)component->overlayDefs.content_dup; - unknown[2] = component->staticModule.fileInfo.unkC; - // TODO: Replace offset with a constant! - *(int *)(content + footerPtr + 0x14) = component->staticModule.fileInfo.unkC + unknown[0]; + component->staticModule.fileInfo.fileSize, component->staticModule.fileInfo.compressedSize); + int *header = (int *)component->overlayDefs.header; + header[2] = component->staticModule.fileInfo.compressedSize; + staticParams->compressedStatic = component->staticModule.fileInfo.compressedSize + header[0]; CopyBuffer(component->staticModule.footerContent, - // TODO: Consider making a macro: #define ALIGN_4(x) ((x + 3) & 0xfffffffc) - component->staticModule.fileInfo.content + ((component->staticModule.fileInfo.unkC + 3U) & 0xfffffffc), + component->staticModule.fileInfo.content + ALIGN_4(component->staticModule.fileInfo.compressedSize), component->staticModule.footerSize); - component->overlayDefs.fileInfo.unk10 = 1; - component->staticModule.fileInfo.unk10 = 1; + component->overlayDefs.fileInfo.rewrite = true; + component->staticModule.fileInfo.rewrite = true; success = true; } } @@ -112,52 +105,50 @@ bool CompressStaticModule(Component *component, int headerSize) { return success; } -bool CalculateHMAC_OverlayModules(Component *component, int a1, char *digestKey) { +bool CalculateHMAC_OverlayModules(Component *component, int digestType, char *digestKey) { bool success; OverlayModule *overlayModule = component->overlayModules; - char *contentDup = component->overlayTable.content_dup; + char *overlayTable = component->overlayTable.table; int numOverlays = component->numOverlays; - if (numOverlays == 0 || overlayModule == NULL || contentDup == NULL) { + if (numOverlays == 0 || overlayModule == NULL || overlayTable == NULL) { DebugPrintf("No overlay to calculate HMAC\n"); success = true; } else { - bool initDigestSuccess = Init_Digest(a1, digestKey); + bool initDigestSuccess = Init_Digest(digestType, digestKey); if (!initDigestSuccess) { ErrorPrintf("Cannot setup digest library\n"); success = false; } else { DebugPrintf("Calculating HMAC for OverlayModules\n"); - // TODO: Fill in all the unknown vars and offsets below! - // NOTE TO SELF: Replaced `initDigestSuccess` re-use with new var `unknown3`. - int unknown3 = *(int *)(component->staticModule.footerContent + 8); + int digestParamsOffset = *(int *)(component->staticModule.footerContent + STATIC_FOOTER_DIGEST_PARAM_OFFSET); char *content = component->staticModule.fileInfo.content; - char *unknown1 = component->staticModule.fileInfo.content + *(int *)(component->staticModule.footerContent + 8); + char *digestParams = (char *)(content + digestParamsOffset); for (int i = 0; i < numOverlays; i++) { - if (contentDup[0x1f] & 2U != 0) { + if (overlayTable[OT_COMPRESSED_FLAGS_OFFSET] & 2U != 0) { printf("OverlayModule[%02d]: HMAC already calculated - do it again.\n", i); } - if ((uint)overlayModule->fileInfo.fileSize < *(uint *)(contentDup + 8)) { + if ((uint)overlayModule->fileInfo.fileSize < *(uint *)(overlayTable + OT_FILESIZE_OFFSET)) { ErrorPrintf("Overlay module file is shorter than the size reported in overlay table\n" - " File size=%d InOverlayTabe=%d\n", overlayModule->fileInfo.fileSize, *(uint *)(contentDup + 8)); + " File size=%d InOverlayTabe=%d\n", overlayModule->fileInfo.fileSize, *(uint *)(overlayTable + OT_FILESIZE_OFFSET)); return false; } - uint unknown2 = *(uint *)(contentDup + 0x1c) & 0x00ffffff; - if (unknown2 == 0) { - unknown2 = *(uint *)(contentDup + 8); + uint overlaySize = *(uint *)(overlayTable + OT_COMPRESSED_FILESIZE_OFFSET) & 0x00ffffff; + if (overlaySize == 0) { + overlaySize = *(uint *)(overlayTable + OT_FILESIZE_OFFSET); } printf("OverlayModule[%02d]", i); - Calc_Digest(overlayModule->fileInfo.content, unknown2, unknown1, 0); - contentDup[0x1f] |= 2; - component->staticModule.fileInfo.unk10 = 1; - component->overlayTable.fileInfo.unk10 = 1; - unknown1 += 0x14; + Calc_Digest(overlayModule->fileInfo.content, overlaySize, digestParams, false); + overlayTable[OT_COMPRESSED_FLAGS_OFFSET] |= 2; + component->staticModule.fileInfo.rewrite = true; + component->overlayTable.fileInfo.rewrite = true; + digestParams += DIGEST_HASH_SIZE; overlayModule++; - contentDup += 0x20; + overlayTable += OVERLAY_ENTRY_SIZE; } printf("OverlayTable "); - Calc_Digest(component->overlayTable.content_dup, numOverlays << 5, content + unknown3 - 0x14, 1); + Calc_Digest(component->overlayTable.table, numOverlays * OVERLAY_ENTRY_SIZE, content + digestParamsOffset - DIGEST_HASH_SIZE, true); success = true; } } @@ -174,7 +165,7 @@ static int Compress(char *content, int size) { if (compressed == NULL) { ErrorPrintf("Cannot allocate memory size=%d\n", size); ret = -2; - } else if (((size_t)content % 4) == 0) { // CLEAN UP: Replaced (uint) cast with (size_t) cast + } else if (((size_t)content % 4) == 0) { char *contentCpy = content; int sizeCpy = size; int compressedSize = size; @@ -187,7 +178,6 @@ static int Compress(char *content, int size) { compressedSize -= lzResult; compressed += lzResult; DebugPrintf("1: source size = %d compressed = %d\n", size, compressedSize); - // CLEAN UP: Replaced `lzResult` with `overWriteResult` int overwriteResult = CheckOverwrite(sizeCpy, compressed, compressedSize, &sourceOffset, &compressedOffset); if (overwriteResult == 0) { contentCpy += sourceOffset; @@ -198,9 +188,8 @@ static int Compress(char *content, int size) { " !! Expand non-compressed region = +%d\n" "2: source size = %d compressed = %d\n", sourceOffset, sizeCpy, compressedSize); } - // CLEAN UP: Replaced `lzResult` with `compressedEnd` int compressedEnd = compressedSize + sourceOffset; - uint compressedEndAligned = (compressedEnd + 3) & 0xfffffffc; + uint compressedEndAligned = ALIGN_4(compressedEnd); ret = compressedEndAligned + 8; if (ret < size) { CopyBuffer(compressed, contentCpy, compressedSize); @@ -227,9 +216,6 @@ static int Compress(char *content, int size) { return ret; } -// Parameters: -// - A buffer with the uncompressed byte array, and size of buffer -// - A buffer for the compressed byte array, and size of buffer static int LZCompressRV(char *uncompressed, int uncompressedSize, char *compressed, int compressedSize) { int optimalRemainderIdx; ushort optimalRemainderIdx16; @@ -247,9 +233,7 @@ static int LZCompressRV(char *uncompressed, int uncompressedSize, char *compress char *remainder = uncompressed + bytesLeft; int bytesRead = uncompressedSize - bytesLeft; int chunkSize = MIN(bytesLeft, 0x12); - // CLEAN UP: Removed var `unused` char *chunk = remainder - chunkSize; - // CLEAN UP: Replaced `bytesReadLimit` with `bytesRead` bytesRead = MIN(bytesRead, 0x1002); int numMatches = FindMatched(chunk, chunkSize, remainder, bytesRead, &optimalRemainderIdx); if (numMatches < 3) { @@ -314,8 +298,6 @@ static int HowManyMatched(char *buffer1, char *buffer2, int size) { } static int CheckOverwrite(int sourceSize, char *compressed, int compressedSize, int *sourceOffset, int *compressedOffset) { - // CLEAN UP: Replaced `compressedSizeCpy` and `sourceSizeCpy` with - // `compressedSize` and `sourceSize`, respectively. do { if (sourceSize < 1) { *sourceOffset = 0; @@ -339,7 +321,6 @@ static int CheckOverwrite(int sourceSize, char *compressed, int compressedSize, compressedSize = nextCompressedSize; if (sourceSize < nextCompressedSize) { *sourceOffset = sourceSize; - // CLEAN UP: Replaced `nextCompressedSize` with `compressedSize`. *compressedOffset = compressedSize; return 0; } diff --git a/tools/compstatic/compress.h b/tools/compstatic/compress.h index 140d495fc..ed62fac36 100644 --- a/tools/compstatic/compress.h +++ b/tools/compstatic/compress.h @@ -6,6 +6,6 @@ bool CompressOverlayModules(Component *component); bool CompressStaticModule(Component *component, int headerSize); -bool CalculateHMAC_OverlayModules(Component *component, int a1, char *digestKey); +bool CalculateHMAC_OverlayModules(Component *component, int digestType, char *digestKey); #endif // COMPRESS_H diff --git a/tools/compstatic/digest.c b/tools/compstatic/digest.c index 8fd38198c..7ed9d2107 100644 --- a/tools/compstatic/digest.c +++ b/tools/compstatic/digest.c @@ -38,14 +38,14 @@ typedef struct { Hash2GetDigestCb hash2GetDigest; } HmacParam; -static void DGT_Hash2CalcHmac(char *hash, char *content, int a2, char *a3, int a4); -static int DGT_SetOverlayTableMode(int mode); +static void DGT_Hash2CalcHmac(char *hash, char *content, int size, char *digestKey, int digestKeySize); +static bool DGT_SetOverlayTableMode(bool mode); static bool DGT_Hash2Reset(HashWork *hashWork); static uint DGT_Hash2SetSource(HashWork *hashWork, char *digestKey, int digestKeySize); static uint DGT_Hash2GetDigest(HashWork *hashWork, char *digestBuffer); static void DGT_Hash2SetPadding(HashWork *hashWork); static void DGT_Hash2DoProcess(HashWork *hashWork); -static void HmacCalc(char *hash, char *a1, int a2, char *digestKey, int digestKeySize, HmacParam *param); +static void HmacCalc(char *hash, char *content, int size, char *digestKey, int digestKeySize, HmacParam *param); // Set default DigestFunc DigestFunc gDigestFunc = DGT_Hash2CalcHmac; @@ -101,32 +101,28 @@ bool Init_Digest(uint digestType, char *digestKey) { return success; } -void Calc_Digest(char *content, int a1, char *a2, int a3) { - byte hash[40]; // CLEAN UP: Called `local_2c` in Ghidra +void Calc_Digest(char *content, int size, char *hash, bool overlayTableMode) { + byte hashBuffer[40]; - int overlayTableMode = DGT_SetOverlayTableMode(a3); - gDigestFunc(hash, content, a1, gDigestKey, gDigestKeySize); - DGT_SetOverlayTableMode(overlayTableMode); + bool oldMode = DGT_SetOverlayTableMode(overlayTableMode); + gDigestFunc(hashBuffer, content, size, gDigestKey, gDigestKeySize); + DGT_SetOverlayTableMode(oldMode); int iCpy = 0; - // CLEAN UP: Initialized as 0, but OG uses *(gDigestFunc + 4). for (int i = 0; i < 20; i++) { - hash[i] = hash[iCpy + 1] ^ hash[iCpy]; + hashBuffer[i] = hashBuffer[iCpy + 1] ^ hashBuffer[iCpy]; iCpy++; } printf(": Digest "); for (int i = 0; i < 20; i++) { - printf("%02X", hash[i]); + printf("%02X", hashBuffer[i]); } - // CLEAN UP: Is (long int) cast necessary? Is `int` not 32 bits? If so, - // that's a problem... - printf(" %8ld\n", (long int)a1); - CopyBuffer(hash, a2, 20); + printf(" %8ld\n", (long int)size); + CopyBuffer(hashBuffer, hash, 20); } -static void DGT_Hash2CalcHmac(char *hash, char *content, int a2, char *digestKey, int digestKeySize) { +static void DGT_Hash2CalcHmac(char *hash, char *content, int size, char *digestKey, int digestKeySize) { HashWork hashWork; char unkBuffer1[0x20]; - // CLEAN UP: OG has a loop that initializes each field to 0. HmacParam param = {0}; param.unk0 = 20; @@ -136,11 +132,11 @@ static void DGT_Hash2CalcHmac(char *hash, char *content, int a2, char *digestKey param.hash2Reset = DGT_Hash2Reset; param.hash2SetSource = DGT_Hash2SetSource; param.hash2GetDigest = DGT_Hash2GetDigest; - HmacCalc(hash, content, a2, digestKey, digestKeySize, ¶m); + HmacCalc(hash, content, size, digestKey, digestKeySize, ¶m); } -static int DGT_SetOverlayTableMode(int mode) { - int oldMode = gOverlayTableMode; +static bool DGT_SetOverlayTableMode(bool mode) { + bool oldMode = gOverlayTableMode; gOverlayTableMode = mode; return oldMode; } @@ -209,7 +205,6 @@ static uint DGT_Hash2GetDigest(HashWork *hashWork, char *digestBuffer) { hashWork->unk60 = 1; } for (int i = 0; i < 20; i++) { - // CLEAN UP: Replaced byte literals with unsigned ints (e.g. 3u, 8u). digestBuffer[i] = (char)(*(uint *)(hashWork->unk20 + (i >> 2) * 4 + -0x20) >> ((3u - ((byte)i % 4)) * 8u & 0x1f)); } ret = 0; @@ -258,7 +253,7 @@ static void DGT_Hash2DoProcess(HashWork *hashWork) { uint buffer[99]; int i, idx; - if (gOverlayTableMode != 0) { + if (gOverlayTableMode) { buffer[10] = *(uint *)(hashWork->unk20 + 0x18); buffer[9] = *(uint *)(hashWork->unk20 + 0x38); *(uint *)(hashWork->unk20 + 0x18) = 0; @@ -325,13 +320,13 @@ static void DGT_Hash2DoProcess(HashWork *hashWork) { hashWork->unkC = buffer[12] + hashWork->unkC; hashWork->unk10 = buffer[11] + hashWork->unk10; hashWork->unk1C = 0; - if (gOverlayTableMode != 0) { + if (gOverlayTableMode) { *(uint *)(hashWork->unk20 + 0x18) = buffer[10]; *(uint *)(hashWork->unk20 + 0x38) = buffer[9]; } } -static void HmacCalc(char *hash, char *content, int a2, char *digestKey, int digestKeySize, HmacParam *param) { +static void HmacCalc(char *hash, char *content, int size, char *digestKey, int digestKeySize, HmacParam *param) { byte digestBuffer[0x4C]; byte *key; int keySize; @@ -339,7 +334,7 @@ static void HmacCalc(char *hash, char *content, int a2, char *digestKey, int dig char outerKey[0x40]; int i; - if (hash != NULL && content != NULL && a2 != 0 && digestKey != NULL && + if (hash != NULL && content != NULL && size != 0 && digestKey != NULL && digestKeySize != 0 && param != NULL) { if (param->blockSize < digestKeySize) { param->hash2Reset(param->hashWork); @@ -359,7 +354,7 @@ static void HmacCalc(char *hash, char *content, int a2, char *digestKey, int dig } param->hash2Reset(param->hashWork); param->hash2SetSource(param->hashWork, innerKey, param->blockSize); - param->hash2SetSource(param->hashWork, content, a2); + param->hash2SetSource(param->hashWork, content, size); param->hash2GetDigest(param->hashWork, param->unkC); for (i = 0; i < keySize; i++) { diff --git a/tools/compstatic/digest.h b/tools/compstatic/digest.h index ebb292a1d..5890ba1f9 100644 --- a/tools/compstatic/digest.h +++ b/tools/compstatic/digest.h @@ -4,16 +4,17 @@ #include #include "global.h" -#define DIGEST_KEY_SIZE (0x40) +#define DIGEST_KEY_SIZE (0x40) +#define DIGEST_HASH_SIZE (0x14) -typedef void (*DigestFunc)(char *a0, char *content, int a2, char *digestKey, int digestKeySize); +typedef void (*DigestFunc)(char *hash, char *content, int size, char *digestKey, int digestKeySize); DigestFunc gDigestFunc; char *gDigestKey; int gDigestKeySize; -int gOverlayTableMode; +bool gOverlayTableMode; bool Init_Digest(uint digestType, char *digestKey); -void Calc_Digest(char *content, int a1, char *a2, int a3); +void Calc_Digest(char *content, int size, char *hash, bool overlayTableMode); #endif // DIGEST_H diff --git a/tools/compstatic/files.c b/tools/compstatic/files.c index d754171ea..5f815b2e6 100644 --- a/tools/compstatic/files.c +++ b/tools/compstatic/files.c @@ -22,7 +22,6 @@ char *GetDirName(char *filename) { } if (filename[i] == '/' || filename[i] == '\\') break; if (filename[i] == ':') { - // TODO: Slightly adjusted logic to remove `prev_i` dirName = malloc(i + 3); if (dirName != NULL) { strncpy(dirName, filename, i); @@ -54,7 +53,6 @@ bool GetFiles(char *responseFile, SourceFiles *sourceFiles) { success = false; } else { numWords = 0; - // TODO: I added this variable to get StrCat to work wordStart = 0; for (int i = 0; i < bytesRead; i++) { if (content[i] == '\0') { @@ -83,8 +81,6 @@ bool GetFiles(char *responseFile, SourceFiles *sourceFiles) { } // Returns size of file. -// TODO: Double-check that `content` is char ** -// NOTE: There were 3 args that weren't read at all. Removed. int ReadFile(char *filename, char **content) { int bytesRead; struct stat fileInfo; @@ -94,7 +90,6 @@ int ReadFile(char *filename, char **content) { if (filename == NULL) { ErrorPrintf("Not specified filename\n"); } else { - // TODO: I think OG does a mode_t check? Probably not necessary, and can be removed. int error = stat(filename, &fileInfo); if ((error == 0) && (fp = fopen(filename, "rb"), fp != NULL)) { *content = malloc(fileInfo.st_size); diff --git a/tools/compstatic/files.h b/tools/compstatic/files.h index 44ea43fce..e66d34dbd 100644 --- a/tools/compstatic/files.h +++ b/tools/compstatic/files.h @@ -6,7 +6,7 @@ char *GetDirName(char *filename); bool GetFiles(char *responseFile, SourceFiles *sourceFiles); -int ReadFile(char *filename, char **content); // TODO: Double-check: it passes a bunch of stack variables.. +int ReadFile(char *filename, char **content); int WriteFile(char *filename, char *content, int size); #endif // FILES_H diff --git a/tools/compstatic/global.h b/tools/compstatic/global.h index dc31af15b..2e4c28f2e 100644 --- a/tools/compstatic/global.h +++ b/tools/compstatic/global.h @@ -10,17 +10,16 @@ typedef unsigned int uint; #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -// NOTE TO SELF: All the fields are ints in the original! +#define ALIGN_4(addr) ((addr + 3U) & 0xfffffffc) + typedef struct { bool staticModule; int headerSize; // size in bytes bool overlayModules; bool overlayDigest; - int unk10; + int digestType; char *digestKey; char *outSuffix; - int unk1C; // stack allocated but unitialized - delete? - int unk20; // stack allocated but unitialized - delete? } Options; #define SOURCE_FILES_STATIC_MODULE 0 @@ -38,31 +37,29 @@ typedef struct { char *filename; char *content; int fileSize; - int unkC; - int unk10; -} FileInfo; // sizeof == 0x14 + int compressedSize; + bool rewrite; // File should be updated after compression +} FileInfo; // win32 sizeof == 0x14 typedef struct { FileInfo fileInfo; char *footerContent; uint footerSize; -} StaticModule; // sizeof == 0x1c +} StaticModule; // win32 sizeof == 0x1c typedef struct { FileInfo fileInfo; - char *content_dup; -} OverlayDefs; // sizeof == 0x18 + char *header; +} OverlayDefs; // win32 sizeof == 0x18 typedef struct { FileInfo fileInfo; -} OverlayModule; // sizeof == 0x14 +} OverlayModule; // win32 sizeof == 0x14 -// TODO: Size seems to be 0x18 from ReadOverlayTable(). Make sure this is -// consistent with other usages. typedef struct { FileInfo fileInfo; - char *content_dup; -} OverlayTable; // sizeof == 0x18 + char *table; // == fileInfo.content +} OverlayTable; // win32 sizeof == 0x18 typedef struct { StaticModule staticModule; @@ -72,6 +69,6 @@ typedef struct { char *dirName; OverlayTable overlayTable; OverlayModule *overlayModules; -} Component; // size: 0x5c +} Component; // win32 sizeof: 0x5c #endif // GLOBAL_H diff --git a/tools/compstatic/main.c b/tools/compstatic/main.c index b46d6e903..0c051d8af 100644 --- a/tools/compstatic/main.c +++ b/tools/compstatic/main.c @@ -9,7 +9,6 @@ #include "print.h" #include "str.h" -// Global vars bool gDebugMode = false; void InitializeOptions(Options *options) { @@ -17,7 +16,7 @@ void InitializeOptions(Options *options) { options->headerSize = 0x4000; options->overlayModules = false; options->overlayDigest = false; - options->unk10 = 2; + options->digestType = 2; options->digestKey = StrDup(NULL, NULL); options->outSuffix = StrDup(NULL, "_LZ"); } @@ -64,10 +63,10 @@ int main(int argc, char *argv[]) { break; // Not referenced in usage case 'A': - options.unk10 = atoi(optarg); + options.digestType = atoi(optarg); break; case 'F': - options.outSuffix = StrDup(options.outSuffix, NULL); // TODO: Check if NULL or "" + options.outSuffix = StrDup(options.outSuffix, NULL); break; case 'a': options.overlayDigest = true; diff --git a/tools/compstatic/misc.c b/tools/compstatic/misc.c index d6837efc1..e54bbb6b9 100644 --- a/tools/compstatic/misc.c +++ b/tools/compstatic/misc.c @@ -26,9 +26,9 @@ void FreeBuffer(FileInfo *fileInfo) { free(fileInfo->filename); fileInfo->filename = NULL; } - fileInfo->unkC = 0; + fileInfo->compressedSize = 0; fileInfo->fileSize = 0; - fileInfo->unk10 = 0; + fileInfo->rewrite = false; } bool AddSuffixBuffer(FileInfo *fileInfo, char *suffix) { @@ -47,7 +47,7 @@ bool AddSuffixBuffer(FileInfo *fileInfo, char *suffix) { sprintf(dest, "%s%s", fileInfo->filename, suffix); free(fileInfo->filename); fileInfo->filename = dest; - fileInfo->unk10 = 1; + fileInfo->rewrite = true; success = true; } } diff --git a/tools/compstatic/overlay_defs.c b/tools/compstatic/overlay_defs.c index 8df58de65..8839dfaac 100644 --- a/tools/compstatic/overlay_defs.c +++ b/tools/compstatic/overlay_defs.c @@ -13,10 +13,10 @@ bool ReadOverlayDefs(Component *component, char *filename) { bool success = false; DebugPrintf("Reading overlayDefs=%s\n", filename); - int fileSize = ReadFile(filename, &component->overlayDefs.fileInfo.content); // TODO: Double-check: it passes a bunch of stack variables.. + int fileSize = ReadFile(filename, &component->overlayDefs.fileInfo.content); component->overlayDefs.fileInfo.fileSize = fileSize; - component->overlayDefs.fileInfo.unkC = 0; - component->overlayDefs.fileInfo.unk10 = 0; + component->overlayDefs.fileInfo.compressedSize = 0; + component->overlayDefs.fileInfo.rewrite = false; component->overlayDefs.fileInfo.filename = strdup(filename); if (component->overlayDefs.fileInfo.fileSize < 0) { @@ -25,8 +25,8 @@ bool ReadOverlayDefs(Component *component, char *filename) { ErrorPrintf("Overlaydefs is too small (size=%d). Must be >= %d\n", component->overlayDefs.fileInfo.fileSize, MIN_OVERLAY_DEFS_FILE_SIZE); success = false; } else { - component->overlayDefs.content_dup = component->overlayDefs.fileInfo.content; - component->overlayFilenames = component->overlayDefs.content_dup + OVERLAY_DEFS_FILENAMES_OFFSET; + component->overlayDefs.header = component->overlayDefs.fileInfo.content; + component->overlayFilenames = component->overlayDefs.header + OVERLAY_DEFS_FILENAMES_OFFSET; component->dirName = GetDirName(filename); if (component->dirName == NULL) { success = false; @@ -55,12 +55,11 @@ bool WriteOverlayDefs(Component *component) { bool success; OverlayDefs *overlayDefs = &component->overlayDefs; - if (overlayDefs->fileInfo.unk10 == 0) { + if (!overlayDefs->fileInfo.rewrite) { success = true; } else { DebugPrintf("Writing overlayDefs=%s\n", overlayDefs->fileInfo.filename); - if (overlayDefs->fileInfo.unkC == 0) { - // CLEAN UP: I re-wrote this from (success := ~sizeWriten >> 0x1f) + if (overlayDefs->fileInfo.compressedSize == 0) { sizeWritten = WriteFile(overlayDefs->fileInfo.filename, overlayDefs->fileInfo.content, overlayDefs->fileInfo.fileSize); success = sizeWritten >= 0; } else { @@ -79,7 +78,7 @@ bool AddSuffixOverlayDefs(Component *component, char *suffix) { void FreeOverlayDefs(Component *component) { DebugPrintf("Releasing overlayDefs\n"); FreeBuffer(&component->overlayDefs.fileInfo); - component->overlayDefs.content_dup = NULL; + component->overlayDefs.header = NULL; component->overlayFilenames = NULL; if (component->dirName != NULL) { free(component->dirName); diff --git a/tools/compstatic/overlay_defs.h b/tools/compstatic/overlay_defs.h index dab23540d..0d83c4fcc 100644 --- a/tools/compstatic/overlay_defs.h +++ b/tools/compstatic/overlay_defs.h @@ -4,10 +4,15 @@ #include #include "global.h" -#define MIN_OVERLAY_DEFS_FILE_SIZE 0x10 -#define OVERLAY_DEFS_FOOTER_OFFSET 0x8 +#define MIN_OVERLAY_DEFS_FILE_SIZE 0x10 +#define OVERLAY_DEFS_FOOTER_OFFSET 0x8 #define OVERLAY_DEFS_FILENAMES_OFFSET 0x10 -#define OVERLAY_DEFS_FILENAMES_SIZE 0x10 +#define OVERLAY_DEFS_FILENAMES_SIZE 0x10 + +#define OVERLAY_DEFS_HEADER_LOAD_ADDRESS_OFFSET 0 +#define OVERLAY_DEFS_HEADER_ENTRY_ADDRESS_OFFSET 4 +#define OVERLAY_DEFS_HEADER_MODULE_SIZE_OFFSET 8 +#define OVERLAY_DEFS_HEADER_AUTOLOAD_DONE_OFFSET 12 bool ReadOverlayDefs(Component *component, char *filename); bool WriteOverlayDefs(Component *component); diff --git a/tools/compstatic/overlay_modules.c b/tools/compstatic/overlay_modules.c index ccd764068..f000b0c30 100644 --- a/tools/compstatic/overlay_modules.c +++ b/tools/compstatic/overlay_modules.c @@ -35,15 +35,13 @@ bool ReadOverlayModules(Component *component) { ErrorPrintf("Cannot allocate memory\n"); return false; } - // TODO: Make sure that this copies only the current filename - // and not the whole `overlayFilenames` string! sprintf(overlayModules->fileInfo.filename, "%s/%s", dirName, overlayFilenames); DebugPrintf("Reading overlay[%d]=%s\n", i, overlayModules->fileInfo.filename); int fileSize = ReadFile(overlayModules->fileInfo.filename, &overlayModules->fileInfo.content); overlayModules->fileInfo.fileSize = fileSize; - overlayModules->fileInfo.unkC = 0; - overlayModules->fileInfo.unk10 = 0; + overlayModules->fileInfo.compressedSize = 0; + overlayModules->fileInfo.rewrite = false; if (overlayModules->fileInfo.fileSize < 0) return false; overlayModules++; @@ -66,9 +64,9 @@ bool WriteOverlayModules(Component *component) { if (i >= component->numOverlays) { return true; } - if (overlayModule->fileInfo.unk10 != 0) { + if (overlayModule->fileInfo.rewrite) { DebugPrintf("Writing overlay[%d]=%s\n", i, overlayModule->fileInfo.filename); - int overlaySize = overlayModule->fileInfo.unkC ? overlayModule->fileInfo.unkC : overlayModule->fileInfo.fileSize; + int overlaySize = overlayModule->fileInfo.compressedSize ? overlayModule->fileInfo.compressedSize : overlayModule->fileInfo.fileSize; int sizeWritten = WriteFile(overlayModule->fileInfo.filename, overlayModule->fileInfo.content, overlaySize); if (sizeWritten < 0) { return false; @@ -96,11 +94,11 @@ bool AddSuffixOverlayModules(Component *component, char *suffix) { ErrorPrintf("Cannot allocate memory\n"); success = false; } else { - uint *contentDup32 = (uint *)component->overlayDefs.content_dup; - *(uint *)buffer = contentDup32[0]; - *(uint *)(buffer + 4) = contentDup32[1]; - *(uint *)(buffer + 8) = contentDup32[2]; - *(uint *)(buffer + 0xc) = contentDup32[3]; + uint *header32 = (uint *)component->overlayDefs.header; + *(uint *)buffer = header32[0]; + *(uint *)(buffer + 4) = header32[1]; + *(uint *)(buffer + 8) = header32[2]; + *(uint *)(buffer + 0xc) = header32[3]; char *contentPtr = buffer + 0x10; char *ovFilename = component->overlayFilenames; @@ -124,8 +122,8 @@ bool AddSuffixOverlayModules(Component *component, char *suffix) { free(component->overlayDefs.fileInfo.content); component->overlayDefs.fileInfo.content = buffer; component->overlayDefs.fileInfo.fileSize = fileSize; - component->overlayDefs.fileInfo.unk10 = 1; - component->overlayDefs.content_dup = buffer; + component->overlayDefs.fileInfo.rewrite = true; + component->overlayDefs.header = buffer; component->overlayFilenames = buffer + 0x10; success = true; } diff --git a/tools/compstatic/overlay_table.c b/tools/compstatic/overlay_table.c index 7217f5e5e..cf0a3445c 100644 --- a/tools/compstatic/overlay_table.c +++ b/tools/compstatic/overlay_table.c @@ -6,8 +6,6 @@ #include "overlay_table.h" #include "print.h" -#define OVERLAY_ENTRY_SIZE (32) - bool ReadOverlayTable(Component *component, char *filename) { OverlayTable *overlayTable = &component->overlayTable; if (filename == NULL || component->numOverlays < 1) { @@ -16,17 +14,16 @@ bool ReadOverlayTable(Component *component, char *filename) { overlayTable->fileInfo.fileSize = 0; overlayTable->fileInfo.filename = NULL; } else { - // TODO: Removed duplicate var `ovTable2`. Clean up DebugPrintf("Reading overlayTable=%s\n", filename); int fileSize = ReadFile(filename, &overlayTable->fileInfo.content); overlayTable->fileInfo.fileSize = fileSize; overlayTable->fileInfo.filename = strdup(filename); } - overlayTable->fileInfo.unkC = false; - overlayTable->fileInfo.unk10 = 0; + overlayTable->fileInfo.compressedSize = 0; + overlayTable->fileInfo.rewrite = false; bool success = overlayTable->fileInfo.fileSize == component->numOverlays * OVERLAY_ENTRY_SIZE; if (success) { - overlayTable->content_dup = overlayTable->fileInfo.content; + overlayTable->table = overlayTable->fileInfo.content; } else { ErrorPrintf("Not matched number of overlays and size of overlay table\n"); } @@ -37,15 +34,14 @@ bool WriteOverlayTable(Component *component) { bool success; OverlayTable *overlayTable = &component->overlayTable; - if (overlayTable->fileInfo.unk10 == 0) { + if (!overlayTable->fileInfo.rewrite) { success = true; } else if (overlayTable->fileInfo.filename == NULL) { ErrorPrintf("No filename specified for overlay table\n"); success = false; } else { DebugPrintf("Writing overlayTable=%s\n", overlayTable->fileInfo.filename); - if (overlayTable->fileInfo.unkC == 0) { - // CLEAN UP: I re-wrote this from (success := ~sizeWriten >> 0x1f) + if (overlayTable->fileInfo.compressedSize == 0) { int sizeWritten = WriteFile(overlayTable->fileInfo.filename, overlayTable->fileInfo.content, overlayTable->fileInfo.fileSize); success = sizeWritten >= 0; } else { @@ -76,5 +72,5 @@ void FreeOverlayTable(Component *component) { DebugPrintf("Releasing overlayTable\n"); FreeBuffer(&component->overlayTable.fileInfo); } - component->overlayTable.content_dup = NULL; + component->overlayTable.table = NULL; } diff --git a/tools/compstatic/overlay_table.h b/tools/compstatic/overlay_table.h index f649d3bfa..7343a2dba 100644 --- a/tools/compstatic/overlay_table.h +++ b/tools/compstatic/overlay_table.h @@ -4,6 +4,12 @@ #include #include "component.h" +#define OVERLAY_ENTRY_SIZE 32 + +#define OT_FILESIZE_OFFSET 0x8 +#define OT_COMPRESSED_FILESIZE_OFFSET 0x1c +#define OT_COMPRESSED_FLAGS_OFFSET 0x1f + bool ReadOverlayTable(Component *component, char *filename); bool WriteOverlayTable(Component *component); bool AddSuffixOverlayTable(Component *component, char *suffix); diff --git a/tools/compstatic/static_module.c b/tools/compstatic/static_module.c index 72994136c..84a26d5ad 100644 --- a/tools/compstatic/static_module.c +++ b/tools/compstatic/static_module.c @@ -10,32 +10,30 @@ bool ReadStaticModule(Component *component, char *filename) { bool success; - // TODO: Note that OG makes changes on component directly. StaticModule *staticModule = &component->staticModule; DebugPrintf("Reading staticModule=%s\n", filename); int fileSize = ReadFile(filename, &staticModule->fileInfo.content); staticModule->fileInfo.fileSize = fileSize; - staticModule->fileInfo.unkC = 0; - staticModule->fileInfo.unk10 = 0; + staticModule->fileInfo.compressedSize = 0; + staticModule->fileInfo.rewrite = false; staticModule->fileInfo.filename = strdup(filename); if (staticModule->fileInfo.fileSize < 0) { success = false; } else if (staticModule->fileInfo.fileSize % 4 == 0) { - int footerOffset = *(int *)(component->overlayDefs.content_dup + OVERLAY_DEFS_FOOTER_OFFSET); - uint footerOffsetAligned = (footerOffset + 3) & 0xfffffffc; + int footerOffset = *(int *)(component->overlayDefs.header + OVERLAY_DEFS_FOOTER_OFFSET); + uint footerOffsetAligned = ALIGN_4(footerOffset); staticModule->footerSize = staticModule->fileInfo.fileSize - footerOffsetAligned; staticModule->footerContent = staticModule->fileInfo.content + footerOffsetAligned; staticModule->fileInfo.fileSize = footerOffset; - // CLEAN UP: Consider simplifying: Make a local int variable for - // (staticModule->footerContent + 4). - if (staticModule->footerSize < 0xc || *(uint *)staticModule->footerContent != 0xDEC00621) { + int staticParamsOffset = *(uint *)(staticModule->footerContent + 4); + if (staticModule->footerSize < 0xc || *(uint *)(staticModule->footerContent + STATIC_FOOTER_MAGIC_OFFSET) != 0xDEC00621) { ErrorPrintf("Static module is older format (No footer extension).\n"); success = false; - } else if ((*(uint *)(staticModule->footerContent + 4) % 4 == 0) && - (*(int *)(staticModule->footerContent + 4) > -1) && - (*(int *)(staticModule->footerContent + 4) < footerOffset)) { + } else if (((staticParamsOffset % 4) == 0) && + (staticParamsOffset > -1) && + (staticParamsOffset < footerOffset)) { success = true; } else { ErrorPrintf("Static module is illegal format (Unknown footer format).\n"); @@ -52,12 +50,11 @@ bool WriteStaticModule(Component *component) { bool success; StaticModule *staticModule = &component->staticModule; - if (staticModule->fileInfo.unk10 == 0) { + if (!staticModule->fileInfo.rewrite) { success = true; } else { DebugPrintf("Writing staticModule=%s\n", staticModule->fileInfo.filename); - int fileSize = staticModule->fileInfo.unkC ? staticModule->fileInfo.unkC : staticModule->fileInfo.fileSize; - // CLEAN UP: I re-wrote this from (success := ~sizeWriten >> 0x1f) + int fileSize = staticModule->fileInfo.compressedSize ? staticModule->fileInfo.compressedSize : staticModule->fileInfo.fileSize; int sizeWritten = WriteFile(staticModule->fileInfo.filename, staticModule->fileInfo.content, fileSize + staticModule->footerSize); success = sizeWritten >= 0; } diff --git a/tools/compstatic/static_module.h b/tools/compstatic/static_module.h index 33de99ef2..15691a2fa 100644 --- a/tools/compstatic/static_module.h +++ b/tools/compstatic/static_module.h @@ -4,6 +4,19 @@ #include #include "global.h" +#define STATIC_FOOTER_MAGIC_OFFSET (0) +#define STATIC_FOOTER_STATIC_PARAM_OFFSET (4) +#define STATIC_FOOTER_DIGEST_PARAM_OFFSET (8) + +typedef struct { + uint autoloadList; + uint autoloadListEnd; + uint autoloadStart; + uint staticBssStart; + uint staticBssEnd; + int compressedStatic; +} StaticParams; + bool ReadStaticModule(Component *component, char *filename); bool WriteStaticModule(Component *component); bool AddSuffixStaticModule(Component *component, char *suffix); From 82b10f61a47bf6e839271daebeb7f2fd0ba02e04 Mon Sep 17 00:00:00 2001 From: Abaresk Date: Mon, 25 Apr 2022 17:10:30 +0000 Subject: [PATCH 3/5] Update types in digest.c --- tools/compstatic/digest.c | 235 +++++++++++++++++++------------------- 1 file changed, 115 insertions(+), 120 deletions(-) diff --git a/tools/compstatic/digest.c b/tools/compstatic/digest.c index 7ed9d2107..fa0b45e69 100644 --- a/tools/compstatic/digest.c +++ b/tools/compstatic/digest.c @@ -10,28 +10,23 @@ #include "print.h" typedef struct { - uint unk0; - uint unk4; - uint unk8; - uint unkC; - uint unk10; - uint unk14; - uint unk18; - int unk1C; - char unk20[0x40]; - uint unk60; - uint unk64; - char unk68[0xC]; -} HashWork; + uint intermediateHash[5]; + uint lengthLow; + uint lengthHigh; + int messageBlockIdx; + byte messageBlock[64]; + bool computed; + uint corrupted; +} DGTHash2Context; -typedef bool (*Hash2ResetCb)(HashWork *hashWork); -typedef uint (*Hash2SetSourceCb)(HashWork *hashWork, char *digestKey, int digestKeySize); -typedef uint (*Hash2GetDigestCb)(HashWork *hashWork, char *digestBuffer); +typedef bool (*Hash2ResetCb)(DGTHash2Context *hashCtx); +typedef uint (*Hash2SetSourceCb)(DGTHash2Context *hashCtx, char *digestKey, int digestKeySize); +typedef uint (*Hash2GetDigestCb)(DGTHash2Context *hashCtx, char *digestBuffer); typedef struct { int unk0; int blockSize; - HashWork *hashWork; + DGTHash2Context *hashCtx; char *unkC; Hash2ResetCb hash2Reset; Hash2SetSourceCb hash2SetSource; @@ -40,11 +35,11 @@ typedef struct { static void DGT_Hash2CalcHmac(char *hash, char *content, int size, char *digestKey, int digestKeySize); static bool DGT_SetOverlayTableMode(bool mode); -static bool DGT_Hash2Reset(HashWork *hashWork); -static uint DGT_Hash2SetSource(HashWork *hashWork, char *digestKey, int digestKeySize); -static uint DGT_Hash2GetDigest(HashWork *hashWork, char *digestBuffer); -static void DGT_Hash2SetPadding(HashWork *hashWork); -static void DGT_Hash2DoProcess(HashWork *hashWork); +static bool DGT_Hash2Reset(DGTHash2Context *hashCtx); +static uint DGT_Hash2SetSource(DGTHash2Context *hashCtx, char *digestKey, int digestKeySize); +static uint DGT_Hash2GetDigest(DGTHash2Context *hashCtx, char *digestBuffer); +static void DGT_Hash2SetPadding(DGTHash2Context *hashCtx); +static void DGT_Hash2DoProcess(DGTHash2Context *hashCtx); static void HmacCalc(char *hash, char *content, int size, char *digestKey, int digestKeySize, HmacParam *param); // Set default DigestFunc @@ -121,13 +116,13 @@ void Calc_Digest(char *content, int size, char *hash, bool overlayTableMode) { } static void DGT_Hash2CalcHmac(char *hash, char *content, int size, char *digestKey, int digestKeySize) { - HashWork hashWork; + DGTHash2Context hashCtx; char unkBuffer1[0x20]; HmacParam param = {0}; param.unk0 = 20; param.blockSize = DIGEST_KEY_SIZE; - param.hashWork = &hashWork; + param.hashCtx = &hashCtx; param.unkC = unkBuffer1; param.hash2Reset = DGT_Hash2Reset; param.hash2SetSource = DGT_Hash2SetSource; @@ -141,139 +136,139 @@ static bool DGT_SetOverlayTableMode(bool mode) { return oldMode; } -static bool DGT_Hash2Reset(HashWork *hashWork) { - if (hashWork != NULL) { - hashWork->unk14 = 0; - hashWork->unk18 = 0; - hashWork->unk1C = 0; - hashWork->unk0 = 0x67452301; - hashWork->unk4 = 0xefcdab89; - hashWork->unk8 = 0x98badcfe; - hashWork->unkC = 0x10325476; - hashWork->unk10 = 0xc3d2e1f0; - hashWork->unk60 = 0; - hashWork->unk64 = 0; +static bool DGT_Hash2Reset(DGTHash2Context *hashCtx) { + if (hashCtx != NULL) { + hashCtx->intermediateHash[0] = 0x67452301; + hashCtx->intermediateHash[1] = 0xefcdab89; + hashCtx->intermediateHash[2] = 0x98badcfe; + hashCtx->intermediateHash[3] = 0x10325476; + hashCtx->intermediateHash[4] = 0xc3d2e1f0; + hashCtx->lengthLow = 0; + hashCtx->lengthHigh = 0; + hashCtx->messageBlockIdx = 0; + hashCtx->computed = false; + hashCtx->corrupted = 0; } - return hashWork == NULL; + return hashCtx == NULL; } -static uint DGT_Hash2SetSource(HashWork *hashWork, char *digestKey, int digestKeySize) { +static uint DGT_Hash2SetSource(DGTHash2Context *hashCtx, char *digestKey, int digestKeySize) { uint ret; if (digestKeySize == 0) { ret = 0; - } else if (hashWork == NULL || digestKey == NULL) { + } else if (hashCtx == NULL || digestKey == NULL) { ret = 1; - } else if (hashWork->unk60 = 0) { - if (hashWork->unk64 == 0) { - while (digestKeySize -= 1, digestKeySize != -1 && hashWork->unk64 == 0) { - hashWork->unk20[hashWork->unk1C] = *digestKey; - hashWork->unk1C += 1; - hashWork->unk14 += 8; - if (hashWork->unk1C == 0 && (hashWork->unk18 += 1, hashWork->unk18 == 0)) { - hashWork->unk64 = 1; + } else if (!hashCtx->computed) { + if (hashCtx->corrupted == 0) { + while (digestKeySize -= 1, digestKeySize != -1 && hashCtx->corrupted == 0) { + hashCtx->messageBlock[hashCtx->messageBlockIdx] = *digestKey; + hashCtx->messageBlockIdx += 1; + hashCtx->lengthLow += 8; + if (hashCtx->messageBlockIdx == 0 && (hashCtx->lengthHigh += 1, hashCtx->lengthHigh == 0)) { + hashCtx->corrupted = 1; } - if (hashWork->unk1C == 0x40) { - DGT_Hash2DoProcess(hashWork); + if (hashCtx->messageBlockIdx == 0x40) { + DGT_Hash2DoProcess(hashCtx); } digestKey++; } ret = 0; } else { - ret = hashWork->unk64; + ret = hashCtx->corrupted; } } else { - hashWork->unk64 = 3; + hashCtx->corrupted = 3; ret = 3; } return ret; } -static uint DGT_Hash2GetDigest(HashWork *hashWork, char *digestBuffer) { +static uint DGT_Hash2GetDigest(DGTHash2Context *hashCtx, char *digestBuffer) { uint ret; - if (hashWork == NULL || digestBuffer == NULL) { + if (hashCtx == NULL || digestBuffer == NULL) { ret = 1; - } else if (hashWork->unk64 == 0) { - if (hashWork->unk60 == 0) { - DGT_Hash2SetPadding(hashWork); + } else if (hashCtx->corrupted == 0) { + if (!hashCtx->computed) { + DGT_Hash2SetPadding(hashCtx); for (int i = 0; i < 0x40; i++) { - hashWork->unk20[i] = '\0'; + hashCtx->messageBlock[i] = '\0'; } - hashWork->unk14 = 0; - hashWork->unk18 = 0; - hashWork->unk60 = 1; + hashCtx->lengthLow = 0; + hashCtx->lengthHigh = 0; + hashCtx->computed = true; } for (int i = 0; i < 20; i++) { - digestBuffer[i] = (char)(*(uint *)(hashWork->unk20 + (i >> 2) * 4 + -0x20) >> ((3u - ((byte)i % 4)) * 8u & 0x1f)); + digestBuffer[i] = (char)(*(uint *)(hashCtx->messageBlock + (i >> 2) * 4 + -0x20) >> ((3u - ((byte)i % 4)) * 8u & 0x1f)); } ret = 0; } else { - ret = hashWork->unk64; + ret = hashCtx->corrupted; } return ret; } -static void DGT_Hash2SetPadding(HashWork *hashWork) { - if (hashWork->unk1C < 0x38) { - hashWork->unk20[hashWork->unk1C] = -0x80; - hashWork->unk1C += 1; - while (hashWork->unk1C < 0x38) { - hashWork->unk20[hashWork->unk1C] = '\0'; - hashWork->unk1C += 1; +static void DGT_Hash2SetPadding(DGTHash2Context *hashCtx) { + if (hashCtx->messageBlockIdx < 0x38) { + hashCtx->messageBlock[hashCtx->messageBlockIdx] = -0x80; + hashCtx->messageBlockIdx += 1; + while (hashCtx->messageBlockIdx < 0x38) { + hashCtx->messageBlock[hashCtx->messageBlockIdx] = '\0'; + hashCtx->messageBlockIdx += 1; } } else { - hashWork->unk20[hashWork->unk1C] = -0x80; - hashWork->unk1C += 1; - while (hashWork->unk1C < 0x40) { - hashWork->unk20[hashWork->unk1C] = '\0'; - hashWork->unk1C += 1; + hashCtx->messageBlock[hashCtx->messageBlockIdx] = -0x80; + hashCtx->messageBlockIdx += 1; + while (hashCtx->messageBlockIdx < 0x40) { + hashCtx->messageBlock[hashCtx->messageBlockIdx] = '\0'; + hashCtx->messageBlockIdx += 1; } - DGT_Hash2DoProcess(hashWork); - while (hashWork->unk1C < 0x38) { - hashWork->unk20[hashWork->unk1C] = '\0'; - hashWork->unk1C += 1; + DGT_Hash2DoProcess(hashCtx); + while (hashCtx->messageBlockIdx < 0x38) { + hashCtx->messageBlock[hashCtx->messageBlockIdx] = '\0'; + hashCtx->messageBlockIdx += 1; } } - hashWork->unk20[0x38] = (char)(hashWork->unk18 >> 0x18); - hashWork->unk20[0x39] = (char)(hashWork->unk18 >> 0x10); - hashWork->unk20[0x3a] = (char)(hashWork->unk18 >> 8); - hashWork->unk20[0x3b] = *(char *)(&hashWork->unk18); - hashWork->unk20[0x3c] = (char)(hashWork->unk14 >> 0x18); - hashWork->unk20[0x3d] = (char)(hashWork->unk14 >> 0x10); - hashWork->unk20[0x3e] = (char)(hashWork->unk14 >> 8); - hashWork->unk20[0x3f] = *(char *)(&hashWork->unk14); - DGT_Hash2DoProcess(hashWork); + hashCtx->messageBlock[0x38] = hashCtx->lengthHigh >> 0x18; + hashCtx->messageBlock[0x39] = (byte)(hashCtx->lengthHigh >> 0x10); + hashCtx->messageBlock[0x3a] = (byte)(hashCtx->lengthHigh >> 8); + hashCtx->messageBlock[0x3b] = (byte)(hashCtx->lengthHigh); + hashCtx->messageBlock[0x3c] = hashCtx->lengthLow >> 0x18; + hashCtx->messageBlock[0x3d] = (byte)(hashCtx->lengthLow >> 0x10); + hashCtx->messageBlock[0x3e] = (byte)(hashCtx->lengthLow >> 8); + hashCtx->messageBlock[0x3f] = (byte)(hashCtx->lengthLow); + DGT_Hash2DoProcess(hashCtx); } // SHA hash -static void DGT_Hash2DoProcess(HashWork *hashWork) { +static void DGT_Hash2DoProcess(DGTHash2Context *hashCtx) { uint temp; int temp2; uint buffer[99]; int i, idx; if (gOverlayTableMode) { - buffer[10] = *(uint *)(hashWork->unk20 + 0x18); - buffer[9] = *(uint *)(hashWork->unk20 + 0x38); - *(uint *)(hashWork->unk20 + 0x18) = 0; - *(uint *)(hashWork->unk20 + 0x38) = 0; + buffer[10] = *(uint *)(hashCtx->messageBlock + 0x18); + buffer[9] = *(uint *)(hashCtx->messageBlock + 0x38); + *(uint *)(hashCtx->messageBlock + 0x18) = 0; + *(uint *)(hashCtx->messageBlock + 0x38) = 0; } for (i = 0; i < 0x10; i++) { - buffer[i + 0x10] = (uint)(byte)hashWork->unk20[i * 4] << 0x18; - buffer[i + 0x10] = (uint)(byte)hashWork->unk20[i * 4 + 1] << 0x10 | buffer[i + 0x10]; - buffer[i + 0x10] = (uint)(byte)hashWork->unk20[i * 4 + 2] << 8 | buffer[i + 0x10]; - buffer[i + 0x10] = (uint)(byte)hashWork->unk20[i * 4 + 3] | buffer[i + 0x10]; + buffer[i + 0x10] = (uint)(byte)hashCtx->messageBlock[i * 4] << 0x18; + buffer[i + 0x10] = (uint)(byte)hashCtx->messageBlock[i * 4 + 1] << 0x10 | buffer[i + 0x10]; + buffer[i + 0x10] = (uint)(byte)hashCtx->messageBlock[i * 4 + 2] << 8 | buffer[i + 0x10]; + buffer[i + 0x10] = (uint)(byte)hashCtx->messageBlock[i * 4 + 3] | buffer[i + 0x10]; } for (i = 0x10; i < 0x50; i++) { temp = buffer[i + 0xd] ^ buffer[i + 8] ^ buffer[i + 2] ^ buffer[i]; buffer[i + 0x10] = temp << 1 | (uint)((int)temp < 0); } - buffer[14] = hashWork->unk4; - buffer[13] = hashWork->unk8; - buffer[12] = hashWork->unkC; - buffer[11] = hashWork->unk10; - buffer[15] = hashWork->unk0; + buffer[14] = hashCtx->intermediateHash[1]; + buffer[13] = hashCtx->intermediateHash[2]; + buffer[12] = hashCtx->intermediateHash[3]; + buffer[11] = hashCtx->intermediateHash[4]; + buffer[15] = hashCtx->intermediateHash[0]; for (i = 0; i < 0x14; i++) { temp2 = (~buffer[14] & buffer[12] | buffer[14] & buffer[13]) + (buffer[15] << 5 | buffer[15] >> 0x1b) + buffer[11]; @@ -314,15 +309,15 @@ static void DGT_Hash2DoProcess(HashWork *hashWork) { buffer[14] = buffer[15]; buffer[15] = buffer[idx] + temp2 + 0xca62c1d6; } - hashWork->unk0 = buffer[15] + hashWork->unk0; - hashWork->unk4 = buffer[14] + hashWork->unk4; - hashWork->unk8 = buffer[13] + hashWork->unk8; - hashWork->unkC = buffer[12] + hashWork->unkC; - hashWork->unk10 = buffer[11] + hashWork->unk10; - hashWork->unk1C = 0; + hashCtx->intermediateHash[0] += buffer[15]; + hashCtx->intermediateHash[1] += buffer[14]; + hashCtx->intermediateHash[2] += buffer[13]; + hashCtx->intermediateHash[3] += buffer[12]; + hashCtx->intermediateHash[4] += buffer[11]; + hashCtx->messageBlockIdx = 0; if (gOverlayTableMode) { - *(uint *)(hashWork->unk20 + 0x18) = buffer[10]; - *(uint *)(hashWork->unk20 + 0x38) = buffer[9]; + *(uint *)(hashCtx->messageBlock + 0x18) = buffer[10]; + *(uint *)(hashCtx->messageBlock + 0x38) = buffer[9]; } } @@ -337,9 +332,9 @@ static void HmacCalc(char *hash, char *content, int size, char *digestKey, int d if (hash != NULL && content != NULL && size != 0 && digestKey != NULL && digestKeySize != 0 && param != NULL) { if (param->blockSize < digestKeySize) { - param->hash2Reset(param->hashWork); - param->hash2SetSource(param->hashWork, digestKey, digestKeySize); - param->hash2GetDigest(param->hashWork, digestBuffer); + param->hash2Reset(param->hashCtx); + param->hash2SetSource(param->hashCtx, digestKey, digestKeySize); + param->hash2GetDigest(param->hashCtx, digestBuffer); key = digestBuffer; keySize = param->unk0; } else { @@ -352,10 +347,10 @@ static void HmacCalc(char *hash, char *content, int size, char *digestKey, int d for (; i < param->blockSize; i++) { innerKey[i] = 0x36; } - param->hash2Reset(param->hashWork); - param->hash2SetSource(param->hashWork, innerKey, param->blockSize); - param->hash2SetSource(param->hashWork, content, size); - param->hash2GetDigest(param->hashWork, param->unkC); + param->hash2Reset(param->hashCtx); + param->hash2SetSource(param->hashCtx, innerKey, param->blockSize); + param->hash2SetSource(param->hashCtx, content, size); + param->hash2GetDigest(param->hashCtx, param->unkC); for (i = 0; i < keySize; i++) { outerKey[i] = key[i] ^ 0x5c; @@ -363,9 +358,9 @@ static void HmacCalc(char *hash, char *content, int size, char *digestKey, int d for (; i < param->blockSize; i++) { outerKey[i] = 0x5c; } - param->hash2Reset(param->hashWork); - param->hash2SetSource(param->hashWork, outerKey, param->blockSize); - param->hash2SetSource(param->hashWork, param->unkC, param->unk0); - param->hash2GetDigest(param->hashWork, hash); + param->hash2Reset(param->hashCtx); + param->hash2SetSource(param->hashCtx, outerKey, param->blockSize); + param->hash2SetSource(param->hashCtx, param->unkC, param->unk0); + param->hash2GetDigest(param->hashCtx, hash); } } From 8865cf95b02292e922a04b20a4ccccb859dfd75c Mon Sep 17 00:00:00 2001 From: Abaresk Date: Mon, 25 Apr 2022 18:07:40 +0000 Subject: [PATCH 4/5] Fix warnings for clang --- tools/compstatic/Makefile | 6 +++--- tools/compstatic/component.c | 2 +- tools/compstatic/compress.c | 2 +- tools/compstatic/digest.c | 8 ++++---- tools/compstatic/overlay_modules.c | 2 +- tools/compstatic/print.c | 6 +++--- tools/compstatic/print.h | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/compstatic/Makefile b/tools/compstatic/Makefile index 5fefbbec2..d1981d43b 100644 --- a/tools/compstatic/Makefile +++ b/tools/compstatic/Makefile @@ -2,15 +2,15 @@ CC := gcc CFLAGS := -O3 SRCS = $(wildcard *.c) -INCLUDES = $(wildcard *.h) +OBJS = $(SRCS:%.c=%.o) .PHONY: all clean all: compstatic @: -compstatic: $(SRCS) $(INCLUDES) +compstatic: $(OBJS) $(CC) $(CFLAGS) -o $@ $^ clean: - $(RM) compstatic compstatic.exe + $(RM) compstatic compstatic.exe $(OBJS) diff --git a/tools/compstatic/component.c b/tools/compstatic/component.c index 7486dc75c..0df9d3a57 100644 --- a/tools/compstatic/component.c +++ b/tools/compstatic/component.c @@ -75,7 +75,7 @@ static bool WriteComponent(Component *component) { } static bool ComponentAddSuffix(Component *component, char *suffix) { - if (suffix == NULL || suffix == "") return true; + if (suffix == NULL || *suffix == '\0') return true; bool finalSuccess = false; bool success = AddSuffixOverlayDefs(component, suffix); diff --git a/tools/compstatic/compress.c b/tools/compstatic/compress.c index 7b57df2ce..528d0ad31 100644 --- a/tools/compstatic/compress.c +++ b/tools/compstatic/compress.c @@ -125,7 +125,7 @@ bool CalculateHMAC_OverlayModules(Component *component, int digestType, char *di char *content = component->staticModule.fileInfo.content; char *digestParams = (char *)(content + digestParamsOffset); for (int i = 0; i < numOverlays; i++) { - if (overlayTable[OT_COMPRESSED_FLAGS_OFFSET] & 2U != 0) { + if ((overlayTable[OT_COMPRESSED_FLAGS_OFFSET] & 2U) != 0) { printf("OverlayModule[%02d]: HMAC already calculated - do it again.\n", i); } if ((uint)overlayModule->fileInfo.fileSize < *(uint *)(overlayTable + OT_FILESIZE_OFFSET)) { diff --git a/tools/compstatic/digest.c b/tools/compstatic/digest.c index fa0b45e69..132b18b27 100644 --- a/tools/compstatic/digest.c +++ b/tools/compstatic/digest.c @@ -100,7 +100,7 @@ void Calc_Digest(char *content, int size, char *hash, bool overlayTableMode) { byte hashBuffer[40]; bool oldMode = DGT_SetOverlayTableMode(overlayTableMode); - gDigestFunc(hashBuffer, content, size, gDigestKey, gDigestKeySize); + gDigestFunc((char *)hashBuffer, content, size, gDigestKey, gDigestKeySize); DGT_SetOverlayTableMode(oldMode); int iCpy = 0; for (int i = 0; i < 20; i++) { @@ -112,7 +112,7 @@ void Calc_Digest(char *content, int size, char *hash, bool overlayTableMode) { printf("%02X", hashBuffer[i]); } printf(" %8ld\n", (long int)size); - CopyBuffer(hashBuffer, hash, 20); + CopyBuffer((char *)hashBuffer, hash, 20); } static void DGT_Hash2CalcHmac(char *hash, char *content, int size, char *digestKey, int digestKeySize) { @@ -322,8 +322,8 @@ static void DGT_Hash2DoProcess(DGTHash2Context *hashCtx) { } static void HmacCalc(char *hash, char *content, int size, char *digestKey, int digestKeySize, HmacParam *param) { - byte digestBuffer[0x4C]; - byte *key; + char digestBuffer[0x4C]; + char *key; int keySize; char innerKey[0x48]; char outerKey[0x40]; diff --git a/tools/compstatic/overlay_modules.c b/tools/compstatic/overlay_modules.c index f000b0c30..440df669c 100644 --- a/tools/compstatic/overlay_modules.c +++ b/tools/compstatic/overlay_modules.c @@ -144,6 +144,6 @@ void FreeOverlayModules(Component *component) { } if (component->overlayModules != NULL) { free(component->overlayModules); - component->overlayModules == NULL; + component->overlayModules = NULL; } } diff --git a/tools/compstatic/print.c b/tools/compstatic/print.c index 155bc7bde..d0750529b 100644 --- a/tools/compstatic/print.c +++ b/tools/compstatic/print.c @@ -3,8 +3,8 @@ #include "global.h" #include "print.h" -int DebugPrintf(const char *format, ...) { - if (!gDebugMode) return 0; +void DebugPrintf(const char *format, ...) { + if (!gDebugMode) return; va_list args; va_start(args, format); @@ -12,7 +12,7 @@ int DebugPrintf(const char *format, ...) { va_end(args); } -int ErrorPrintf(const char *format, ...) { +void ErrorPrintf(const char *format, ...) { printf("Error: "); va_list args; diff --git a/tools/compstatic/print.h b/tools/compstatic/print.h index a17b67a4c..afc6a409b 100644 --- a/tools/compstatic/print.h +++ b/tools/compstatic/print.h @@ -1,7 +1,7 @@ #ifndef PRINT_H #define PRINT_H -int DebugPrintf(const char *format, ...); -int ErrorPrintf(const char *format, ...); +void DebugPrintf(const char *format, ...); +void ErrorPrintf(const char *format, ...); #endif // PRINT_H From 9984cd8cfd072390800f2a15262fc44763251359 Mon Sep 17 00:00:00 2001 From: Abaresk Date: Mon, 25 Apr 2022 23:45:25 +0000 Subject: [PATCH 5/5] Rebuild when headers change --- tools/compstatic/Makefile | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tools/compstatic/Makefile b/tools/compstatic/Makefile index d1981d43b..4352c0cbe 100644 --- a/tools/compstatic/Makefile +++ b/tools/compstatic/Makefile @@ -4,13 +4,29 @@ CFLAGS := -O3 SRCS = $(wildcard *.c) OBJS = $(SRCS:%.c=%.o) +prog := compstatic + .PHONY: all clean -all: compstatic +DEPDIR := .deps +DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d + +all: $(prog) @: -compstatic: $(OBJS) - $(CC) $(CFLAGS) -o $@ $^ - clean: - $(RM) compstatic compstatic.exe $(OBJS) + $(RM) -r $(DEPDIR) $(OBJS) $(prog) $(prog).exe + +$(prog): $(OBJS) + $(CC) $(LDFLAGS) -o $@ $^ + +$(OBJS): %.o: %.c +$(OBJS): %.o: %.c $(DEPDIR)/%.d | $(DEPDIR) + $(CC) $(CFLAGS) $(DEPFLAGS) -c -o $@ $< + +$(DEPDIR): ; @mkdir -p $@ + +DEPFILES := $(SRCS:%.c=$(DEPDIR)/%.d) +$(DEPFILES): + +include $(wildcard $(DEPFILES))