Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 需要了解FF间接调用指令x86的帮助吗_Assembly_X86_Intel - Fatal编程技术网

Assembly 需要了解FF间接调用指令x86的帮助吗

Assembly 需要了解FF间接调用指令x86的帮助吗,assembly,x86,intel,Assembly,X86,Intel,我正在尝试重新编码一个简单的ftrace,但我在理解FF间接调用时遇到了困难,比如: ff 15 76 0b 20 00 callq *0x200b76(%rip) # 600ff0 <__libc_start_main@GLIBC_2.2.5> ff 15 76 0b 20 00 callq*0x200b76(%rip)#600ff0 它的工作方式是否与带有偏移量的E8指令类似?如果没有,如何找到呼叫点的地址?该呼叫的返回地址可以由以下几个属性表示:

我正在尝试重新编码一个简单的ftrace,但我在理解FF间接调用时遇到了困难,比如:

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

它的工作方式是否与带有偏移量的E8指令类似?如果没有,如何找到呼叫点的地址?该呼叫的返回地址可以由以下几个属性表示:

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

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

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

现在,
E8
是直接的、接近的和相对的。相反,
FF
是间接的、接近的和绝对的。FF有一个变体是far而不是near,主要用于呼叫门AFAIK。有关
CALL
s的简明表格,请参阅

另请参见以下内容:

因此,对于您的问题:

如何找到呼叫点的地址

15
表示指针相对于
RIP
(如果指针相对于
RAX
,则表示指针相对于
ff 90
)。相对于
RIP
的偏移量位于紧跟
15
之后的四个字节中-在您的示例中,它们是
0x00200b76
。有关解码的更多说明,请参阅

那个电话的回音地址


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

指令
callq*0x200b76(%rip)
执行以下操作:

  • rip+0x200b76
    加载一个64位字,其中
    rip
    是指令指针。根据注释,这应该是地址
    0x600ff0
    ,但如果重新定位代码,则可能会有所不同
  • 将堆栈上下一条指令的地址作为返回地址推送
  • 跳转到我们在第一步中读取的基准值
  • 与正常的
    调用
    (即操作码
    e8
    )指令不同的是,这是一个间接函数调用,我们调用的地址是从内存加载的,而不是在那里指定的。这由星号(
    *
    )表示
    callfoo
    是要
    call*foo
    mov$foo,%eax
    是要
    mov-foo,%eax
    间接分支(间接跳转和间接调用)是二进制分析工具的主要挑战。您需要检查几个工具,以了解这些工具如何处理间接分支。最流行的二进制分析工具有:

    • 艾达专业
    • 雷达2
    • 戴宁斯特
    • 吉德拉
    • BAP
    这些技术使用不同的方法来解析间接分支(编译器模式、递归反汇编和传播)。 然而,在我看来,没有任何工具能够解决所有类型的间接分支

    重要提示: 间接分支是:

  • 间接跳跃
  • 间接调用函数
  • 尾部功能,以及
  • 非返回函数

  • 你的调试器/反汇编程序不是在注释中给了你目标地址吗?它正在调用
    libc\u start\u main
    。它将像任何其他函数调用一样返回。@CodyGray,这是不正确的。它调用存储在该地址的任何内容。请注意,整个操作码是
    ff/2
    ,因为modr/m字节的一位数字也是opcde的一部分。你所说的
    ff
    的另一个变体是间接远呼叫,操作码
    ff/3
    。请注意,许多其他指令的操作码
    ff
    (例如,
    incr/m32
    dec r/m32
    )具有不同的扩展操作码。@fuz这是一个公平的观点。我提到的
    ff/3
    变体是为了完整性,而不是因为这是OP给出的示例。