如果你分配的内存地址是64位的话。如: 504BEA0000, 你可以这样
方法一:
48 B8 0000EA4B50000000 - mov rax,000000504BEA0000
FF E0 - jmp rax
指令和机器码:
mov rax, 64位地址 的机器码就是 “48 B8 64位地址的little-endian(需要64位即8个字节)”
jmp rax 的机器码 FF E0
这个方法会占用12个字节。如果你还要保存rax寄存器内容和还原寄存器,你还需要额外的2两个字节,即14个字节。
方法二:
如果跳转前后的地址都是32位的,那么地址的换算和32位没有什么区别,都是用的相对偏移。
方法三:
504BEA0006 - FF 25 00000000 - jmp qword ptr [504BEA000C]
504BEA000C - 00 00 - add [rax],al
504BEA000E - EA 4B500000 0000 - jmp 0000:0000504B
把64位的跳转地址000000504BEA0000作为数据直接写到跳转语句504BEA0006的下面504BEA000C处。那么跳转语句永远都是FF 25 00000000, 它会读取接下来的8个字节作为跳转地址来使用的。而这个地址就是你申请到的内存地址。可以看到这种方法需要14个连续字节,且不改变寄存器的内容。
当然也可以把跳转地址的数据写到其他的地方如: 04BEA000D处。 那么跳转语句的FF 25 00000000就变成FF 25 01000000, 其中01000000 little-endian读下来就是00000001=1 即关于504BEA000C的相对地址是1。这后面4个字节其实就是数据地址关于504BEA000C的偏移量。和32位的原理是相同的。
总之,以上三种方法各有特色也各有利弊。方法一和三对于32和64位地址是通用的。方法二适用当地址是32位的情况下。而对于第一种方法需要修改寄存器,但是不需要计算跳转地址,而且寻址范围包括整个64位可用地址空间。第三种方法不修改寄存器,但需要计算偏移地址,而且和32位一样寻址空间限制在32位即前后2GB的范围内。所以根据需要自己取舍吧。