假设我想使用以下操作码进行短跳:
EB CB 或 JMP rel8
“跳短,RIP = RIP + 8位位移符号 扩展到64位“
(其中CB是字节有符号值,表示与 EIP 寄存器中的方向相关的相对偏移量)
也许偏移总是偏移+ 2 ,因为此短跳转中的执行时间(参考方向)中的EIP是twobyte指令的基础,但是加数occurs always
eb 30 = jmp 0x00000032(+30)
eb e2 = jmp 0xffffffe4(-30)
然后EIP可以是有意的相同方向,因为fe + 2 00 或 EIP 。
eb fe = jmp 0x00000000
我发现令人惊讶的是,过度偏移出现了分叉,尽管这个数字是负数。但在英特尔,我发现没有提及(可能因为3000页)。
英特尔®64和IA-32架构 软件开发人员手册:Vol。 2A 3-423
近跳,其中跳跃范围从当前 EIP值限制为-128到+127 。
然后我考虑了三种可能性:
答案 0 :(得分:18)
是否是短跳,它总是destination - (source + sizeof(instruction))
。
即。 dst - end_of_jmp
在你的情况下(短跳),sizeof(instruction)
是2。
这种添加背后的原因是因为一旦cpu执行了指令获取阶段,指令指针就已经指向分支之后的指令。 rel8或rel32分支位移与该EIP / RIP值相关。
答案 1 :(得分:16)
rel8
相对于下一条指令的内存地址,可以通过创建两个可执行文件并将其拆解来轻松确认:
@label:
jmp @label
nop
这反汇编为(有了ndisasm,它在16位,32位和64位代码中是相同的):
EBFE jmp short 0x0
90 nop
然后,另一个可执行文件:
jmp @label
@label:
nop
EB00 jmp short 0x2
90 nop
因此,rel8
始终相对于jmp
之后的下一条指令进行编码。但是,反汇编程序(至少ndisasm
和udcli
)会显示它与jmp
指令本身的关系。这可能会引起一些混乱。
答案 2 :(得分:5)
跳转短路相对于跳转指令的 end (两个字节长)采用EIP,并采用一个字节操作数,这是一个符号扩展并添加到EIP。