如何在二进制的PLT中找到静态图书馆函数的索引?

逆向工程 二元分析 x86 C 小精灵 二进制
2021-06-12 05:22:26

所以现在我正在尝试在我的反向工具中解析函数调用及其名称

我遇到的问题是诸如 printf 和 fwrite 之类的库函数在符号表中没有相应的地址,这与实际程序中的函数不同,它们在符号表中包含虚拟地址,因此我可以在以下情况下解析它们的名称它们被静态调用

基本上我想解析函数的名称,即使是像 printf 这样的静态库函数,就像 readelf 所做的一样(我尝试过 readelf 并且确实它确实解析了 printf 的名称,即使它说符号表中 printf 的地址值是 0 与其他函数不同所以不确定它是如何实现plt内部printf的偏移量的)

所以我有这些问题:

  1. 如何在 PLT 中找到 printf 的索引或地址,以便在看到“呼叫地址”时解析其名称

  2. 与代码中的函数不同,为什么符号表不包含这些函数的虚拟地址?考虑到这些是静态库并且在该程序中静态链接,它们不应该像其他函数一样具有固定地址吗?

  3. 该程序只是main中的一个printf函数,只包含stdio.h,现在我的理解是我静态地包含了stdio.h,考虑到我在开始时包含它并且在编译时没有使用任何特定选项。那么为什么它会进入 PLT 而不是 .text 部分并具有静态地址?我想当我在开始时包含一个库时,它基本上是将它复制并粘贴到我的 .text 部分中?

1个回答

如何在 PLT 中找到 printf 的索引或地址,以便在看到“呼叫地址”时解析其名称

当一个函数出现在PLT(Procedure Linkage Table) 部分时,这意味着它的地址在编译时是未知的,必须在运行时由动态链接器解析。但是,要知道在程序中的某个时刻调用了某个函数,您可以使用像objdump这样的工具,它会显示函数名称,然后@plt像这样:

call   720 <printf@plt>

与代码中的函数不同,为什么符号表不包含这些函数的虚拟地址?考虑到这些是静态库并且在该程序中静态链接,它们不应该像其他函数一样具有固定地址吗?

因为它们不是静态链接的(请参阅第一个问题答案的第一句话)。它们没有固定地址,因为这些将在运行时解析。

那么为什么它会进入 PLT 而不是 .text 部分并具有静态地址?我想当我在开始时包含一个库时,它基本上是将它复制并粘贴到我的 .text 部分中?

如果每个可执行文件都包含同一个库的副本,那将是浪费空间。这些.h文件被包含在内,它们通常包含声明所以你不包括声明的函数的编译定义.h- 只是原型。连接器是负责联系与它使用的库程序。它们仍然可以静态或动态链接,并且由于动态链接避免将整个库的代码复制到每个可执行文件中,因此经常使用它而不是静态链接。

请参阅此问题以获取进一步参考。