计算JMP指令的地址

3
我正在尝试通过用JMP指令替换函数开头来挂钩函数,这应该会引导到我的函数。但问题是我不知道如何计算JMP偏移量以定位到我的函数地址。如果你向内存前面跳转(目标地址-当前地址),我知道该怎么做,但是我不知道当你向内存后面跳转时该如何确定它。能有人帮忙吗?
5个回答

8

只需使用负偏移量向后跳转。

记得考虑 JMP 指令的大小。偏移量是相对于 JMP 指令的结尾而不是开头的。如果当前地址是您将要写入 JMP 的地址,则需要一个偏移量为 5+dest-current,因为 JMP 指令的大小加上偏移量共计 5 字节。


7
这是基本的数学知识,应该很容易理解。 :)
如果一个JMP向前跳转的距离是“目标-起始地址”,那么一个JMP向后跳转的距离就是“起始地址-目标”。
以简单的数字为例:如果你想从100跳转到110,你的JMP将是“110-100=10”。如果你想向后跳相同的距离,那么它将是“100-110=-10”。

1
不,我当然知道如何向前跳转。问题是,我不确定如何计算并以十六进制表示它。例如,如果我想从地址1000跳转到2000,那么它将是“E9 3E8”,但如果我想从地址2000跳转到1000,它会是什么呢?像“E9 FFFFFFFFFFFFFC18”这样可怕的东西吗? - user972948
4
Hexadecimal(十六进制)与其他进制类似,只需将例子中的100改为0x100110改为0x110即可,计算方法不变。 - Ken White
1
user972948:这并不可怕,只是你想要的负偏移量的二进制补码。 - SullX

1

相对跳转是带符号的,也就是说,它们使用符号位具有正负位移。绝对跳转是绝对的,所以没有关系。请参阅英特尔指令指南的2A和2B卷。


-2

你好,我建议你使用“call”语句。 “call”语句会负责将返回指针放在堆栈上。

计算所需跳转的公式为:ToAddress - FromAddress - 5

-5是因为“call”+偏移指令在内存中占用的空间

内存中的指针是反向写入的。如果要指向内存0x857830,则在内存中该值为307885

指令操作码 jmp = 0xE9 call = 0xE8


2
这个问题不是关于使用calljmp,所以那个方向错了。而且,虽然与之相关,但小端dword编码并不能用两个多位数字字符串很好地表示。相反,你应该写成例如30 78 85 00,以列出小端dword 857830h的字节。你还忘记包括尾随零(来自dword的最高字节)。 - ecm

-6

做得狡猾一些

向您的函数上方的某个位置发起虚拟调用

 call location1


 .location1
 call location2
 .location2
 pop ax
 ret
 .yourfunction

现在你在ax寄存器中有location2的地址

将3加到ax中,你就得到了函数的内存地址


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接