Ello.
I'm trying to hook MineSweeper's ClickBox(x, y) function on XP. I know my function pointer and declaration is correct(calling it with typedef worked like a charm).
I have functions HookCall(dwAddress, dwFunction) which returns the address of the original function, and UnhookCall(dwAddress, dwOldCall) which redirects the call back to the original function.
I'm calling them as follows:
On DllMain(process attach)
Code:
dwOldClickBox = HookCall(dwClickBoxPtr, (DWORD)MyClickBox);
On my trampoline hook proc:
Code:
int MyClickBox(unsigned int x, unsigned int y)
{
UnhookCall(dwClickBoxPtr, dwOldClickBox);
int ret = ClickBox(x, y);
dwOldClickBox = HookCall(dwClickBoxPtr, (DWORD)MyClickBox);
return ret;
}
Redirecting the function works OK(I guess) because everything works normally until I click one of the cells on minesweeper. But when I do, something goes wrong and an unhandled win32 exception rises( minesweeper crashes).
It is very possible I simply don't know what I'm doing, my understanding of the concept of function hooking is at this point rather vague.
Here's the full source code for my injected DLL:
Code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
DWORD dwOldClickBox = 0;
DWORD dwClickBoxPtr = 0x1003512;
typedef int ( __stdcall *D_ClickBox )(unsigned int, unsigned int);
D_ClickBox ClickBox = (D_ClickBox)dwClickBoxPtr;
DWORD HookCall(DWORD dwAddress, DWORD dwFunction)
{
DWORD dwOldProtect, dwNewProtect, dwOldCall, dwNewCall;
BYTE callByte[5] = {0xE8, 0x00, 0x00, 0x00, 0x00};
dwNewCall = dwFunction - dwAddress - 5;
memcpy(&callByte[1], &dwNewCall, 4);
VirtualProtect((LPVOID)(dwAddress), 5, PAGE_READWRITE, &dwOldProtect);
memcpy(&dwOldCall, (LPVOID)(dwAddress+1), 4);
memcpy((LPVOID)(dwAddress), &callByte, 5);
VirtualProtect((LPVOID)(dwAddress), 5, dwOldProtect, &dwNewProtect);
return dwOldCall;
}
void UnhookCall(DWORD dwAddress, DWORD dwOldCall)
{
DWORD dwOldProtect, dwNewProtect;
BYTE callByte[5] = {0xE8, 0x00, 0x00, 0x00, 0x00};
memcpy(&callByte[1], &dwOldCall, 4);
VirtualProtect((LPVOID)(dwAddress), 5, PAGE_READWRITE, &dwOldProtect);
memcpy((LPVOID)(dwAddress), &callByte, 5);
VirtualProtect((LPVOID)(dwAddress), 5, dwOldProtect, &dwNewProtect);
}
int MyClickBox(unsigned int x, unsigned int y)
{
UnhookCall(dwClickBoxPtr, dwOldClickBox);
int ret = ClickBox(x, y);
dwOldClickBox = HookCall(dwClickBoxPtr, (DWORD)MyClickBox);
return ret;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
dwOldClickBox = HookCall(dwClickBoxPtr, (DWORD)MyClickBox);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
I'm really hoping one of you could point out where I'm being a dumbass.
Thanks in advance!