From df52bb5ca1399988284848991ef46c1d00d0030c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Thu, 1 Oct 2015 18:48:48 +0200 Subject: [PATCH 1/2] Add hooks for Linux --- src/hook.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/hook.c b/src/hook.c index 0471ad3037..be83f39dc3 100644 --- a/src/hook.c +++ b/src/hook.c @@ -8,18 +8,20 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - + * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - + * You should have received a copy of the GNU General Public License * along with this program. If not, see . *****************************************************************************/ #ifdef _WIN32 -#include + #include +#else + #include #endif // _WIN32 #include "hook.h" #include "platform/platform.h" @@ -28,7 +30,6 @@ void* g_hooktableaddress = 0; int g_hooktableoffset = 0; int g_maxhooks = 1000; -#ifdef _WIN32 void hookfunc(int address, int newaddress, int stacksize, int registerargs[], int registersreturned, int eaxDestinationRegister) { int i = 0; @@ -96,7 +97,7 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in data[i++] = 0x00; data[i++] = 0x00; data[i++] = 0x00; - + int sizec = i; data[i++] = 0x8B; // push eax, [esp] - puts eip in eax @@ -140,7 +141,7 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in if (!(registersreturned & EDI)) { data[i++] = 0x57; // push edi } - + data[i++] = 0x83; // sub esp, x data[i++] = 0xEC; data[i++] = 4 + (stacksize * 4) + rargssize; @@ -210,18 +211,31 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in if (!(registersreturned & EAX)) { data[i++] = 0x58; // pop eax } - + data[i++] = 0xC3; // retn +#ifdef _WIN32 WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, data, i, 0); -} +#else + // We own the pages with PROT_WRITE | PROT_EXEC, we can simply just memcpy the data + memcpy((void *)address, data, i); #endif // _WIN32 +} void addhook(int address, int newaddress, int stacksize, int registerargs[], int registersreturned, int eaxDestinationRegister) { -#ifdef _WIN32 if (!g_hooktableaddress) { - g_hooktableaddress = VirtualAllocEx(GetCurrentProcess(), NULL, g_maxhooks * 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + size_t size = g_maxhooks * 100; +#ifdef _WIN32 + g_hooktableaddress = VirtualAllocEx(GetCurrentProcess(), NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); +#else + g_hooktableaddress = mmap(NULL, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (g_hooktableaddress == MAP_FAILED) + { + perror("mmap"); + exit(1); + } +#endif // _WIN32 } if (g_hooktableoffset > g_maxhooks) { return; @@ -232,10 +246,12 @@ void addhook(int address, int newaddress, int stacksize, int registerargs[], int data[i++] = 0xE9; // jmp *((int *)&data[i]) = hookaddress - address - i - 4; i += 4; data[i++] = 0xC3; // retn +#ifdef _WIN32 WriteProcessMemory(GetCurrentProcess(), (LPVOID)address, data, i, 0); +#else + // We own the pages with PROT_WRITE | PROT_EXEC, we can simply just memcpy the data + memcpy((void *)address, data, i); +#endif // _WIN32 hookfunc(hookaddress, newaddress, stacksize, registerargs, registersreturned, eaxDestinationRegister); g_hooktableoffset++; -#else - STUB(); -#endif // _WIN32 } From 9a1e88872f91c66540e4f51f3996d9fcbf4b9138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Thu, 1 Oct 2015 18:57:45 +0200 Subject: [PATCH 2/2] sub_6E7FF3 no longer causes problems --- src/interface/viewport.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 5ec11bf5a4..11175a52d6 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -271,11 +271,7 @@ void sub_689174(sint16* x, sint16* y, sint16 *z) void sub_6E7FF3(rct_window *w, rct_viewport *viewport, int x, int y) { -#ifdef _WIN32 RCT2_CALLPROC_X(0x006E7FF3, 0, 0, 0, x, (int)viewport, (int)w, y); -#else - STUB(); -#endif // _WIN32 // int zoom = 1 << viewport->zoom; // if (w >= RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*)){