简体   繁体   English

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

[英].plt .plt.got what is different?

.plt : in RE able segment, have trampoline functioning at plt[n] except 0, have.got.plt resolver link at plt[0] .plt :在 RE 能段中,除 0 外,在plt[n]处具有蹦床功能,在plt[0]处具有.got.plt 解析器链接

.got .got.plt : in RW able segment, just address .got .got.plt :在 RW 段中,只是地址

Which I learned from this post: https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/我从这篇文章中了解到: https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/

Problem问题

Actual Linux shell command gave me a different answer实际的 Linux shell 命令给了我不同的答案

$readelf -l /bin/bash

读取 elf -l 结果

got.plt is gone and what is.plt.got in 02 segment? got.plt 消失了,02 段中的 is.plt.got 是什么?

I dumped two section(plt, plt.got) and got this assembly我倾倒了两个部分(plt,plt.got)并得到了这个程序集

.plt is plt as i learned: .plt 是 plt 我了解到的:.plt 是我了解到的 plt

.plt.got, what is this for? .plt.got,这是干什么用的?.plt.got ,这是为了什么

sorry for poor dumping, it was done by很抱歉倾销不好,它是由

objcopy -O binary --only-section=.plt.got /bin/bash ./pltgot
objcopy -O binary --only-section=.plt /bin/bash ./plt

Questions问题

  1. what is difference between.plt and.plt.got .plt 和.plt.got 有什么区别
  2. why this difference happened?为什么会发生这种差异?

See answer to your questions.查看您的问题的答案。 Hopefully it helps you.希望它可以帮助你。

  1. The difference is that.got.plt is runtime-writable, while.got is not if you enable a defense against GOT overwriting attacks called RELRO (relocations read-only).不同之处在于.got.plt 是运行时可写的,而.got 不是如果您启用了针对称为RELRO 的GOT 覆盖攻击的防御(重定位只读)。 To enable RELRO, you use the ld option -z relro.要启用 RELRO,请使用 ld 选项 -z relro。 RELRO places GOT entries that must be runtime-writable for lazy binding in.got.plt, and all others in the read-only.got section RELRO 将惰性绑定必须是运行时可写的 GOT 条目放在.got.plt 中,所有其他条目放在 read-only.got 部分

  2. The difference or this design rather has been there as part of the ELF common standard file format:作为 ELF 通用标准文件格式的一部分,差异或这种设计已经存在:

    ELF binaries often contain a separate GOT section called.got.plt for use in conjunction with.plt in the lazy binding process ELF 二进制文件通常包含一个名为 .got.plt 的单独 GOT 部分,用于在惰性绑定过程中与 .plt 一起使用

Q1 Ref Page 45: Andriesse, Dennis.Practical binary analysis: build your own Linux tools for binary instrumentation, analysis, and disassembly.San Francisco, No Starch Press, 2019 Q1 参考第 45 页: Andriesse,Dennis。实用二进制分析:构建您自己的 Linux 工具,用于二进制检测、分析和反汇编。旧金山,No Starch Press,2019

Q2 Ref Page 45 : same book, see section "Lazy Binding and the PLT" Q2 参考第 45 页:同一本书,请参阅“惰性绑定和 PLT”部分

The difference between .plt and .plt.got is that .plt uses lazy binding and .plt.got uses non-lazy binding. .plt.plt.got的区别在于.plt使用惰性绑定,而.plt.got使用非惰性绑定。

Lazy binding is possible when all uses of a function are simple function calls.当 function 的所有使用都是简单的 function 调用时,延迟绑定是可能的。 However, if anything requires the address of the function, then non-lazy binding must be used, since binding can only occur when the function is called, and we may need to know the address before the first call.但是,如果需要 function 的地址,则必须使用非惰性绑定,因为绑定只能在调用 function 时发生,并且我们可能需要在第一次调用之前知道地址。 Note that when obtaining the address, the GOT entry is accessed directly;注意获取地址时直接访问GOT入口; only the function calls go via .plt and .plt.got .只有 function 通过.plt和 .plt.got 调用.plt.got If the -fno-plt compiler option is used, then neither .plt nor .plt.got are emitted, and function calls also directly access the GOT entry.如果使用-fno-plt编译器选项,则不会发出.plt.plt.got ,并且 function 调用也直接访问 GOT 条目。

In the following examples, objdump -d is used for disassembly, and readelf -r is used to list relocations.在以下示例中, objdump -d用于反汇编,而readelf -r用于列出重定位。

.plt

Using x64-64 as an example, .plt will contain entries such as:以 x64-64 为例, .plt将包含以下条目:

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>

The first jmpq is to the GOT entry, and the second jmpq performs the lazy binding if the GOT entry hasn't been bound yet.第一个jmpq指向 GOT 条目,如果 GOT 条目尚未绑定,则第二个jmpq执行延迟绑定。

The relocations for .plt 's associated GOT entries are in the .rela.plt section and use R_X86_64_JUMP_SLOT , which lets the dynamic linker know these are lazy. .plt相关 GOT 条目的重定位位于.rela.plt部分并使用R_X86_64_JUMP_SLOT ,这让动态 linker 知道这些是惰性的。

0000000000102690  0000004600000007 R_X86_64_JUMP_SLOT     0000000000000000 _Unwind_Resume@GCC_3.0 + 0

.plt.got

.plt.got contains entries that only need a single jmpq since they aren't lazy: .plt.got包含只需要一个jmpq的条目,因为它们不是惰性的:

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

The relocations for .plt.got 's associated GOT entries are in the .rela.dyn section (along with the rest of the GOT relocations), which the dynamic linker binds immediately: .plt.got的相关 GOT 条目的重定位位于.rela.dyn部分(连同 GOT 重定位的 rest),动态 linker 立即绑定:

0000000000102ac0  0000004b00000006 R_X86_64_GLOB_DAT      0000000000000000 memset@GLIBC_2.2.5 + 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM