问题
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
回答1:
Why was it loaded eagerly already?
Because the dynamic loader mmaps 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:
- You have
LD_BIND_NOWset in the environment or - Your binary was linked with
-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
来源:https://stackoverflow.com/questions/58011661/gdb-shows-incorrect-jump-address-at-plt-section