From ce56b2c7f780e0e2bc02f0647c59c14047797268 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Mon, 7 Dec 2015 23:21:44 +0000 Subject: [PATCH] Aligned hook for better OS X support --- src/hook.c | 127 +++++++++++++++++++++---------------------------- src/openrct2.c | 2 +- 2 files changed, 55 insertions(+), 74 deletions(-) diff --git a/src/hook.c b/src/hook.c index be83f39dc3..36a80cf789 100644 --- a/src/hook.c +++ b/src/hook.c @@ -53,73 +53,6 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in int rargssize = numrargs * 4; - data[i++] = 0x50; // push eax - - // move stack down for possible existing arguments - for (int j = 0; j < stacksize; j++) { - data[i++] = 0x8B; // mov eax, [esp+x] - data[i++] = 0x44; - data[i++] = 0xE4; - data[i++] = (signed char)((4 * (stacksize - j)) + 4); - - data[i++] = 0x89; // mov [esp+x], eax - data[i++] = 0x44; - data[i++] = 0xE4; - data[i++] = (signed char)((4 * (stacksize - j)) - ((registerssaved + stacksize) * 4)); - } - - if (numrargs > 0) { - // push the registers to be on the stack to access as arguments - data[i++] = 0x83; // add esp, x - data[i++] = 0xC4; - data[i++] = -((registerssaved + stacksize) * 4) + 4; - - for (signed int j = numrargs - 1; j >= 0; j--) { - switch (registerargs[j]) { - case EAX: data[i++] = 0x50; break; - case EBX: data[i++] = 0x53; break; - case ECX: data[i++] = 0x51; break; - case EDX: data[i++] = 0x52; break; - case ESI: data[i++] = 0x56; break; - case EDI: data[i++] = 0x57; break; - case EBP: data[i++] = 0x55; break; - } - } - - data[i++] = 0x83; // add esp, x - data[i++] = 0xC4; - data[i++] = rargssize + ((registerssaved + stacksize) * 4) - 4; - } - - - data[i++] = 0xE8; // call - data[i++] = 0x00; - data[i++] = 0x00; - data[i++] = 0x00; - data[i++] = 0x00; - - int sizec = i; - - data[i++] = 0x8B; // push eax, [esp] - puts eip in eax - data[i++] = 0x04; - data[i++] = 0xE4; - - data[i++] = 0x83; // add eax, x - data[i++] = 0xC0; - int sizeoffset = i; - data[i++] = 0; // set to returnlocation offset later - - data[i++] = 0x89; // mov [esp-20h], eax - put return address on stack - data[i++] = 0x44; - data[i++] = 0xE4; - data[i++] = (signed char)(-(registerssaved * 4) - rargssize - (stacksize * 4)) + 4; - - data[i++] = 0x83; // add esp, x - data[i++] = 0xC4; - data[i++] = 4; - - data[i++] = 0x58; // pop eax - if (!(registersreturned & EAX)) { data[i++] = 0x50; // push eax } @@ -142,15 +75,56 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in data[i++] = 0x57; // push edi } - data[i++] = 0x83; // sub esp, x - data[i++] = 0xEC; - data[i++] = 4 + (stacksize * 4) + rargssize; + data[i++] = 0x50; //push eax + data[i++] = 0x89; //mov eax, esp + data[i++] = 0xE0; + data[i++] = 0x83; //sub eax, (numargs + 1)*4 + data[i++] = 0xC0; + data[i++] = (numrargs) * 4; + data[i++] = 0x83; //and eax, 0xC + data[i++] = 0xE0; + data[i++] = 0x0C; + data[i++] = 0x83; //sub eax, 0x18 + data[i++] = 0xE8; + data[i++] = 0x18; + data[i++] = 0xF7; //neg eax + data[i++] = 0xD8; + data[i++] = 0xA3; //mov [0x9ABDA8], eax + data[i++] = 0xA8; + data[i++] = 0xBD; + data[i++] = 0x9A; + data[i++] = 0x00; + data[i++] = 0x58; //pop eax + data[i++] = 0x2B; //sub esp, [0x9ABDA8] + data[i++] = 0x25; + data[i++] = 0xA8; + data[i++] = 0xBD; + data[i++] = 0x9A; + data[i++] = 0x00; - data[i++] = 0xE9; // jmp + // work out distance to nearest 0xC + // (esp - numargs * 4) & 0xC + // move to align - 4 + // save that amount + + if (numrargs > 0) { + // push the registers to be on the stack to access as arguments + for (signed int j = numrargs - 1; j >= 0; j--) { + switch (registerargs[j]) { + case EAX: data[i++] = 0x50; break; + case EBX: data[i++] = 0x53; break; + case ECX: data[i++] = 0x51; break; + case EDX: data[i++] = 0x52; break; + case ESI: data[i++] = 0x56; break; + case EDI: data[i++] = 0x57; break; + case EBP: data[i++] = 0x55; break; + } + } + } + + data[i++] = 0xE8; // call *((int *)&data[i]) = (newaddress - address - i - 4); i += 4; - data[sizeoffset] = i - sizec; - // returnlocation: switch (eaxDestinationRegister) { @@ -190,6 +164,13 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in data[i++] = 0xEC; data[i++] = (signed char)(stacksize * -4) - rargssize; + data[i++] = 0x03; //add esp, [0x9ABDA8] + data[i++] = 0x25; + data[i++] = 0xA8; + data[i++] = 0xBD; + data[i++] = 0x9A; + data[i++] = 0x00; + if (!(registersreturned & EDI)) { data[i++] = 0x5F; // pop edi } diff --git a/src/openrct2.c b/src/openrct2.c index 6bb2fcd81b..0821ce5788 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -647,7 +647,7 @@ static void openrct2_setup_rct2_hooks() addhook(0x006E7499, (int)gfx_redraw_screen_rect, 0, (int[]){ EAX, EBX, EDX, EBP, END }, 0, 0); // remove when 0x6E7FF3 is decompiled addhook(0x006B752C, (int)ride_crash, 0, (int[]){ EDX, EBX, END }, 0, 0); // remove when all callers are decompiled addhook(0x0069A42F, (int)peep_window_state_update, 0, (int[]){ ESI, END }, 0, 0); // remove when all callers are decompiled - addhook(0x006BB76E, (int)audio_play_sound_panned, 0, (int[]){EAX, EBX, ECX, EDX, EBP, END}, EAX, 0); // remove when all callers are decompiled + addhook(0x006BB76E, (int)audio_play_sound_panned, 0, (int[]){EAX, EBX, ECX, EDX, EBP, END}, 0, EAX); // remove when all callers are decompiled addhook(0x006C42D9, (int)scrolling_text_setup, 0, (int[]){EAX, ECX, EBP, END}, 0, EBX); // remove when all callers are decompiled addhook(0x006C2321, (int)gfx_get_string_width, 0, (int[]){ESI, END}, 0, ECX); // remove when all callers are decompiled addhook(0x006C2555, (int)format_string, 0, (int[]){EDI, EAX, ECX, END}, 0, 0); // remove when all callers are decompiled