GDB在PLT部分显示了不正确的跳转地址 [英] GDB shows incorrect jump address at PLT section

查看:134
本文介绍了GDB在PLT部分显示了不正确的跳转地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了以下示例以了解PLT/GOT部分.

I wrote the following example to get a grasp of PLT/GOT section.

共享库libshar代码:

shared.h

int sum(int a, int b);

shared.c

#include "shared.h"

int sum(int a, int b){
    return a + b;
}

可执行文件bin_shared代码:

#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);
}

因此,我编译了共享库并将其与可执行文件链接,并编写了以下gdb脚本以进入动态链接器代码.我希望它会在第一次调用sum时执行.

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. .当按下main函数条目上的断点时,info proc mappings显示libshar.so已经被映射:

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

尚未调用sum共享库函数.为什么已经热切加载了?

The sum shared library function had not been called yet. Why was it loaded eagerly already?

II. .第一次输入sum@plt时,我会看到以下asm:

II. When entering the sum@plt for the first time I see the following asm:

0x555555554690 <sum@plt>   jmp    QWORD PTR [rip+0x200932]        # 0x555555754fc8

这是预期的GOT指针:

This is the pointer to the GOT as expected:

(gdb) disassemble 0x555555754fc8
Dump of assembler code for function _GLOBAL_OFFSET_TABLE_:

但是问题在于,此时单指令步进将gdb正确地放入

But the problem is that single instruction stepping at this point gets gdb right into the

0x7ffff7bd3580 <sum>            lea    eax,[rdi+rsi*1]   

表示指向GOT的指针已被实际的函数指针覆盖,但是gdb仍显示GOT指针.为什么会这样?

我从jmpGOT地址提取了原始内存,希望找到被覆盖的地址,但是它看起来并不像这样:

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?

因为动态加载程序mmap all 您直接链接到的共享库.

Because the dynamic loader mmaps all shared libraries that you directly link against.

如果要按需加载共享库,则必须使用dlopen而不是将二进制文件与libshar.so链接.

If you want the shared library to be loaded on demand, you must use dlopen instead of linking the binary with libshar.so.

指向GOT的指针已被实际的函数指针覆盖,但是gdb仍显示GOT指针.为什么会这样?

the pointer to the GOT was already overwritten with the actual function pointer, but gdb still shows the GOT pointer. Why is that?

两个可能的原因之一:

  1. 您已在环境中设置LD_BIND_NOW
  2. 您的二进制文件已与-Wl,-z,now链接(这可能是较新的Linux发行版中的默认设置).
  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).

您可以使用以下方法检查上述2是否正确:

You can examine whether 2 above is true with:

readelf -d bin_shared | grep FLAGS

对于-z now二进制文件,您将看到:

For a -z now binary you would see:

  0x000000000000001e (FLAGS)              BIND_NOW

这篇关于GDB在PLT部分显示了不正确的跳转地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆