计算 trampoline hook 的 JMP 指令地址

Calculating JMP instruction's address for trampoline hook

我正在尝试计算从一条指令到另一条指令的相对地址偏移量。

我了解基本计算,以及为什么我必须 -5(以适应 jmp 的大小和指令大小)(Calculating JMP instruction's address)

问题是,如果我不想跳转到代码的开头而是跳转到代码之后的一些特定指令怎么办?

例如:

original function

我想跳转到高亮指令OPENGL32.dll+48195,而我只有OPENGL32.wglSwapBu的起始地址。

根据我的代码,我知道我可以做到

uintptr_t gatewayRelativeAddr = src - gateway - 5;

其中src是OPENGL32.wglSwapBu的地址,gateway是我代码的起始地址

// len is 5

BYTE* gateway = (BYTE*)VirtualAlloc(NULL, len+5, MEM_COMMIT | MEM_RESERVE, 
PAGE_EXECUTE_READWRITE);
memcpy_s(gateway, len, src, len);

// Jump back to original function, but at the highlighted instruction
uintptr_t gatewayRelativeAddr = src - gateway - 5;

// add the jmp opcode to end of gateway

*(gateway + len) = 0xE9;

*(uintptr_t*)(gateway + len + 1) = gatewayRelativeAddr;

到目前为止,我了解代码的作用: 计算从gateway起始地址到src起始地址的相对address/bytes(原函数)。我也是-5来迎合跳跃的大小

然而,当我在内存中查看它时,它最终出现在我想要的位置。但是我在代码中没有指定它跳转到突出显示的指令。

这是可行的,因为 len 恰好等于所需指令之前的指令 (5) 的字节数,我认为这就是重点(您想复制将被跳过的指令,也许以后再修改它们?)。

跳转指令从gateway+len开始,因此跳转处的EIP为gateway+len+5。另一方面,你要跳转到的地址是src+len。所以相对地址是(src+len)-(gateway+len+5),和len抵消,所以你的公式是正确的

如果你想跳转到一个不是你复制的指令之后的下一条指令,你需要通过反汇编计算出它与 src 的偏移量(称之为 ofs) , 然后将 gatewayRelativeAddr 设置为 (src+ofs)-(gateway+len+5).