I wrote the following example to get a grasp of PLT/GOT section.
The shared library libshar
code:
shared.h
int sum(int a, int b);
shared.c
#include "shared.h"
int sum(int a, int b){
return a + b;
}
The executable bin_shared
code:
#include <stdio.h>
#include "shared.h"
int main(void){
printf("Starting the programm... \n");
int s = sum(1, 2); //<=== I expected the dynamic linker would be called here
int s2 = sum(2, 3);
printf("s = %d, s2 = %d\n", s, s2);
}
So I compiled and linked the shared library with the executable and wrote the following gdb-script to get into the dynamic linker code. I expected it to be executed on the first call to sum
.
set pagination off
file build/bin_shared
b main
commands
layout asm
info proc mappings
end
r
I faced the 2 problems:
I. When the breakpoint on the main
function entry was hit the info proc mappings
shows that libshar.so
was already mapped:
0x7ffff7bd3000 0x7ffff7bd4000 0x1000 0x0 /home/me/c/build/libshar.so
0x7ffff7bd4000 0x7ffff7dd3000 0x1ff000 0x1000 /home/me/c/build/libshar.so
0x7ffff7dd3000 0x7ffff7dd4000 0x1000 0x0 /home/me/c/build/libshar.so
0x7ffff7dd4000 0x7ffff7dd5000 0x1000 0x1000 /home/me/c/build/libshar.so
The sum
shared library function had not been called yet. Why was it loaded eagerly already?
II. When entering the sum@plt
for the first time I see the following asm:
0x555555554690 <sum@plt> jmp QWORD PTR [rip+0x200932] # 0x555555754fc8
This is the pointer to the GOT as expected:
(gdb) disassemble 0x555555754fc8
Dump of assembler code for function _GLOBAL_OFFSET_TABLE_:
But the problem is that single instruction stepping at this point gets gdb
right into the
0x7ffff7bd3580 <sum> lea eax,[rdi+rsi*1]
meaning that the pointer to the GOT was already overwritten with the actual function pointer, but gdb still shows the GOT pointer. Why is that?
I extracted the raw memory at the jmp
to GOT
address in hope of finding the overwritten address, but it does not seem like one:
(gdb) x/2xg 0x555555554690
0x555555554690 <sum@plt>: 0x01680020093225ff 0xffffffd0e9000000
Why was it loaded eagerly already?
Because the dynamic loader mmap
s all shared libraries that you directly link against.
If you want the shared library to be loaded on demand, you must use dlopen
instead of linking the binary with libshar.so
.
the pointer to the GOT was already overwritten with the actual function pointer, but gdb still shows the GOT pointer. Why is that?
One of two likely causes:
LD_BIND_NOW
set in the environment or-Wl,-z,now
(which could be the default on a newer Linux distribution).You can examine whether 2 above is true with:
readelf -d bin_shared | grep FLAGS
For a -z now
binary you would see:
0x000000000000001e (FLAGS) BIND_NOW
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.