gpt4 book ai didi

assembly - 在 x64 asm 中,如何使用相对于 RIP 的跳转恰好跳过 1 条指令?

转载 作者:行者123 更新时间:2023-12-04 03:02:41 25 4
gpt4 key购买 nike

我试图在不使用标签的情况下恰好跳过 1 条指令,带有标签的示例是:

cmp r12, r13
je dest ; skip the jmp
jmp whatever
dest:
nop

但是,我的限制是我不能使用标签,所以我假设我必须创建一个相对于 RIP 寄存器的跳转。例如(伪):

cmp r12, r13
je rip+0x05 ; this would obviously depend on the length of the next instruction
jmp whatever
nop

但是,我缺乏产生任何工作的知识,而且据我所知,没有黑客是不可能读/写 RIP 寄存器的。

编辑: 我只熟悉 Intel 语法,并且使用 Keystone 作为汇编程序。我将从程序集中获取字节并将其加载到可执行内存位置。我正在使用我自己的网站从程序集中获取字节,如果您查看 it,您可能会明白这一点。 .

编辑 2: 我尝试了 Jesters 和 Margaret Blooms 的评论,建议使用:

je .+0x05
; or
je $+0x05

但是,我可以确认两者都不适用于 Keystone!幸运的是,我注意到 Keystone 能够处理这段代码:

je +0x05

有谁能证实这有效吗?

编辑 3: 我用 NASM 进行了尝试,$ 前缀在我测试的代码中运行良好。我用这个来测试它:

section .text       
global _WinMain@16

_WinMain@16:
jmp $+2+2 ; skip this jmp and the next jmp (each 2 bytes)
jmp $
ret 16

它按预期工作。还有 defuse产生与 Keystone 相同的输出。唯一的区别是 defuse 使用 $ 前缀,而 Keystone 根本不需要!Keystone 等价物是:

jmp +4
jmp .
ret 16

最佳答案

请注意,在 NASM 和 MASM 中,$ 不是前缀。 It's a stand-alone keyword / symbol which refers to the address of the current line .

je $+5 不行:jmp rel32 是 5 个字节,short JCC 是 2。所以你需要 je $+7 跳过 5 字节指令,或 $+4 跳过 2 字节指令。

rel8 位移将为 0x050x02,因为跳转编码了它们从指令末尾开始的位移。但是 NASM 的 $ 标签给出了指令开始的地址,汇编程序总是根据目标地址为你计算相对位移。因此对于 $+x,您需要包括当前指令的长度。

如果你想自己编码 rel8,你可以使用 db 伪指令来发出你想要的字节。例如db 0xEB, 0x02


您不使用任何标签的整个方法/目标从根本上来说是有缺陷的,除非您有可靠的方法来了解下一条指令的长度。 (例如,通过使用 jmp NEARjmp SHORT 来强制进行长编码或短编码)。您所能做的就是编码向前移动固定字节数的跳转,而不是跳过一条指令的跳转,无论宽度如何。

但真的只是使用标签;无论如何,x86 跳转始终是相对的,因此让您的汇编器让您的生活更轻松并计算正确的相对位移。

关于assembly - 在 x64 asm 中,如何使用相对于 RIP 的跳转恰好跳过 1 条指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47775452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com