查找PLT存根的地址

7

我正在使用Linux X86_64操作系统。

我需要根据动态函数的名称确定ELF文件中特定PLT入口的地址。虽然我可以从地址推断出文件偏移量,但我仍需要确定地址。

如果我使用objdump -D -z elffile反汇编ELF文件,我会看到objdump为PLT中的每个入口使用符号名称。(objdump从哪里获取这些地址和符号名称之间的关系?)

示例:

0000000000000041a2b0 fileno@plt:

如果我使用objdump -T elffile | grep fileno,我会得到类似这样的结果:
0000000000000   DF *UND*  00000000000000000   GLIBC_2.2.5 fileno

我需要从"C"中能够做的是,找到特定动态函数在ELF文件中的PLT条目并获取其地址。
背景是,我正在修补现有的ELF文件,并需要将函数调用重定向到另一个动态函数。我已经手动修补了一个ELF文件,使用objdump反汇编所收集的地址证明这对于我的特定应用程序有效,我只需要能够从程序中做到这一点。我希望不必爬行 objdump 反汇编器代码来弄清楚它如何获取 PLT 条目符号和地址。

有趣的是,似乎没有一种从汇编语言中实现此功能的方法。直觉上,movq someFunc@PLT,%rax 应该可以实现,但 @PLT 引用似乎意味着链接器修改会破坏 movq,这似乎使得这些 someFunc@PLT 引用仅可用于 call 指令。 - Petr Skocik
1个回答

8
我想到了一个解决办法:你需要解析rela.plt部分的重定位表。这些条目包含可用于通过索引动态符号部分查找函数名称的字符串表索引。动态符号部分中的每个条目都包含一个动态字符串表偏移量,可用于提取函数名称。当您找到相应的函数时,重定位表中的索引(+1)对应于函数PLT条目的.plt节中的索引。因此,要计算特定条目的地址,只需使用以下公式:.plt.sec地址+((relocation_index + 1)* .plt条目大小)。
这种方法适用于x86。 这对于PPC不起作用,因为PPC具有完全不同的.plt部分格式。如果有人有关于如何在PPC上执行此操作的任何信息,请发帖。

对于i386架构,PLT条目大小未正确报告。您可以将报告的plt条目大小乘以4,或者使用16作为条目大小。 - codemonkey
我不明白如何获取重定位表中的索引。你能否添加代码来解决这个问题? - Mahwish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接