为什么很多导入的函数会跳转到不包含指令的地址?

逆向工程 部件 x86 雷达2 职能
2021-07-06 22:33:26

我正在学习使用radare2 分析二进制文件,并且对导入函数中发生的事情感到困惑。在下面名为 Lab2B 的二进制文件中,我静态反汇编了二进制文件,然后反汇编了其中一个导入的库函数 sym.imp.printf。正如您在下面看到的,它仅列出了一条指令:jmp dword [reloc.printf]. 当我寻找该位置[reloc.printf]并打印其中包含的反汇编函数时,命令行会打印“无法在 0x0804a00c 处找到函数”。我注意到所有其他导入函数的行为相同。它们通常有一条指向不包含任何指令的地址的指令。

为什么指令告诉编译器跳转到的地址中没有包含指令?

在此处输入图片说明

1个回答

我假设您正在静态检查程序,因此,链接器尚未计算导入符号的地址。要更好地理解这一点,您需要熟悉两个术语,PLT 和 GOT。无论如何,即使您正在调试文件,这些也不是函数而是带有指针的表。所以pdf不是你应该尝试的。试一试pd

动态链接

过程链接表是一种内存结构,其中包含链接时地址未知的外部函数的代码存根。

每当我们CALL.text段中看到一个函数指令时,它不会直接调用该函数。相反,它调用 stub 代码PLT,比如func_name@plt然后存根跳转到全局偏移表 ( GOT) 中为该函数列出的地址如果它是CALL此函数的第一个,则该GOT条目将指向回PLT,后者将调用动态链接器,该链接器将解析所需函数的实际地址。下次func_name@plt调用时,存根直接从GOT.

要阅读有关链接过程的更多信息,我强烈推荐Ian Lance Taylor撰写的有关链接器的系列文章


Radare2 正在检测 PLT 和 GOT 的地址。你看到的sym.imp.printf地方实际上printf()是 PLT 的 int保留地址当你看到的reloc.printf是 GOT 中为它保留的地址。

通过使用iS你可以列出的部分PLTGOT