Som*_*ame 4 c linux assembly gdb shared-libraries
我编写了以下示例来了解 PLT/GOT 部分。
共享库libshar代码:
shared.h
int sum(int a, int b);
Run Code Online (Sandbox Code Playgroud)
shared.c
#include "shared.h"
int sum(int a, int b){
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
可执行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);
}
Run Code Online (Sandbox Code Playgroud)
因此,我编译了共享库并将其与可执行文件链接,并编写了以下 gdb 脚本来进入动态链接器代码。我预计它会在第一次调用时执行sum。
set pagination off
file build/bin_shared
b main
commands
layout asm
info proc mappings
end
r
Run Code Online (Sandbox Code Playgroud)
我遇到了两个问题:
I.当函数入口处的断点main被击中info proc mappings,显示libshar.so已经映射的:
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
Run Code Online (Sandbox Code Playgroud)
共享库函数sum尚未被调用。为什么它已经急切地加载了?
二. sum@plt第一次进入时,
0x555555554690 <sum@plt> jmp QWORD PTR [rip+0x200932] # 0x555555754fc8
Run Code Online (Sandbox Code Playgroud)
这是预期的指向 GOT 的指针:
(gdb) disassemble 0x555555754fc8
Dump of assembler code for function _GLOBAL_OFFSET_TABLE_:
Run Code Online (Sandbox Code Playgroud)
但问题是单步指令此时gdb直接进入
0x7ffff7bd3580 <sum> lea eax,[rdi+rsi*1]
Run Code Online (Sandbox Code Playgroud)
这意味着指向 GOT 的指针已经被实际的函数指针覆盖,但 gdb 仍然显示 GOT 指针。这是为什么?
jmp我提取了to地址处的原始内存,GOT希望找到被覆盖的地址,但它看起来不像:
(gdb) x/2xg 0x555555554690
0x555555554690 <sum@plt>: 0x01680020093225ff 0xffffffd0e9000000
Run Code Online (Sandbox Code Playgroud)
为什么它已经急切地加载了?
因为动态加载器mmap是您直接链接的所有共享库。
如果您希望按需加载共享库,dlopen则必须使用libshar.so.
指向 GOT 的指针已经被实际的函数指针覆盖,但 gdb 仍然显示 GOT 指针。这是为什么?
两个可能的原因之一:
LD_BIND_NOW在环境中设置或-Wl,-z,now(这可能是较新的 Linux 发行版上的默认设置)。您可以通过以下方式检查上述 2 是否正确:
readelf -d bin_shared | grep FLAGS
Run Code Online (Sandbox Code Playgroud)
对于-z now二进制文件,您将看到:
0x000000000000001e (FLAGS) BIND_NOW
Run Code Online (Sandbox Code Playgroud)