组合远距离呼叫或远距离跳跃(j *指令) [英] Assemble far calls or far jumps (j* instructions)

查看:175
本文介绍了组合远距离呼叫或远距离跳跃(j *指令)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个分配表,该表更改某些指令在AllocateMemoryOnRemoteProcess分配的另一个地址中的位置.

I'm trying to create a dispatch table which changes the location of some instruction in another address which is allocated by AllocateMemoryOnRemoteProcess.

我遇到的问题之一是几乎所有的Calls和所有的Jumps都是nearrelative,只要我将程序集加载到新位置,那么这些指令就不会工作.

One of the problems that I encountered was almost all of Calls and all kind of Jumps are near and relative and as long as I load the assemblies in new location, then these instructions won't work.

据我所知,我应该将这些指令转换为far jumpfar call,在谷歌搜索过程中看到的一种解决方案是使用pushret,如:

As I know I should convert these instructions to far jump or far call one of the solutions that I saw during my googling was using push and ret like :

push 0xdeadbeef
ret

或者有人建议使用寄存器进行绝对寻址,如:

or someone suggests using registers for absolute addressing like :

mov %eax,0xdeadbeef
jmp %eax

这些解决方案在我的情况下不起作用,因为只要我处于函数例程中,更改堆栈状态或在第二种情况下,更改类似%eax的寄存器都会导致失败.

These solutions won't work in my case because as long as I'm in a function routine, changing the stack state or in the second case changing a register like %eax causes failure.

此问题中的某人写道:

Someone in this question wrote :

  • 调用远(使用操作码9A)跳转到绝对段和偏移. 即,就像立即设置CS和?IP.
  • call far (with opcode 9A) jumps to an absolute segment and offset. ie, it's like setting CS and ?IP at once.

所以看来我应该对far calls使用带9A的操作码,但这仅适用于调用,而且我不知道要使用这种方法转换各种跳转!

So it seems I should use opcode with 9A for far calls, but this just works for the calls and I have no idea about converting all kinds of Jumps with this method!

我经常使用objdump来反汇编二进制文件,然后使用以下命令将clang用作汇编器:

I regularly use objdump to disassemble a binary, then use clang as the assembler by using the following command :

clang -c MyAsm.asm -m32

但是当我使用上述命令进行汇编时,结果是相对的.

But when I assemble with the above command then the result is relative.

例如,当MyAsm.asm为时:

call   0x402af2

objdump的结果是:

    MyAsm.o:    file format Mach-O 32-bit i386

Disassembly of section __TEXT,__text:
__text:
       0:   e8 ed 2a 40 00  calll   4205293 <__text+0x402AF2>

这些结果是相对的.

所以我的问题是:

  1. 如何用clang或任何其他工具(当然,它们同时适用于80x86和Amd64结构)来组装far callsfar jumps(j*指令)?
  2. 是否还有其他使用相对寻址的指令(如调用或跳转),所以我应该重新组装以避免出现此问题?
  1. How can I assemble far calls or far jumps (j* instructions) with clang or any other tools (which of course, work for both 80x86 and Amd64 structures)?
  2. Is there any other instruction like calls or jumps that use relative addressing, so I should reassemble in order to avoid the problem?

推荐答案

如果您可以保留一个寄存器,建议您使用

If you can spare a register, I advise you to use

    movabs $addr,%rax
    jmp *%rax

,或者,如果您可以确保地址在地址空间的前2 GB之内,

or, if you can ensure that the address is within the first 2 GB of address space,

    mov $addr,%eax
    jmp *%eax

强烈建议您不要使用

    push $addr
    ret

因为这破坏了返回预测,使接下来的几个函数返回速度比必需的慢.跳远和呼叫(ljmplcall)是红色鲱鱼.尽管可以在技术上使用它们,但它们并不能帮助您实现目标,并且实际上是为了不同的目的(更改cs),并且在现代处理器上以慢速,微编码的指令实现.

as this trashes the return prediction, making the next few function returns slower than necessary. Far jumps and calls (ljmp and lcall) are a red herring. While they could technically be used, they won't help you achieve your goal and are actually meant for a different purpose (changing cs) and are implemented as slow, micro-coded instructions on modern processors.

如果您不能保留寄存器,则可以使用以下技巧:

If you cannot spare a register, you can use this sort of trick instead:

    jmp *0f(%rip)
0:  .quad addr

这应该可以正常工作,并且不需要您使用额外的寄存器.但是,它比使用寄存器要慢.

This should just work and in addition doesn't require you to use an extra register. It is slower than using a register though.

请注意,条件跳转严格要求跳转目标必须是立即执行的.如果要有条件地跳转到绝对地址,请使用如下习惯用法:

Note that conditional jumps strictly require the jump target to be immediate. If you want to do a conditional jump to an absolute address, use an idiom like this:

    # for jz addr
    jnz 1f
    jmp *0f(%rip)
0:  .quad addr
1:

这篇关于组合远距离呼叫或远距离跳跃(j *指令)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆