.plt
: in RE able segment, have trampoline functioning at plt[n]
except 0, have .got.plt resolver link at plt[0]
.got
.got.plt
: in RW able segment, just address
Which I learned from this post: https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/
Actual Linux shell command gave me a different answer
$readelf -l /bin/bash
I dumped two section(plt, plt.got) and got this assembly
.plt is plt as i learned:
.plt.got , what is this for?
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
PLT and GOT are part of the linux ELF file format that is used for linux executable. Programming starts with having a clever idea, and writing source code in a programming language of your choice, for example C, and saving the source code in a file.
The PLT entry for a function usually contains a jump to a Global Offset Table (GOT) entry. This entry will first reference some code to load the actual function address into the GOT, and contain the actual function address after the first call (lazy binding).
Dynamically linked binaries (usually) resolve external function calls lazily through what's called the Procedure Linkage Table (PLT). The PLT holds an entry for each external function reference. When the function, say printf, is first called, it jumps to a known offset within the PLT corresponding to that function.
– gdb. Mar 29, 2011 at 8:32. 3. It's the procedure linkage table.
The difference between .plt
and .plt.got
is that .plt
uses lazy binding and .plt.got
uses non-lazy binding.
Lazy binding is possible when all uses of a function are simple function calls. 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. Note that when obtaining the address, the GOT entry is accessed directly; only the function calls go via .plt
and .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.
In the following examples, objdump -d
is used for disassembly, and readelf -r
is used to list relocations.
.plt
Using x64-64 as an example, .plt
will contain entries such as:
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.
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.
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:
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:
0000000000102ac0 0000004b00000006 R_X86_64_GLOB_DAT 0000000000000000 memset@GLIBC_2.2.5 + 0
See answer to your questions. Hopefully it helps you.
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
The difference or this design rather has been there as part of the ELF common standard file format:
ELF binaries often contain a separate GOT section called .got.plt for use in conjunction with .plt in the lazy binding process
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
Q2 Ref Page 45: same book, see section "Lazy Binding and the PLT"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With