DIY Your Ani patch
// HookFunction
BOOL HookFunction(
PBYTE pbCode,
void *pfnHook)
{
LPVOID lpvbounce;
DWORD cb;
DWORD dwprotect;
//---------------- skip hot-patch JMP SHORT if present
if ( pbCode[0] == 0x8B && pbCode[1] >= 0xC0 && // 8Bh/11abcabc: MOV reg, self
(((pbCode[1] >> 3) ^ pbCode[1]) & 0x07) == 0 )
{
pbCode += 2;
}
//---------------- prepare dynamic portion of hook
cb = DisassembleProlog(pbCode, 0x05);
if (cb < 0x05)
return FALSE;
lpvbounce = VirtualAlloc(NULL, 0x05 + cb + 0x05, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (lpvbounce == NULL)
return FALSE;
* ((LPBYTE)lpvbounce + 0x00) = 0xE8; // E8h/xxxxxxxx: CALL pfnHook
*(LPDWORD)((LPBYTE)lpvbounce + 0x01) = (DWORD)pfnHook - (DWORD)lpvbounce - 0x05;
memcpy((LPBYTE)lpvbounce + 0x05, pbCode, cb);
* ((LPBYTE)lpvbounce + 0x05 + cb) = 0xE9; // E9h/xxxxxxxx: JMP (pbCode + cb)
*(LPDWORD)((LPBYTE)lpvbounce + 0x06 + cb) = (DWORD)pbCode - (DWORD)lpvbounce - 0x05 - 0x05;
VirtualProtect(lpvbounce, 0x05 + cb + 0x05, PAGE_EXECUTE_READ, &dwprotect);
//---------------- hook code entry point ("prolog")
if (!VirtualProtect(pbCode, cb, PAGE_EXECUTE_READWRITE, &dwprotect))
{
VirtualFree(lpvbounce, 0, MEM_RELEASE);
return FALSE;
}
* (pbCode + 0x00) = 0xE9; // E9h/xxxxxxxx: JMP lpvbounce
*(DWORD*)(pbCode + 0x01) = (DWORD)lpvbounce - (DWORD)pbCode - 0x05;
VirtualProtect(pbCode, cb, dwprotect, &dwprotect);
return TRUE;
} //HookFunction()
// HookExports
const struct { const char *szexport; void *pfn; } USER32_HOOKS[] =
{
{ "LoadImageA", MyLoadImageA },
{ "LoadImageW", MyLoadImageW }
} ;
BOOL HookExports()
{
HMODULE hm;
PBYTE pb;
size_t c;
//---------------- hook USER32.DLL exports
hm = GetModuleHandle("user32.dll");
if (hm == NULL)
return FALSE;
for (c = 0; c < (sizeof(USER32_HOOKS) / sizeof(USER32_HOOKS[0])); c++)
{
pb = (PBYTE)GetProcAddress(hm, USER32_HOOKS[c].szexport);
if (pb == NULL)
continue;
HookFunction(pb, USER32_HOOKS[c].pfn);
} //for(c)
return TRUE;
} //HookExports()
// HookFunction
BOOL HookFunction(
PBYTE pbCode,
void *pfnHook)
{
LPVOID lpvbounce;
DWORD cb;
DWORD dwprotect;
//---------------- skip hot-patch JMP SHORT if present
if ( pbCode[0] == 0x8B && pbCode[1] >= 0xC0 && // 8Bh/11abcabc: MOV reg, self
(((pbCode[1] >> 3) ^ pbCode[1]) & 0x07) == 0 )
{
pbCode += 2;
}
//---------------- prepare dynamic portion of hook
cb = DisassembleProlog(pbCode, 0x05);
if (cb < 0x05)
return FALSE;
lpvbounce = VirtualAlloc(NULL, 0x05 + cb + 0x05, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (lpvbounce == NULL)
return FALSE;
* ((LPBYTE)lpvbounce + 0x00) = 0xE8; // E8h/xxxxxxxx: CALL pfnHook
*(LPDWORD)((LPBYTE)lpvbounce + 0x01) = (DWORD)pfnHook - (DWORD)lpvbounce - 0x05;
memcpy((LPBYTE)lpvbounce + 0x05, pbCode, cb);
* ((LPBYTE)lpvbounce + 0x05 + cb) = 0xE9; // E9h/xxxxxxxx: JMP (pbCode + cb)
*(LPDWORD)((LPBYTE)lpvbounce + 0x06 + cb) = (DWORD)pbCode - (DWORD)lpvbounce - 0x05 - 0x05;
VirtualProtect(lpvbounce, 0x05 + cb + 0x05, PAGE_EXECUTE_READ, &dwprotect);
//---------------- hook code entry point ("prolog")
if (!VirtualProtect(pbCode, cb, PAGE_EXECUTE_READWRITE, &dwprotect))
{
VirtualFree(lpvbounce, 0, MEM_RELEASE);
return FALSE;
}
* (pbCode + 0x00) = 0xE9; // E9h/xxxxxxxx: JMP lpvbounce
*(DWORD*)(pbCode + 0x01) = (DWORD)lpvbounce - (DWORD)pbCode - 0x05;
VirtualProtect(pbCode, cb, dwprotect, &dwprotect);
return TRUE;
} //HookFunction()
// HookExports
const struct { const char *szexport; void *pfn; } USER32_HOOKS[] =
{
{ "LoadImageA", MyLoadImageA },
{ "LoadImageW", MyLoadImageW }
} ;
BOOL HookExports()
{
HMODULE hm;
PBYTE pb;
size_t c;
//---------------- hook USER32.DLL exports
hm = GetModuleHandle("user32.dll");
if (hm == NULL)
return FALSE;
for (c = 0; c < (sizeof(USER32_HOOKS) / sizeof(USER32_HOOKS[0])); c++)
{
pb = (PBYTE)GetProcAddress(hm, USER32_HOOKS[c].szexport);
if (pb == NULL)
continue;
HookFunction(pb, USER32_HOOKS[c].pfn);
} //for(c)
return TRUE;
} //HookExports()