首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.plt .plt.got有什么不同?

.plt .plt.got有什么不同?
EN

Stack Overflow用户
提问于 2019-09-24 08:54:15
回答 2查看 3.3K关注 0票数 8

.plt:在resolver段中,除了0之外,还有蹦床在plt[n]上工作,在plt[0]上有.got.plt解析器链接。

.got .got.plt:在RW段中,只需地址

我从这篇文章中学到的:https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/

问题

实际的Linux shell命令给了我一个不同的答案。

代码语言:javascript
复制
$readelf -l /bin/bash

got.plt已经走了,.plt.got在02段是什么?

我抛弃了两个部分(plt,plt.got),得到了这个程序集。

据我所知,.plt是plt:

.plt.got,这是干什么用的?

对不起倾销不当,这是由

代码语言:javascript
复制
objcopy -O binary --only-section=.plt.got /bin/bash ./pltgot
objcopy -O binary --only-section=.plt /bin/bash ./plt

问题

  1. .plt和.plt.got
  2. 之间有什么区别,为什么会发生这种差异?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-11 09:47:08

.plt.plt.got的区别在于,.plt使用惰性绑定,而.plt.got使用非惰性绑定。

当函数的所有使用都是简单的函数调用时,延迟绑定是可能的。但是,如果需要函数的地址,则必须使用非延迟绑定,因为绑定只能在调用函数时发生,而且我们可能需要在第一次调用之前知道地址。注意,在获取地址时,将直接访问GOT条目;只有函数调用通过.plt.plt.got进行。如果使用-fno-plt编译器选项,则不会发出.plt.plt.got,函数调用也直接访问GOT条目。

在下面的示例中,objdump -d用于反汇编,readelf -r用于列出重定位。

.plt

以x64-64为例,.plt将包含如下条目:

代码语言:javascript
复制
0000000000014050 <_Unwind_Resume@plt>:
   14050:       ff 25 3a e6 0e 00       jmpq   *0xee63a(%rip)        # 102690 <_Unwind_Resume@GCC_3.0>
   14056:       68 02 00 00 00          pushq  $0x2
   1405b:       e9 c0 ff ff ff          jmpq   14020 <.plt>

第一个jmpq指向GOT条目,而第二个jmpq执行延迟绑定(如果GOT条目尚未绑定)。

.plt相关的GOT条目的重定位位于.rela.plt部分并使用R_X86_64_JUMP_SLOT,这让动态链接器知道这些条目是懒惰的。

代码语言:javascript
复制
0000000000102690  0000004600000007 R_X86_64_JUMP_SLOT     0000000000000000 _Unwind_Resume@GCC_3.0 + 0

.plt.got

.plt.got包含只需要一个jmpq的条目,因为它们并不懒惰:

代码语言:javascript
复制
0000000000014060 <memset@plt>:
   14060:       ff 25 5a ea 0e 00       jmpq   *0xeea5a(%rip)        # 102ac0 <memset@GLIBC_2.2.5>
   14066:       66 90                   xchg   %ax,%ax

.plt.got关联的GOT条目的重定位位于.rela.dyn部分(以及其余的GOT重定位部分),动态链接器立即绑定该部分:

代码语言:javascript
复制
0000000000102ac0  0000004b00000006 R_X86_64_GLOB_DAT      0000000000000000 memset@GLIBC_2.2.5 + 0
票数 10
EN

Stack Overflow用户

发布于 2019-12-31 01:47:53

见你问题的答案。希望它能帮到你。

  1. 区别在于,.got.plt是可运行时可写的,而.got则不是,如果您启用了防御被称为RELRO (仅重定位只读)的覆盖攻击。要启用RELRO,可以使用ld选项-z relro。RELRO位置的条目必须是运行时可写的,以便在.got.plt中进行延迟绑定,以及在只读.got部分(

)中的所有其他条目。

作为ELF通用标准文件格式的一部分,

  1. 差异或此设计是存在的:

精灵二进制文件通常包含一个单独的GOT部分,名为.got.plt,以便在延迟绑定过程中与.plt一起使用。

Q1参考页45: Andriesse,Dennis.Practical二进制分析:为二进制测试、分析和disassembly.San Francisco构建自己的Linux工具,No淀粉出版社,2019年

Q2参考页45:同一本书,见“懒散装订与PLT”一节。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58076539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档