.plt .plt.got 有什么不同?
.plt .plt.got what is different?
.plt
:在 RE able 段中,在 plt[n]
处有蹦床功能,除了 0,在 plt[0]
[=22 处有 .got.plt 解析器 link =]
.got
.got.plt
: 在可读段中,地址
我从中学到的post:
https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
问题
实际 Linux shell 命令给了我不同的答案
$readelf -l /bin/bash
got.plt 不见了,02 段中的 .plt.got 是什么?
我转储了两个部分(plt,plt.got)并得到了这个程序集
.plt 是我了解到的 plt:
.plt.got ,这是干嘛的?
抱歉倾倒不当,这是由
完成的
objcopy -O binary --only-section=.plt.got /bin/bash ./pltgot
objcopy -O binary --only-section=.plt /bin/bash ./plt
问题
- .plt 和 .plt.got
有什么区别
- 为什么会出现这种差异?
查看问题的答案。希望对你有帮助。
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). To enable RELRO, you use the ld option -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
作为ELF通用标准文件格式的一部分,这种设计的不同之处在于:
ELF binaries often contain a separate GOT section called .got.plt for use in conjunction with .plt in the lazy binding process
Q1 参考页 45: Andriesse,Dennis.Practical 二进制分析:构建您自己的 Linux 工具二元仪器、分析和 disassembly.San Francisco,No Starch Press,2019
Q2 参考页 45:同一本书,请参阅第 "Lazy Binding and the PLT"
.plt
和.plt.got
的区别在于.plt
使用延迟绑定而.plt.got
使用非延迟绑定。
当一个函数的所有使用都是简单的函数调用时,延迟绑定是可能的。然而,如果任何东西需要函数的地址,那么必须使用非惰性绑定,因为绑定只能在函数被调用时发生,我们可能需要在第一次调用之前知道地址。注意,获取地址时,直接访问GOT表项;只有函数调用通过 .plt
和 .plt.got
。
如果使用 -fno-plt
编译器选项,则不会发出 .plt
和 .plt.got
,并且函数调用也直接访问 GOT 条目。
在下面的例子中,objdump -d
用于反汇编,readelf -r
用于列出重定位。
.plt
以 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 [=10=]x2
1405b: e9 c0 ff ff ff jmpq 14020 <.plt>
第一个jmpq
是GOT条目,第二个jmpq
如果GOT条目还没有绑定则执行惰性绑定。
.plt
的关联 GOT 条目的重定位在 .rela.plt
部分并使用 R_X86_64_JUMP_SLOT
,这让动态链接器知道这些是惰性的。
0000000000102690 0000004600000007 R_X86_64_JUMP_SLOT 0000000000000000 _Unwind_Resume@GCC_3.0 + 0
.plt.got
.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
.plt.got
的关联 GOT 条目的重定位在 .rela.dyn
部分(连同其余的 GOT 重定位),动态链接器立即绑定:
0000000000102ac0 0000004b00000006 R_X86_64_GLOB_DAT 0000000000000000 memset@GLIBC_2.2.5 + 0
.plt
:在 RE able 段中,在 plt[n]
处有蹦床功能,除了 0,在 plt[0]
[=22 处有 .got.plt 解析器 link =]
.got
.got.plt
: 在可读段中,地址
我从中学到的post: https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
问题
实际 Linux shell 命令给了我不同的答案
$readelf -l /bin/bash
got.plt 不见了,02 段中的 .plt.got 是什么?
我转储了两个部分(plt,plt.got)并得到了这个程序集
.plt 是我了解到的 plt:
.plt.got ,这是干嘛的?
抱歉倾倒不当,这是由
完成的objcopy -O binary --only-section=.plt.got /bin/bash ./pltgot
objcopy -O binary --only-section=.plt /bin/bash ./plt
问题
- .plt 和 .plt.got 有什么区别
- 为什么会出现这种差异?
查看问题的答案。希望对你有帮助。
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). To enable RELRO, you use the ld option -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
作为ELF通用标准文件格式的一部分,这种设计的不同之处在于:
ELF binaries often contain a separate GOT section called .got.plt for use in conjunction with .plt in the lazy binding process
Q1 参考页 45: Andriesse,Dennis.Practical 二进制分析:构建您自己的 Linux 工具二元仪器、分析和 disassembly.San Francisco,No Starch Press,2019
Q2 参考页 45:同一本书,请参阅第 "Lazy Binding and the PLT"
.plt
和.plt.got
的区别在于.plt
使用延迟绑定而.plt.got
使用非延迟绑定。
当一个函数的所有使用都是简单的函数调用时,延迟绑定是可能的。然而,如果任何东西需要函数的地址,那么必须使用非惰性绑定,因为绑定只能在函数被调用时发生,我们可能需要在第一次调用之前知道地址。注意,获取地址时,直接访问GOT表项;只有函数调用通过 .plt
和 .plt.got
。
如果使用 -fno-plt
编译器选项,则不会发出 .plt
和 .plt.got
,并且函数调用也直接访问 GOT 条目。
在下面的例子中,objdump -d
用于反汇编,readelf -r
用于列出重定位。
.plt
以 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 [=10=]x2
1405b: e9 c0 ff ff ff jmpq 14020 <.plt>
第一个jmpq
是GOT条目,第二个jmpq
如果GOT条目还没有绑定则执行惰性绑定。
.plt
的关联 GOT 条目的重定位在 .rela.plt
部分并使用 R_X86_64_JUMP_SLOT
,这让动态链接器知道这些是惰性的。
0000000000102690 0000004600000007 R_X86_64_JUMP_SLOT 0000000000000000 _Unwind_Resume@GCC_3.0 + 0
.plt.got
.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
.plt.got
的关联 GOT 条目的重定位在 .rela.dyn
部分(连同其余的 GOT 重定位),动态链接器立即绑定:
0000000000102ac0 0000004b00000006 R_X86_64_GLOB_DAT 0000000000000000 memset@GLIBC_2.2.5 + 0