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

为什么指令告诉编译器跳转到的地址没有任何指令?



#1 楼

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

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

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

要了解有关链接过程的更多信息,我强烈建议Ian Lance Taylor发表有关链接器的系列文章。和GOT。在看到sym.imp.printf的位置,它实际上是printf() int PLT的保留地址。当看到reloc.printf是GOT中为其保留的地址时。

通过使用iS,您可以列出PLTGOT的各个部分。