GDB在PLT部分显示了不正确的跳转地址 [英] GDB shows incorrect jump address at PLT section
问题描述
我写了以下示例以了解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指针.为什么会这样?
我从jmp
到GOT
地址提取了原始内存,希望找到被覆盖的地址,但是它看起来并不像这样:
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 mmap
s 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?
两个可能的原因之一:
- 您已在环境中设置
LD_BIND_NOW
或 - 您的二进制文件已与
-Wl,-z,now
链接(这可能是较新的Linux发行版中的默认设置).
- You have
LD_BIND_NOW
set in the environment or - 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屋!