我经常在下面的代码段中看到该文本(<perror@plt+0x2008e0>),但是我不确定它是否调用perror来说明反汇编程序是否存在问题。如果主函数所做的第一件事是调用退出代码,那将很奇怪。最后,@plt指的是什么。

0000000000400540 <__libc_start_main@plt>:
  400540:   ff 25 0a 09 20 00    jmpq  *0x20090a(%rip)    # 600e50 <perror@plt+0x2008e0>


让我知道是否需要更多信息,我将更新问题

#1 楼

PLT代表过程链接表。它实际上是功能地址表。更准确地说,如此处所示,PLT是一个表,其中每个条目都包含一个跳转指令,该跳转指令实际上是该函数的代码所在的位置。因此,PLT由函数存根组成。

对动态链接函数的调用被编译为对PLT地址(而不是函数实际所在的地址)的调用。由于这种间接方式,模块中的外部调用可以相对跳转到PLT中来实现。动态链接器使用实际代码的运行时地址来更新PLT,这取决于被调用模块相对于被调用方在内存中的位置。链接,其中在编译时无法预测库的地址,并且动态链接器不需要更新代码本身(这将阻止在不同进程中以不同地址加载的库实例之间的共享)。

这说明了<__libc_start_main@plt>perror@plt中指示的跳转使来自反汇编程序的信息混乱。 <perror@plt+0x2008e0>意味着跳转目标是perror的PLT条目开始之后的0x2008e0字节-如果这是跳转到perror函数的代码中,那将是一个巨大的功能!实际上,跳转到的是main入口点的实际代码,该位置恰好位于perror PLT入口这么多的字节中(如果您使用的是GNU binutils,我认为objdump在这里选择了最后一个PLT入口)。二进制文件在编译时没有调试符号,因此所有功能的代码在反汇编程序中都显示为.text的巨大块,并且调试器没有更好的方法来命名该特定地址。如果存在调试符号,则反汇编程序将从二进制中的调试信息中提取函数名称。

#2 楼

因此,首先,(%rip)引用由%rip包含的值所指向的存储单元的内容。

,其次,<perror@plt+0x2008e0>引用符号perror@plt(加上偏移量0x2008e0。 />
如果您想了解有关PLT和GOT如何工作的更多详细信息,请随时提出另一个问题(因为它将填满数页,只是为了很好地说明它)。

注意:这个问题显然对我来说是!!! :-)

评论


所以我实际上只对所指的内容感兴趣,我想我会杀了这个问题,然后再问一个关于GOT和PLT的问题。

–RC1140
13年5月3日在7:38

实际上,我已经问过这个问题。但是,基本上,PLT / GOT是用于从动态加载的库中定位功能的表。

–恐怖
13年5月4日在19:05

再次感谢,一旦您提到PLT / GOT也是一项研究,我就发现它们是什么,它们如何工作以及它们的含义。

–RC1140
13年5月6日在10:27

@perror:为什么+偏移?这是否意味着PLT中偏移处的符号错误,还是PLT地址加上偏移量时的错误?此外,您自己的问答中的几页很短;)

– 0xC0000022L♦
13年5月6日13:02

我同意,我会改善我的问答。这个星期我有时间,所以我会解决这个问题。我知道我遗漏了很多东西(因为我没有时间)。抱歉...

–恐怖
13年5月6日14:16