我正在尝试连接Windows函数FindWindowA()。我在没有“热修补”的情况下成功地完成了下面的代码:我已经在函数的开头覆盖了字节。调用myHook(),调用FindWindowA()时会显示一个消息框。
user32.dll启用了热补丁,我希望在实际函数之前覆盖NOPs,而不是覆盖函数本身。但是,当我将热补丁设置为TRUE时,下面的代码将无法工作。当FindWindowA()被执行时,它什么也不做。
#include <stdio.h>
#include <windows.h>
void myHook()
{
MessageBoxA(NULL, "Hooked", "Hook", MB_ICONINFORMATION);
}
int main(int argc, char *argv[])
{
BOOLEAN hotpatching = FALSE;
LPVOID fwAddress = GetProcAddress(GetModuleHandleA("user32.dll"), "FindWindowA");
LPVOID fwHotpatchingAddress = (LPVOID)((DWORD)fwAddress - 5);
LPVOID myHookAddress = &myHook;
DWORD jmpOffset = (DWORD)&myHook - (DWORD)(!hotpatching ? fwAddress : fwHotpatchingAddress) - 5; // -5 because "JMP offset" = 5 bytes (1 + 4)
printf("fwAddress: %X\n", fwAddress);
printf("fwHotpatchingAddress: %X\n", fwHotpatchingAddress);
printf("myHookAddress: %X\n", myHookAddress);
printf("jmpOffset: %X\n", jmpOffset);
printf("Ready?\n\n");
getchar();
char JMP[1] = {0xE9};
char RETN[1] = {0xC3};
LPVOID offset0 = NULL;
LPVOID offset1 = NULL;
LPVOID offset2 = NULL;
if (!hotpatching)
offset0 = fwAddress;
else
offset0 = fwHotpatchingAddress;
offset1 = (LPVOID)((DWORD)offset0 + 1);
offset2 = (LPVOID)((DWORD)offset1 + 4);
DWORD oldProtect = 0;
VirtualProtect(offset0, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(fwAddress, JMP, 1);
memcpy(offset1, &jmpOffset, 4);
memcpy(offset2, RETN, 1);
VirtualProtect(offset0, 6, oldProtect, &oldProtect);
printf("FindWindowA() Patched");
getchar();
FindWindowA(NULL, "Test");
getchar();
return 0;
}你能告诉我怎么回事吗?
谢谢。
发布于 2014-01-06 09:08:09
启用热修补功能的可执行映像由编译器和链接器准备,以便在使用时替换映像。应用以下两个更改(x86):
mov edi, edi (/hotpatch).为了说明这一点,下面是启用热播功能的一个典型的反汇编清单:
(2) 768C8D66 90 nop
768C8D67 90 nop
768C8D68 90 nop
768C8D69 90 nop
768C8D6A 90 nop
(1) 768C8D6B 8B FF mov edi,edi
(3) 768C8D6D 55 push ebp
768C8D6E 8B EC mov ebp,esp (1)用2字节的no指定函数入口点.(2)是链接器提供的填充,而(3)是重要的函数实现的起点。
要连接到函数,必须用跳转到钩子函数jmp myHook来覆盖jmp myHook,并通过用相对跳转jmp $-5替换(1)来实现这段代码的可达性。
钩子函数必须使堆栈处于一致状态。应该将其声明为__declspec(naked),以防止编译器生成函数prolog和epilog代码。最后的指令必须按照挂钩函数的调用约定执行堆栈清理,或者在(3)指定的地址跳回挂钩函数。
https://stackoverflow.com/questions/20939554
复制相似问题