作为安全类的赋值,我试图__asm__("jmp 0xbffff994");在我的代码中使用,但是当我在gdb中反汇编时,指令被更改为jmp 0xc8047e2a.知道为什么以及如何跳转到特定地址?
什么是callx86机器代码中绝对指针的"正确"方法?有没有一种方法可以在一条指令中完成它?
我想做什么:
我正在尝试基于"子程序线程"构建一种简化的迷你JIT(仍然).它基本上是字节码解释器中最短的步骤:每个操作码都是作为一个单独的函数实现的,因此每个基本的字节码块都可以"JIT"到它自己的新程序中,如下所示:
{prologue}
call {opcode procedure 1}
call {opcode procedure 2}
call {opcode procedure 3}
...etc
{epilogue}
Run Code Online (Sandbox Code Playgroud)
因此,我们的想法是每个块的实际机器代码只能从模板中粘贴(根据需要扩展中间部分),并且需要"动态"处理的唯一位是将每个操作码的函数指针复制到正确的位置作为每个调用指令的一部分.
我遇到的问题是了解call ...模板部分的用途.x86似乎没有考虑到这种用法,并且有利于相对和间接调用.
它看起来像我可以使用FF 15 EFBEADDE或2E FF 15 EFBEADDE在假设调用函数DEADBEEF(通过把东西变成一个汇编和反汇编,看到什么产生有效的结果,基本上发现了这些未通过了解他们在做什么),但我不理解的东东细分,特权和相关信息足以看出差异,或者这些信息与更常见的call指令有何不同.英特尔架构手册还建议这些仅在32位模式下有效,在64位模式下"无效".
有人可以解释这些操作码以及我是如何或者是否会为此目的使用它们或其他人?
(通过寄存器使用间接调用也有明显的答案,但这似乎是"错误的"方法 - 假设实际存在直接调用指令.)
我如何跳转到 intel 汇编语法(x32 和 x64)中的已知内存地址。
我想我已经掌握了 64 位语法。例如,如果在 x64 中我想跳转到位于 的代码0x75767并且我位于0000,我会这样做:
0000: FF 25 01 00 00 00 jmp QWORD PTR [rip+0x75761]
Run Code Online (Sandbox Code Playgroud)
^ 正确吗?我想我可以使用 objdump 将这些字节分解为 x32 指令,objdump.exe -D -Mintel,i386 -b binary -m i386 test.bin结果是:
jmp DWORD PTR 0x75761
Run Code Online (Sandbox Code Playgroud)
然后只需使用clang++.exe -masm=intel -m32 -c test.o将此指令转换为 x32 字节即可,但它显示:
error: invalid operand for instruction
jmp DWORD PTR 0x75761
^
Run Code Online (Sandbox Code Playgroud)
我想避免写入任何寄存器。
我的 x64 jmp 指令正确吗?
我如何在 x32 中完成类似的事情?假设在 x32 中我需要跳转到0x400107并且我在0x400000
我正在调整 Windows 上的运行进程内存。如果我的问题有不准确的地方,请原谅我,我正在学习。