什么是PLT/GOT?


50

有时,当分解x86二进制文件时,我偶然发现 参考PLTGOT,特别是从 动态库调用过程时。

例如,运行在gdb程序时:

(gdb) info file 
Symbols from "/home/user/hello". 
Local exec file: '/home/user/hello', file type elf64-x86-64. 
Entry point: 0x400400 
  0x0000000000400200 - 0x000000000040021c is .interp 
  0x000000000040021c - 0x000000000040023c is .note.ABI-tag 
  0x000000000040023c - 0x0000000000400260 is .note.gnu.build-id 
  0x0000000000400260 - 0x0000000000400284 is .hash 
  0x0000000000400288 - 0x00000000004002a4 is .gnu.hash 
  0x00000000004002a8 - 0x0000000000400308 is .dynsym 
  0x0000000000400308 - 0x0000000000400345 is .dynstr 
  0x0000000000400346 - 0x000000000040034e is .gnu.version 
  0x0000000000400350 - 0x0000000000400370 is .gnu.version_r 
  0x0000000000400370 - 0x0000000000400388 is .rela.dyn 
  0x0000000000400388 - 0x00000000004003b8 is .rela.plt 
  0x00000000004003b8 - 0x00000000004003c6 is .init 
=> 0x00000000004003d0 - 0x0000000000400400 is .plt 
  0x0000000000400400 - 0x00000000004005dc is .text 
  0x00000000004005dc - 0x00000000004005e5 is .fini 
  0x00000000004005e8 - 0x00000000004005fa is .rodata 
  0x00000000004005fc - 0x0000000000400630 is .eh_frame_hdr 
  0x0000000000400630 - 0x00000000004006f4 is .eh_frame 
  0x00000000006006f8 - 0x0000000000600700 is .init_array 
  0x0000000000600700 - 0x0000000000600708 is .fini_array 
  0x0000000000600708 - 0x0000000000600710 is .jcr 
  0x0000000000600710 - 0x00000000006008f0 is .dynamic 
=> 0x00000000006008f0 - 0x00000000006008f8 is .got 
=> 0x00000000006008f8 - 0x0000000000600920 is .got.plt 
  0x0000000000600920 - 0x0000000000600930 is .data 
  0x0000000000600930 - 0x0000000000600938 is .bss 

而且,然后拆卸时([email protected]):

(gdb) disas foo 
Dump of assembler code for function foo: 
  0x000000000040050c <+0>: push %rbp 
  0x000000000040050d <+1>: mov %rsp,%rbp 
  0x0000000000400510 <+4>: sub $0x10,%rsp 
  0x0000000000400514 <+8>: mov %edi,-0x4(%rbp) 
  0x0000000000400517 <+11>: mov$ 0x4005ec,%edi 
=> 0x000000000040051c <+16>: callq 0x4003e0 <[email protected]> 
  0x0000000000400521 <+21>: leaveq 
  0x0000000000400522 <+22>: retq 
End of assembler dump. 

那么,什么是这些GOT/PLT?

+5

我建议您阅读本书“链接器和装载器”,关于该主题的优秀书籍。手稿可在此免费获取:http://www.iecc.com/linker/ 05 5月. 132013-05-05 07:24:02

53

PLT代表程序链接表,简单地说,它被用来调用地址在链接时不知道的外部程序/函数,并在运行时由动态链接程序解决。

GOT代表Global Offsets Table,同样用于解析地址。 PLT和GOT以及其他重新安置信息在this article中有更详细的解释。

另外,伊恩·泰勒兰斯的GOLD笔者提出了在他的博客系列文章这是完全值得一读(配件!):入口点here "Linkers part 1"

+3

有没有更快的方法来阅读20个部分?为什么在第一部分和第二部分之间没有链接? 08 6月. 132013-06-08 20:31:09

  0

@ 0x90事实上,PLT和GOT直到这个精彩系列的第4部分才被提及,如果你只需要这些信息,请点击这里链接:http://www.airs.com/blog/archives/41。我会推荐阅读整件事,但这是一个非常棒的系列! 10 5月. 152015-05-10 11:00:27

+2

@ 0x90,因为他希望你编写一个链接器当然是 29 5月. 152015-05-29 14:58:43

  0

只是为了看看我是否理解这个权利:(1)GOT总是需要位置无关的代码来找到它的依赖关系。 (2)PLT是一种可选的机制来进行惰性绑定工作。 (3)即使有PLT,也可以“手动”调用GOT条目。 17 11月. 152015-11-17 10:13:00

+3

20篇博文的索引:http://a3f.at/lists/linkers 23 2月. 162016-02-23 07:47:46