【问题标题】:Trouble with Call to Absolute Address with IA32 [duplicate]使用 IA32 调用绝对地址时出现问题 [重复]
【发布时间】:2015-10-28 19:55:33
【问题描述】:

我正在尝试使用调用指令进入另一个函数 这些是我的尝试:

call 0x08048b98

由于某种原因,这只是调用 0x5d6cc555,我不知道它是从哪里获得该值的。

mov eax, 0x08048b98
call eax

这给了我 mov 指令的段错误。

我知道我一定错过了一些东西,但我已经工作了好几个小时了,还是想不通。任何帮助将不胜感激!

【问题讨论】:

  • 您使用的是哪个汇编程序?使用普通的0x08048b98 可能指的是位于该地址的内存......你必须以某种方式告诉编译器这些是简单的常量,而不是地址。
  • 我使用 GCC 作为编译器,使用 ODJDUMP 作为反汇编程序。我不知道如何告诉编译器这些是简单的常量
  • 请注意,AT&T 语法在这里起作用(操作数顺序,一般语法)。在常量前面加上一个美元符号来引用常量而不是地址。
  • 我刚刚尝试了“代码”(调用 $0x08048b98),但在尝试编译时出现“操作数类型与 `call' 不匹配”错误。
  • 是的,坦率地说,我不知道如何将绝对值传递给call。 :/ 试试mov $0x08048b98, %eax; call %eax。在互联网上搜索更多信息。

标签: assembly x86 call att


【解决方案1】:

正如 cmets 中所指出的,只使用 call 0xdeadbeef 应该可以工作。我现在已经验证了这一点,它也可以在我的机器上运行。所以下面的答案没有用。我还是把它留在这里,所以以后没有人会提出这个问题,并且失望地认为没有答案。
我希望代码示例仍然对其他一些初学者有所帮助。


假设 ia-32 表示 GAS 语法,应该可以使用 * 将其指定为绝对地址(而不是相对跳转)并使用 $ 将其指定为常量而不是让它加载此地址的值。
因此,如果它是有意义的

call *$0xdeadbeef

但这不起作用。所以这里有一些似乎确实有效的建议。

对于 32 位 (gcc -m32),我知道以下方法有效:

movl $0xdeadbeef, %edi
call *%edi

对于 64 位,您可能需要改用 %rdi

另一种选择,如果您不想使用 reg,则可以使用标签:

.section .text
.globl main
main:
        movl $0x3, %eax        # some other instructions
        call *(THE_ADDR)       # call to your constant absolute address
        ret                    # some other instructions
THE_ADDR:
        .long 0x80483e6        # your constant absolute address
other_func:                    # here is 0x80483e6
        movl $0x4, %eax        # this code is executed

同样,这是 32 位 AT&T GAS 语法汇编代码,由 gcc -m32 汇编而成。


为了完整起见:

mov eax, 0x08048b98
    call eax

这给了我 mov 指令的段错误。 这是因为如果您使用 GAS 语法,您正试图将 eax 移动到该地址。它宁愿是mov $0x08048b98, %eax

This Q&A 也可能对您有所帮助。

【讨论】:

  • 您只使用* 进行间接 跳转。 GAS AT&T 语法中的call 0xdeadbeef 工作正常,在链接时计算正确的rel32 以到达该绝对地址。
  • 另请注意,movl 0xdeadbeef, %edi 是从该绝对地址加载的。 OP 知道目标函数的绝对地址,而不是指向它的指针。所以在与位置无关的代码中,你应该使用movl $0xdeadbeef, %edi / call *%edi。 (没有使用绝对地址的 near-call 编码,只有相对地址。felixcloutier.com/x86/CALL.html
  • call 0xdeadbeef 用于生成对该地址的相对调用,IDK 为什么您只提到尝试使用绝对间接call *something。 (call 0xdeadbeef 不会链接到 64 位代码,因为 0xdeadbeef 距离静态代码所在的位置超过 +-2GiB,但它可以在 32 位模式下工作。像call 0x1234567 这样的地址在 64 位下工作-bit 模式也带有 AT&T 语法。)
  • 我正在考虑清理 x86 调用绝对地址问题的重复项,其中一些我已经回答了 :) IDK,可能 OP 做错了什么,比如假设 call 0xdeadbeef 是与位置无关;它不是。实际上,IDK mov eax, 0x08048b98 甚至会如何组合成 AT&T 语法; eax(没有%)是符号名称,而不是寄存器。问题看起来很假,应该可能会关闭。也许我应该写一个规范的问答,问题中没有一堆令人困惑的东西,有 AT&T 和 NASM 语法答案。
  • 好的,完成对Call an absolute pointer in x86 machine code 的更新,使其成为一个很好的规范答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-03
  • 2021-01-31
相关资源
最近更新 更多