diff --git a/src/hook.c b/src/hook.c index 1aa5a83..5698f0e 100644 --- a/src/hook.c +++ b/src/hook.c @@ -86,8 +86,30 @@ PROC Hook_HotPatch(PROC function, PROC newFunction) { PROC result = function; + if (!function) + return result; + unsigned short *bytes = (unsigned short *)function; - if (function && *bytes == 0xFF8B) // mov edi, edi + + if (*bytes == 0x25FF) // JMP DWORD PTR + { + char *address = (char *)function; + DWORD oldProtect; + + if (VirtualProtect(address, 8, PAGE_EXECUTE_READWRITE, &oldProtect)) + { + if (memcmp(address + 6, (const char[]) { 0xCC, 0xCC }, 2) == 0 || + memcmp(address + 6, (const char[]) { 0x90, 0x90 }, 2) == 0) + { + memmove(address + 2, address, 6); + *((WORD *)(&address[0])) = 0xFF8B; // mov edi, edi + } + + VirtualProtect(address, 8, oldProtect, &oldProtect); + } + } + + if (*bytes == 0xFF8B) // mov edi, edi { char *address = ((char *)function) - 5; DWORD oldProtect; diff --git a/src/settings.c b/src/settings.c index d2ef3e9..16e99ed 100644 --- a/src/settings.c +++ b/src/settings.c @@ -41,7 +41,7 @@ void Settings_Load() ddraw->noactivateapp = GetBool("noactivateapp", FALSE); ddraw->vhack = GetBool("vhack", FALSE); ddraw->accurateTimers = GetBool("accuratetimers", FALSE); - ddraw->hotPatch = GetBool("hotPatch", FALSE); + ddraw->hotPatch = GetBool("hotpatch", FALSE); WindowRect.right = GetInt("width", 0); WindowRect.bottom = GetInt("height", 0); @@ -277,7 +277,8 @@ static void CreateSettingsIni() "\n" "; Use hotpatching rather than IAT hooking\n" "; Note: Can be used to fix issues related to new features added by cnc-ddraw such as windowed mode or stretching\n" - "hotPatch=false\n" + "hotpatch=false\n" + "\n" "\n" "\n" "; ### Game specific settings ###\n"