Assembly 需要了解FF间接调用指令x86的帮助吗
我正在尝试重新编码一个简单的ftrace,但我在理解FF间接调用时遇到了困难,比如: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指令类似?如果没有,如何找到呼叫点的地址?该呼叫的返回地址可以由以下几个属性表示:
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给出的示例。