Plt, got, pltgot
I recently learned about linux advanced debugging technology. The following is an experiment on dynamic library connection.
First, we understand that plt is procedure linkage table, and got is global offset table. The got table stores external symbol addresses. The plt table stores the function address. Next, let's take a look at the lab details.
Source code:
# Include <stdio. h>
Int fun ()
{
Printf ("hello world \ n ");
}
Int main ()
{
While (1 ){
Fun ();
}
Return 1;
}
Set a breakpoint at the beginning of the fun function. Start running the program
First, let's take a look at the disassembly code of the fun function:
First, let's take a look at the disassembly code of the fun function:
(Gdb) disassemble fun
Dump of javaser code for function fun:
0x080483d4 <+ 0>: push % ebp
0x080483d5 <+ 1>: mov % esp, % ebp
0x080483d7 <+ 3>: sub $0x18, % esp
0x080483da <+ 6>: movl $0x80484d0, (% esp)
0x080483e1 <+ 13>: call 0x80482f0 <puts @ plt>
0x080483e6 <+ 18>: leave
0x080483e7 <+ 19>: ret
End of worker er dump.
The assembly with the offset of 13 is to call printf. This can be viewed through the objdump-l and-S options.
View the Assembly at 0x80482f0
(Gdb) disassemble 0x80482f0
Dump of worker er code for function puts @ plt:
0x080482f0 <+ 0>: jmp * 0x804a000
0x080482f6 <+ 6>: push $0x0
0x080482fb <+ 11>: jmp 0x80482e0
End of worker er dump.
Check the content in 0x804a000.
Gdb) x/x 0x804a000
0x804a000 <puts@got.plt>: 0x080482f6
We can see that this is the next sentence of the previous disassembly code, but this is also an item in the plt table.
Check the disassembly of 0x80482e0,
(Gdb) disassemble 0x80482e0
No function contains specified address.
Set a breakpoint for viewing at this address. If you still cannot view the code, you can view the disassembly code in the memory.
(Gdb) x/10i 0x80482e0
0x80482e0: pushl 0x8049ff8
=> 0x80482e6: jmp * 0x8049ffc
Check the content in 0x8049ffc.
(Gdb) x/x 0x8049ffc
0x8049ffc <_ GLOBAL_OFFSET_TABLE _ + 8>: 0xb7ff2690
An item in the got table is found at 0xb7ff2690.
Check the disassembly code at 0xb7ff2690.
(Gdb) x/10i 0xb7ff2690
0xb7ff2690: push % eax
0xb7ff2691: push % ecx
0xb7ff2692: push % edx
0xb7ff2693: mov 0x10 (% esp), % edx
0xb7ff2697: mov 0xc (% esp), % eax
0xb7ff269b: call 0xb7fec1c0
Next, call the code at the 0xb7fec1c0 address. view the map information and you will find that both addresses are 0xb7fde820-0xb7ff6b9f is. text in/lib/ld-linux.so.2 code, but here due to restrictions, do not see the function name inside, on the Internet can be found is _ dl_runtime_resolve function.
When you run the fun function for the first time and then run the function for the second time, let's look at the disassembly code.
(Gdb) disassemble 0x80482f0
Dump of worker er code for function puts @ plt:
0x080482f0 <+ 0>: jmp * 0x804a000
0x080482f6 <+ 6>: push $0x0
0x080482fb <+ 11>: jmp 0x80482e0
This code hasn't changed, but check the address in 0x804a000.
(Gdb) x/x 0x804a000
0x804a000 <puts@got.plt>: 0xb7e866a0
This is different from the previous address. Previously, it jumped to 0x080482f6, And the printf address is actually entered here.
To sum up, if a dynamic library function is called for the first time, the address of this function does not exist in the plt table, this address is retrieved and stored in the got table. When this function is called for the second time, the address of this function is available in the plt table, which is directly redirected to this address without the need to retrieve the address, that is, dynamic links.