假设我想使用以下操作码进行短暂跳转:
EB CB或JMP rel8
“跳短,RIP = RIP + 8位位移符号
扩展到64位”
(其中CB是一个字节带符号的值,表示与EIP寄存器中的方向有关的相对偏移)
偏移量可能总是偏移量+2,因为在此短暂跳转中执行时间(参考方向)中的EIP是双字节指令的基础,但是加数occurs always
eb 30 = jmp 0x00000032(+30)
eb e2 = jmp 0xffffffe4(-30)
则EIP可能会故意朝着同一方向,因为fe + 2为00或EIP。
eb fe = jmp 0x00000000
我发现令人惊讶的是,尽管偏移量为负,但发生了偏移。但是在Intel中我没有提及(也许是因为3000页)。
英特尔®64和IA-32架构
软件开发人员手册:第一卷2A 3-423
近距离跳跃,其跳跃范围从当前EIP值限制为–128至+127。
然后,我考虑了三种可能性:
是+2,因为它是执行时间中EIP的after / future值
编码值不是2s组件编码的带符号数字。
这出现在手册中,但我没有看到,因为我很愚蠢
最佳答案
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
指令本身显示它。这可能会引起一些混乱。关于assembly - 如何在x86中编码相对较短的jmp,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14889643/