From e20e27fdc30bf020d7e908a39a8393a1a202b3b3 Mon Sep 17 00:00:00 2001 From: Regan Green Date: Thu, 5 Oct 2023 05:22:32 -0400 Subject: [PATCH] Further patch work --- LEGO1/decomp.cpp | 102 +++++++++++++++++++++++++++++++++- LEGO1/decomp.h | 23 +++++--- LEGO1/mxtransitionmanager.cpp | 6 +- 3 files changed, 117 insertions(+), 14 deletions(-) diff --git a/LEGO1/decomp.cpp b/LEGO1/decomp.cpp index dee2a0a2..f8387f24 100644 --- a/LEGO1/decomp.cpp +++ b/LEGO1/decomp.cpp @@ -2,8 +2,106 @@ #include "Windows.h" -// Export "Patch" function (non-mangled name) +#include + +#ifdef ISLE_BUILD_PATCH + +// Managed list class for patches +static class DecompPatchList +{ +private: + struct DecompPatchNode + { + DecompPatchNode *next; + void *origFunc, *newFunc; + } *m_head; + +public: + DecompPatchList() + { + // I'm having CRT initialization order issues + // with MSVC 4.20, so I'm going to leave m_head + // uninitialized. It's static so it should be + // zeroed anyways. + // m_head = NULL; + } + + ~DecompPatchList() + { + // Delete all nodes + for (DecompPatchNode *node = m_head; node != NULL;) + { + DecompPatchNode *next = node->next; + delete node; + node = next; + } + } + + void Add(void *origFunc, void *newFunc) + { + // Create new node + DecompPatchNode *node = new DecompPatchNode; + node->origFunc = origFunc; + node->newFunc = newFunc; + node->next = m_head; + + // Add to head of list + m_head = node; + } + + void Patch(void *root) + { + // Go through all nodes + for (DecompPatchNode *node = m_head; node != NULL; node = node->next) + { + // Inject JMP instruction + BYTE *location = (BYTE*)((DWORD)root + (DWORD)node->origFunc); + BYTE *newFunction = (BYTE*)node->newFunc; + + /* + DWORD dwOldProtection; + VirtualProtect(location, 5, PAGE_EXECUTE_READWRITE, &dwOldProtection); + location[0] = 0xE9; //jmp + *((DWORD*)(location + 1)) = (DWORD)(((DWORD)newFunction - (DWORD)location) - 5); + VirtualProtect(location, 5, dwOldProtection, &dwOldProtection); + */ + + BYTE code[5]; + code[0] = 0xE9; //jmp + *((DWORD*)(code + 1)) = (DWORD)(((DWORD)newFunction - (DWORD)location) - 5); + + char buffer[256]; + sprintf(buffer, "location %p, newFunction %p, origFunc %p, root %p", location, newFunction, node->origFunc, root); + MessageBoxA(NULL, buffer, "DecompPatchList", MB_ICONERROR); + + static HANDLE hProcess = GetCurrentProcess(); + DWORD written = 0; + if (WriteProcessMemory(hProcess, location, code, sizeof(code), &written) == FALSE || written != sizeof(code)) + { + // Print error reason + sprintf(buffer, "WriteProcessMemory failed: %d", GetLastError()); + MessageBoxA(NULL, buffer, "DecompPatchList", MB_ICONERROR); + + MessageBoxA(NULL, "Patch failed", "DecompPatchList", MB_ICONERROR); + } + } + } +} decompPatchList; + +// Function called to add a patch to the list of patches +void DecompPatchAdd(void *origFunc, void *newFunc) +{ + // Add to list + decompPatchList.Add(origFunc, newFunc); +} + +// Exported "Patch" function +// This goes through all our added patches and applies them +// Root is the root address of LEGO1.DLL extern "C" __declspec(dllexport) void Patch(void *root) { - MessageBoxA(NULL, "HELLO", "HELLO", 0); + // Apply all patches + decompPatchList.Patch(root); } + +#endif diff --git a/LEGO1/decomp.h b/LEGO1/decomp.h index f47a2343..23a849e1 100644 --- a/LEGO1/decomp.h +++ b/LEGO1/decomp.h @@ -14,18 +14,25 @@ typedef unsigned int undefined4; #ifdef ISLE_BUILD_PATCH -class PatchHook -{ -public: - PatchHook(void *p_ourFunc, void *p_origFunc); -}; +void DecompPatchAdd(void *origFunc, void *newFunc); -#define PATCH_HOOK(ourFunc, origFunc) \ - static PatchHook _patchHook_##__COUNTER__ ((void *)ourFunc, (void *)origFunc) +#define DECOMP_METHOD_HOOK(origFunc, cls, method, retv, args) \ +namespace _DecompPatchHook_##__COUNTER__ \ +{ \ + class DecompPatchHook \ + { \ + public: \ + DecompPatchHook() \ + { \ + retv(cls :: *method) args = cls::method; \ + DecompPatchAdd((void*)origFunc, (void*)&_patchHook); \ + } \ + } _patchHook; \ +} #else -#define PATCH_HOOK(ourFunc, origFunc) +#define DECOMP_METHOD_HOOK() #endif diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index c985aaec..ce3cd215 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -153,6 +153,7 @@ MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim) { + Beep(750, 300); if (this->m_transitionType == NOT_TRANSITIONING) { if (!p_playMusicInAnim) { MxBackgroundAudioManager *backgroundAudioManager = BackgroundAudioManager(); @@ -192,10 +193,7 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx return FAILURE; } -void Test() -{ - MxResult (MxTransitionManager:: * pfTarget)(MxTransitionManager::TransitionType, MxS32, MxBool, MxBool) = MxTransitionManager::StartTransition; -} +DECOMP_METHOD_HOOK(0x1004bb70, MxTransitionManager, StartTransition, MxResult, (MxTransitionManager::TransitionType, MxS32, MxBool, MxBool)); // OFFSET: LEGO1 0x1004c170 void MxTransitionManager::Transition_Wipe()