HooK MessageBoxA
#include <windows.h>
#include <iostream>
#define DN_PATCH_LENGTH 5
DWORD g_dwRetAddress;
DWORD g_dwHookAddress;
void MessageBoxProc(HWND hWnd, LPCSTR lpText,LPCSTR lpCaption,UINT uType)
{
std::cout << hWnd << lpText << lpCaption << uType;
}
//裸函数编译器不会自动生成多余的代码,无法使用局部变量
void __declspec(naked) NewMessageBox()
{
_asm
{
//保存寄存器
pushad
pushfd
//调用处理函数 0x24是上面压入的 参数入栈从右往左
push [esp + 0x24 + 0x10]
push [esp + 0x24 + 0xc + 0x4] //上面压入后这里要加上
push [esp + 0x24 + 0x8 + 0x8]
push [esp + 0x24 + 0x4 + 0xC]
call MessageBoxProc
add esp, 0x10
//恢复寄存器
popfd
popad
//执行覆盖的代码
mov edi, edi
push ebp
mov ebp, esp
//跳回去
jmp g_dwRetAddress
}
}
void HookMessageBox(bool bOpen)
{
BYTE byJmpCode[DN_PATCH_LENGTH] = { 0xE9 };
//备份原代码
static BYTE byOriginalCode[DN_PATCH_LENGTH] = { 0 };
//如果有多余的代码,置为nop
memset(&byJmpCode[1], 0x90, DN_PATCH_LENGTH - 1);
*(int*)&byJmpCode[1] = (int)NewMessageBox - (int)g_dwHookAddress - 5;
//备份被覆盖的code
memcpy(byOriginalCode, (PVOID)g_dwHookAddress, DN_PATCH_LENGTH);
if (bOpen)
{
DWORD dwOldProtect = 0;
VirtualProtect((PVOID)g_dwHookAddress, DN_PATCH_LENGTH, PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy((PVOID)g_dwHookAddress, byJmpCode, DN_PATCH_LENGTH);
VirtualProtect((PVOID)g_dwHookAddress, DN_PATCH_LENGTH, dwOldProtect, NULL);
}
else
{
DWORD dwOldProtect = 0;
VirtualProtect((PVOID)g_dwHookAddress, DN_PATCH_LENGTH, PAGE_EXECUTE_READWRITE, &dwOldProtect);
memcpy((PVOID)g_dwHookAddress, byOriginalCode, DN_PATCH_LENGTH);
VirtualProtect((PVOID)g_dwHookAddress, DN_PATCH_LENGTH, dwOldProtect, NULL);
}
}
int main()
{
HMODULE hUser32 = ::LoadLibraryA("user32.dll");
g_dwHookAddress = (DWORD)::GetProcAddress(hUser32, "MessageBoxA");
g_dwRetAddress = g_dwHookAddress + DN_PATCH_LENGTH;
HookMessageBox(true);
::MessageBoxA(0, "context", "title", 1);
}