简体   繁体   中英

GDB shows incorrect jump address at PLT section

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:

  1. You have LD_BIND_NOW set in the environment or
  2. 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

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM