我正在试图挂钩一个应用程序与我注入的DLL。 此刻该DLL包含一个钩子,一个函数蹦床和一个空的函数。 但是,当调用挂钩函数时,目标应用程序崩溃。 我看了一下出了什么问题,看起来被replace的跳转指令跳转到我没有指定的未知位置。 经仔细检查,我发现这个未知的地址与正确的地址非常相似。 看来未知的地址是正确的地址,它前面有4个垃圾位。 所以我的问题是这是怎么发生的,我可以纠正这个?
#define FUNC_JMP 0x00433504 #define FUNC_ADDR (FUNC_JMP+1) // Trampoline __declspec(naked) void setup (void) { ... } void hook (void) { DWORD protect, buf; DWORD adr = (DWORD) ((BYTE*) &setup - (FUNC_ADDR + 4)); VirtualProtect ((void*) FUNC_ADDR, 4, PAGE_EXECUTE_READWRITE, &protect); memcpy ((void*) FUNC_ADDR, &adr, 4); VirtualProtect ((void*) FUNC_ADDR, 4, protect, &buf); }
在0x00433504之前: jmp dword ptr ds:[0x1F8BAC4]
在0x00433504之后: jmp fword ptr ds:[0x10B51DC] fword jmp fword ptr ds:[0x10B51DC]
adr的实际值: 0x0B51DC2D
TLDR; 为什么我memcpy不完整的值,并向右移4位。
一个jmp dword指令有一个2字节的操作码,你只能跳过这个字节。 (请参阅#define FUNC_ADDR (FUNC_JMP+1)
所以你覆盖了部分指令,而忽略了一部分地址。 这也是由你发布的第二条指令表示的,因为现在它是jmp fword而不是jmp dword 。