diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3e98bafd..91a218f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,11 +60,14 @@ jobs: C:\msys64\usr\bin\wget.exe https://legoisland.org/download/ISLE.EXE C:\msys64\usr\bin\wget.exe https://legoisland.org/download/LEGO1.DLL pip install capstone - python3 tools/reccomp/reccomp.py ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB ISLE - python3 tools/reccomp/reccomp.py LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB LEGO1 + python3 tools/reccmp/reccmp.py -H ISLEPROGRESS.HTML ISLE.EXE Release/ISLE.EXE Release/ISLE.PDB ISLE + python3 tools/reccmp/reccmp.py -H LEGO1PROGRESS.HTML LEGO1.DLL Release/LEGO1.DLL Release/LEGO1.PDB LEGO1 - name: Upload Artifact uses: actions/upload-artifact@master with: name: Win32 - path: Release + path: | + Release + ISLEPROGRESS.HTML + LEGO1PROGRESS.HTML diff --git a/ISLE/isle.cpp b/ISLE/isle.cpp index 5e9e1ec4..a58ad707 100644 --- a/ISLE/isle.cpp +++ b/ISLE/isle.cpp @@ -37,13 +37,7 @@ Isle::Isle() m_frameDelta = 10; m_windowActive = 1; - MxRect32 rect; - rect.m_left = 0; - rect.m_top = 0; - rect.m_right = 639; - rect.m_bottom = 479; - - m_videoParam = MxVideoParam(rect, NULL, 1, MxVideoParamFlags()); + m_videoParam = MxVideoParam(MxRect32(0, 0, 639, 479), NULL, 1, MxVideoParamFlags()); m_videoParam.flags().Enable16Bit(MxDirectDraw::GetPrimaryBitDepth() == 16); m_windowHandle = NULL; @@ -116,7 +110,7 @@ void Isle::Close() } // OFFSET: ISLE 0x402740 -BOOL ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize) +BOOL Isle::ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize) { HKEY hKey; DWORD valueType; @@ -135,7 +129,7 @@ BOOL ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize) } // OFFSET: ISLE 0x4027b0 -int ReadRegBool(LPCSTR name, BOOL *out) +int Isle::ReadRegBool(LPCSTR name, BOOL *out) { char buffer[256]; @@ -143,28 +137,30 @@ int ReadRegBool(LPCSTR name, BOOL *out) if (read) { if (strcmp("YES", buffer) == 0) { *out = TRUE; - return TRUE; + return read; } if (strcmp("NO", buffer) == 0) { *out = FALSE; - return TRUE; + return read; } + + read = FALSE; } - return FALSE; + return read; } // OFFSET: ISLE 0x402880 -int ReadRegInt(LPCSTR name, int *out) +int Isle::ReadRegInt(LPCSTR name, int *out) { char buffer[256]; - if (ReadReg(name, buffer, sizeof(buffer))) { + BOOL read = ReadReg(name, buffer, sizeof(buffer)); + if (read) { *out = atoi(buffer); - return TRUE; } - return FALSE; + return read; } // OFFSET: ISLE 0x4028d0 @@ -256,16 +252,18 @@ void Isle::SetupVideoFlags(BOOL fullScreen, BOOL flipSurfaces, BOOL backBuffers, // OFFSET: ISLE 0x4013b0 BOOL Isle::SetupLegoOmni() { + BOOL result = FALSE; char mediaPath[256]; GetProfileStringA("LEGO Island", "MediaPath", "", mediaPath, sizeof(mediaPath)); - if (Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__ *) m_windowHandle, m_videoParam, MxOmniCreateFlags())) != FAILURE) { + BOOL failure = Lego()->Create(MxOmniCreateParam(mediaPath, (struct HWND__ *) m_windowHandle, m_videoParam, MxOmniCreateFlags())) == FAILURE; + if (!failure) { VariableTable()->SetVariable("ACTOR_01", ""); TickleManager()->vtable1c(VideoManager(), 10); - return TRUE; + result = TRUE; } - return FALSE; + return result; } // OFFSET: ISLE 0x402e80 @@ -283,6 +281,14 @@ void Isle::SetupCursor(WPARAM wParam) break; case 0xB: m_cursorCurrent = NULL; + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 0xA: break; } diff --git a/ISLE/isle.h b/ISLE/isle.h index d4f4e42e..4d6b73c4 100644 --- a/ISLE/isle.h +++ b/ISLE/isle.h @@ -12,7 +12,11 @@ class Isle Isle(); ~Isle(); - static void Close(); + void Close(); + + BOOL ReadReg(LPCSTR name, LPSTR outValue, DWORD outSize); + int ReadRegBool(LPCSTR name, BOOL *out); + int ReadRegInt(LPCSTR name, int *out); MxResult SetupWindow(HINSTANCE hInstance); diff --git a/LEGO1/mxrect32.h b/LEGO1/mxrect32.h index 764117ec..092396f5 100644 --- a/LEGO1/mxrect32.h +++ b/LEGO1/mxrect32.h @@ -4,6 +4,14 @@ class MxRect32 { public: + MxRect32(int p_left, int p_top, int p_right, int p_bottom) + { + this->m_left = p_left; + this->m_top = p_top; + this->m_right = p_right; + this->m_bottom = p_bottom; + } + int m_left; int m_top; int m_right; diff --git a/LEGO1/mxstring.cpp b/LEGO1/mxstring.cpp index 81188291..37d7b7e6 100644 --- a/LEGO1/mxstring.cpp +++ b/LEGO1/mxstring.cpp @@ -11,6 +11,60 @@ MxString::MxString() this->m_length = 0; } +// OFFSET: LEGO1 0x100ae2a0 +MxString::MxString(const MxString &str) +{ + this->m_length = str.m_length; + this->m_data = (char *)malloc(this->m_length + 1); + strcpy(this->m_data, str.m_data); +} + +// OFFSET: LEGO1 0x100ae350 +MxString::MxString(const char *str) +{ + if (str) { + this->m_length = strlen(str); + this->m_data = (char *)malloc(this->m_length + 1); + strcpy(this->m_data, str); + } else { + this->m_data = (char *)malloc(1); + this->m_data[0] = 0; + this->m_length = 0; + } +} + +// OFFSET: LEGO1 0x100ae420 +MxString::~MxString() +{ + free(this->m_data); +} + +// OFFSET: LEGO1 0x100ae490 +void MxString::ToUpperCase() +{ + strupr(this->m_data); +} + +// OFFSET: LEGO1 0x100ae4a0 +void MxString::ToLowerCase() +{ + strlwr(this->m_data); +} + +// OFFSET: LEGO1 0x100ae4b0 +const MxString &MxString::operator=(MxString *param) +{ + if (this->m_data != param->m_data) + { + free(this->m_data); + this->m_length = param->m_length; + this->m_data = (char *)malloc(this->m_length + 1); + strcpy(this->m_data, param->m_data); + } + + return *this; +} + // TODO: this *mostly* matches, again weird with the comparison // OFFSET: LEGO1 0x100ae510 const MxString &MxString::operator=(const char *param) @@ -25,9 +79,3 @@ const MxString &MxString::operator=(const char *param) return *this; } - -// OFFSET: LEGO1 0x100ae420 -MxString::~MxString() -{ - free(this->m_data); -} diff --git a/LEGO1/mxstring.h b/LEGO1/mxstring.h index 9551f1c9..0f9ff9f3 100644 --- a/LEGO1/mxstring.h +++ b/LEGO1/mxstring.h @@ -11,6 +11,10 @@ class MxString : public MxCore __declspec(dllexport) const MxString &operator=(const char *); MxString(); + MxString(const char *); + void ToUpperCase(); + void ToLowerCase(); + const MxString &operator=(MxString *); private: char *m_data; diff --git a/LEGO1/mxtimer.cpp b/LEGO1/mxtimer.cpp index 8be837d4..782ccd70 100644 --- a/LEGO1/mxtimer.cpp +++ b/LEGO1/mxtimer.cpp @@ -10,17 +10,18 @@ long MxTimer::s_LastTimeTimerStarted = 0; // OFFSET: LEGO1 0x100ae060 MxTimer::MxTimer() -{ - this->m_isRunning = MX_FALSE; - MxTimer::s_LastTimeCalculated = timeGetTime(); - this->m_startTime = MxTimer::s_LastTimeCalculated; +{ + this->m_isRunning = MX_FALSE; + m_startTime = timeGetTime(); + // yeah this is somehow what the asm is + s_LastTimeCalculated = m_startTime; } // OFFSET: LEGO1 0x100ae160 void MxTimer::Start() { + s_LastTimeTimerStarted = this->GetRealTime(); this->m_isRunning = MX_TRUE; - MxTimer::s_LastTimeTimerStarted = timeGetTime(); } // OFFSET: LEGO1 0x100ae180 diff --git a/tools/reccomp/cvdump.exe b/tools/reccmp/cvdump.exe similarity index 100% rename from tools/reccomp/cvdump.exe rename to tools/reccmp/cvdump.exe diff --git a/tools/reccomp/reccomp.py b/tools/reccmp/reccmp.py similarity index 86% rename from tools/reccomp/reccomp.py rename to tools/reccmp/reccmp.py index f1f378ae..02189dfe 100755 --- a/tools/reccomp/reccomp.py +++ b/tools/reccmp/reccmp.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import argparse from capstone import * import difflib import struct @@ -7,60 +8,40 @@ import os import sys -def print_usage(): - print('Usage: %s [options] \n' % sys.argv[0]) - print('\t-v, --verbose \t\t\tPrint assembly diff for specific function (original file\'s offset)') - print('\t-h, --html \t\t\tGenerate searchable HTML summary of status and diffs') - sys.exit(1) +parser = argparse.ArgumentParser(allow_abbrev=False, + description='Recompilation Compare: compare an original EXE with a recompiled EXE + PDB.') +parser.add_argument('original', metavar='original-binary', help='The original binary') +parser.add_argument('recompiled', metavar='recompiled-binary', help='The recompiled binary') +parser.add_argument('pdb', metavar='recompiled-pdb', help='The PDB of the recompiled binary') +parser.add_argument('decomp_dir', metavar='decomp-dir', help='The decompiled source tree') +parser.add_argument('--verbose', '-v', metavar='offset', help='Print assembly diff for specific function (original file\'s offset)') +parser.add_argument('--html', '-H', metavar='output-file', help='Generate searchable HTML summary of status and diffs') + +args = parser.parse_args() -positional_args = [] verbose = None -skip = False -html = None +if args.verbose: + try: + verbose = int(args.verbose, 16) + except ValueError: + parser.error('invalid verbose argument') +html = args.html -for i, arg in enumerate(sys.argv): - if skip: - skip = False - continue - - if arg.startswith('-'): - # A flag rather than a positional arg - flag = arg[1:] - - if flag == 'v' or flag == '-verbose': - verbose = int(sys.argv[i + 1], 16) - skip = True - elif flag == 'h' or flag == '-html': - html = sys.argv[i + 1] - skip = True - else: - print('Unknown flag: %s' % arg) - print_usage() - else: - positional_args.append(arg) - -if len(positional_args) != 5: - print_usage() - -original = positional_args[1] +original = args.original if not os.path.isfile(original): - print('Invalid input: Original binary does not exist') - sys.exit(1) + parser.error('Original binary does not exist') -recomp = positional_args[2] +recomp = args.recompiled if not os.path.isfile(recomp): - print('Invalid input: Recompiled binary does not exist') - sys.exit(1) + parser.error('Recompiled binary does not exist') -syms = positional_args[3] +syms = args.pdb if not os.path.isfile(syms): - print('Invalid input: Symbols PDB does not exist') - sys.exit(1) + parser.error('Symbols PDB does not exist') -source = positional_args[4] +source = args.decomp_dir if not os.path.isdir(source): - print('Invalid input: Source directory does not exist') - sys.exit(1) + parser.error('Source directory does not exist') # Declare a class that can automatically convert virtual executable addresses # to file addresses diff --git a/tools/reccomp/template.html b/tools/reccmp/template.html similarity index 87% rename from tools/reccomp/template.html rename to tools/reccmp/template.html index fdc41b20..9b03e4ec 100644 --- a/tools/reccomp/template.html +++ b/tools/reccmp/template.html @@ -67,6 +67,12 @@ #sortind { margin: 0 0.5em; } + + .filters { + font-size: 10pt; + text-align: center; + margin: 0.5em 0 1em 0; + } @@ -230,8 +250,10 @@

Decompilation Status

-
-
+
+ + +
AddressNameMatching