I am trying to calculate the relative address offset from one instruction to another.
I understand the basic calculation, and why I have to -5 (to cater for size of jmp and instruction size) (Calculating JMP instruction's address)
The question is, what if I want to jump not to start of a code but some specific instructions after it?
For example:
I want to JMP to the highlighted instruction OPENGL32.dll+48195, while I only have the start address of OPENGL32.wglSwapBu.
From my code, I understand I can do
uintptr_t gatewayRelativeAddr = src - gateway - 5;
where src is the address of OPENGL32.wglSwapBu and gateway is the start address of my code.
// 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;
I understand thus far what the code does:
calculate the relative address/bytes from the start address of gateway
to start address of src
(original function). I also -5 to cater for the size of the jump.
However, when I viewed it in memory, it ended up at where I want. But no where in the code I specified it to jmp to the highlighted instruction.
This works because len
equals exactly the number of bytes of instructions (5) that precede the desired one, which I presume was the whole point (you want to copy the instructions that will be jumped over, and maybe modify them later on?).
The jump instruction starts at gateway+len
, and so EIP at the jump will be gateway+len+5
. On the other hand, the address you want to jump to is src+len
. So the relative address is (src+len)-(gateway+len+5)
, and len
cancels out, so your formula is correct.
If you want to jump to an instruction that's not the next one after the ones you copied, you'll need to work out its offset from src
by disassembly (call it ofs
), and then set gatewayRelativeAddr
to (src+ofs)-(gateway+len+5)
.