64位汇编跳转,64位HOOK

传统JMP 只支持32位的程序, 64位程序的地址有 8个字节 ,直接JMP只支持4个字节,跳转的地址和HOOK地址相减超过4个字节 就会出错了

在64位 可以这样跳,

push rax 保存寄存器
mov rax,目标绝对地址
jmp rax
pop rax 还原寄存器

很简单,如果你分配的内存地址是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位没有什么区别,都是用的相对偏移。

方法三:
如果你用我前面提到的另外一种64位跳转方法,如

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的范围内。所以根据你的需要自己取舍吧。

安卓内存逆向交流【群】916759588

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值