【问题标题】:Need help understanding FF indirect call instruction x86需要帮助理解 FF 间接调用指令 x86
【发布时间】:2017-05-06 12:58:12
【问题描述】:

我正在尝试重新编码一个简单的 ftrace,但我无法理解像这样的 FF 间接调用:

ff 15 76 0b 20 00       callq  *0x200b76(%rip)        # 600ff0 <__libc_start_main@GLIBC_2.2.5>

它是否像带有偏移量的 E8 指令一样工作?如果没有,如何找到调用点的地址?以及该调用的返回地址?

【问题讨论】:

  • 你的调试器/反汇编器不是在旁边的注释中给你目标地址吗?它正在调用__libc_start_main。它会像任何其他函数调用一样返回。
  • @CodyGray 那不正确。它正在调用存储在该地址的任何内容。

标签: assembly x86 intel


【解决方案1】:

指令callq *0x200b76(%rip) 做了以下事情:

  1. rip + 0x200b76 加载一个64 位字,其中rip指令指针。根据评论,这应该是地址0x600ff0,但如果您的代码被重新定位,它可能会有所不同。
  2. 将下一条指令的地址压入堆栈作为返回地址。
  3. 跳转到我们在第一步中读取的数据的值。

与普通的call(即操作码e8)指令的不同之处在于这是一个间接函数调用,我们调用的地址是从内存中加载的,而不是在那里指定的。这由星号 (*) 表示。 call foocall *foo 就像 mov $foo,%eaxmov foo,%eax

【讨论】:

    【解决方案2】:

    跳跃可以通过几个属性来表征:

    • 直接或间接(即地址是在指令中给出还是从内存指针中检索)。

    • 相对(地址以增量形式给出,相对CALL 操作码所在的位置)或绝对(跳转到提供的实际地址)。间接跳转总是绝对的。

    • 近(在同一段)或远(在不同的段)。跳远总是绝对的。

    现在,E8 是直接的、近的和相对的。相比之下,FF 是间接的、接近的和绝对的。 FF 的一个变体是远而不是近,主要用于呼叫门 AFAIK。有关CALLs 的简洁表,请参阅here

    另请参阅:How can I tell if jump is absolute or relative?

    所以对于你的问题:

    如何找到调用点的地址

    15 表示指针是相对于 RIP 的(如果它是相对的,例如相对于 RAX,那么您将拥有 ff 90)。相对于RIP 的偏移量在紧跟15 的四个字节中 - 在您的示例中,这些是0x00200b76。有关解码的更多说明,请参阅Why call instruction opcode is represented as FF15?

    该调用的返回地址

    返回地址始终是紧跟在CALL 指令之后的指令。因此,如果CALL 位于地址0x100000,则返回地址将为0x100006

    【讨论】:

    • 请注意,整个操作码是ff /2,因为 modr/m 字节的一位数也是 opcde 的一部分。你指的ff 的另一个变体是间接远调用,操作码ff /3。请注意,许多其他指令的操作码 ff(例如 inc r/m32dec r/m32)具有不同的扩展操作码。
    • @fuz 这是一个公平的观点。我提到 ff /3 变体是为了完整性,而不是因为这是 OP 给出的示例。
    【解决方案3】:

    间接分支(间接跳转和间接调用)是二进制分析工具面临的主要挑战。您需要检查几个工具以了解这些工具如何处理间接分支。最流行的二进制分析工具有:

    • IDA 专业版
    • 雷达2
    • 戴宁
    • 吉德拉
    • BAP

    这些技术使用不同的方法来解决间接分支(编译器模式、递归反汇编和传播)。 但是,在我看来,没有一种工具能够解决所有类型的间接分支。

    重要提示: 间接分支是:

    1. 间接跳转,
    2. 间接调用函数,
    3. 尾函数,以及
    4. 不返回函数

    【讨论】:

      猜你喜欢
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-07
      • 2013-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多