如何跳到x64和x32的英特尔语法中的内存位置

发布于 2025-01-27 23:28:53 字数 748 浏览 1 评论 0原文

我将如何跳到Intel Assembly语法中的已知内存地址(X32和X64)。

我想我有64位语法。例如,如果在x64中,我想在0x75767上jmp到代码,并且我位于0000,我会做:

0000: FF 25 01 00 00 00         jmp QWORD PTR [rip+0x75761]

正确吗?我认为我可以使用objdump objdump.exe -d -mintel,i386 -b biary -m i386 test.bin test.bin将这些字节分为x32指令中:

jmp    DWORD PTR 0x75761

然后仅使用clang ++。 EXE -Masm = Intel -M32 -C Test.o将此指令转换为X32字节,但它说:

error: invalid operand for instruction
jmp DWORD PTR 0x75761
^

我想避免写入任何寄存器。

我的X64 JMP指令正确吗?

我将如何完成X32中的类似工作?假设在x32中,我需要jmp到0x400107,我在0x400000

我正在处理Windows上的运行过程内存。如果我的问题不准确,请原谅我,我正在学习。

How would I jump to a known memory address in intel assembly syntax (both x32 and x64).

I think I have the 64 bit syntax down. For example, if in x64 I wanted to jmp to the code at 0x75767 and I was located at 0000, I would do:

0000: FF 25 01 00 00 00         jmp QWORD PTR [rip+0x75761]

Is that ^ correct? I thought I could dissemble those bytes that into x32 instruction using objdump objdump.exe -D -Mintel,i386 -b binary -m i386 test.bin which results in:

jmp    DWORD PTR 0x75761

Then just use clang++.exe -masm=intel -m32 -c test.o to convert this instruction to x32 bytes but it says:

error: invalid operand for instruction
jmp DWORD PTR 0x75761
^

I want to avoid writing into any registers.

Is my x64 jmp instruction correct?

How would I accomplish something similar in x32? Let's say in x32 I need to jmp to 0x400107 and I'm at 0x400000

I'm messing around with tweaking running process memory on Windows. Forgive me if my question has inaccuracies, I'm learning.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

久光 2025-02-03 23:28:53

目前尚不清楚您是需要组装还是机器代码。如果您想跳到绝对地址,则在64位模式下使用嵌入式指针地址RIP亲戚:

jmp [rip+foo]
foo: .quad target_address

机器代码:ff 25 00 00 00 00 00 xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx(最后一个8个字节是目标绝对地址)。
前6个是指令,2个字节编码jmp opcode + modRM,然后4个字节为rel32 = 0,因此加载地址是0个字节,超过了。整个说明的结尾。

或者,如果您可以放弃寄存器,则MOV R11,Offset Target_address/JMP R11,或选择您可以修改的任何寄存器。这通常比从代码中进行数据负载更好,该代码通常不会在L1D缓存或L1DTLB中很热(但可能在L2和L2TLB中。通常您需要放置.quad 在其他地方的常数,以及其他只读数据,如果很方便。)


在32位代码中,您可以使用push+ret> ret ret 如果您不担心关于分支预测:

push offset target_address
ret

机器代码:68 xx xx xx xx xx c3

如果您可以计算相对地址,则可以当然只需使用普通jmp,即e9 xx XX XX XX,最后4个字节是跳跃的距离(从字节遵循的指令计数,执行通常会继续执行)。

如果性能确实很重要,则mov eax,Offset target_address/jmp eax是一种非常标准的方式。 (如果您此时不需要值,则任何寄存器都可以使用。)

It's unclear whether you need assembly or machine code. If you want to jump to an absolute address then in 64 bit mode use an embedded pointer addressed rip relative:

jmp [rip+foo]
foo: .quad target_address

Machine code: ff 25 00 00 00 00 xx xx xx xx xx xx xx xx (with the last 8 bytes being the target absolute address).
The first 6 are the instruction, with 2 byte encoding the jmp opcode + modrm, and the 4 after that being rel32=0, so the load address is 0 bytes past the end of the whole instruction.

Or if you can spare a register, mov r11, OFFSET target_address / jmp r11, or pick any register you can modify. This is often better performance than doing a data load from code, which normally won't be hot in L1d cache or L1dTLB (but probably is in L2 and maybe L2TLB. Normally you'd want to put the .quad constant somewhere else, along with other read-only data, if that's convenient.)


In 32 bit code you can use the push+ret trick if you are not worried about branch prediction:

push offset target_address
ret

Machine code: 68 xx xx xx xx c3

If you can calculate the relative address you can of course just use a normal jmp which is e9 xx xx xx xx with the last 4 bytes being the distance to jump (counted from the byte following the instruction, where execution would normally continue).

If performance does matter, mov eax, offset target_address / jmp eax is a pretty standard way. (Any register works if you don't need its value at this point.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文