跟着本文一起操作,你将明白ELF动态链接过程。
/*
* hello.c
*/
#include <stdio.h>
int main(void)
{
puts("Hello,world\n");
return 0;
}
gcc -c hello.c
gcc hello.c
root@jeff:~/hello# objdump -d ./hello.o
./hello.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: bf 00 00 00 00 mov $0x0,%edi
9: e8 00 00 00 00 callq e <main+0xe>
e: b8 00 00 00 00 mov $0x0,%eax
13: 5d pop %rbp
14: c3 retq
offset代表 .text中需要重定位的地方 000000000005 代表 bf指令之后要重定位。
info 中的a代表重定位的函数的符号名称(在.strtab中的偏移),对照一下下面的.strtab可以看到 a 正好对应着puts,意思就是把pus的函数地址填入.text段中的偏移 5 的位置.000a00000002中的2代表重定位类型
root@jeff:~/hello# readelf -p .strtab ./hello.o
String dump of section '.strtab':
[ 1] hello.c
[ 9] main
[ e] puts
root@jeff:/# readelf -x .got.plt ./a.out
Hex dump of section '.got.plt':
0x00601000 280e6000 00000000 00000000 00000000
0x00601010 00000000 00000000 06044000 00000000
0x00601020 16044000 00000000
小端数据转换:
地址 数据
0x00601000 : 0x00600e28
0x00601008 : 0x00000000
0x00601010 : 0x400406
(.got.glt保存全局函数,.got保存全局数据)
参考段:
root@jeff:~/hello# readelf -x .dynamic a.out
Hex dump of section '.dynamic':
0x00600e28 01000000 00000000 01000000 00000000
0x00600e38 0c000000 00000000 c8034000 00000000
0x00600e48 0d000000 00000000 b4054000 00000000
root@jeff:~/hello# readelf -l ./a.out
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
调试:
gdb ./a.out
(gdb) x/a 0x601018
0x601018: 0x400406 <puts@plt+6>
(gdb) x/a 0x601000
0x601000: 0x600e28
(got[0]保存.dynamic段的地址)
(gdb) x/a 0x601008
0x601008: 0x7ffff7ffe168
(got[1] 保存链接信息结构(没深究)
(gdb) x/a 0x601010
0x601010: 0x7ffff7deeee0 <_dl_runtime_resolve_xsavec>
/lib64/ld-linux-x86-64.so.2中
_dl_runtime_resolve_xsavec地址
(gdb) x/a 0x601020
0x601020: 0x7ffff7a2d740 <__libc_start_main>
(gdb) ni
0x000000000040052f in main ()
(gdb) ni
Hello,world
0x0000000000400534 in main ()
(gdb) x/a 0x601018
0x601018: 0x7ffff7a7c690 <_IO_puts>
(现在找到了真正的puts的地址存在got表中)
(gdb)
root@jeff:~# ps u -C a.out
USER PID STAT COMMAND
root 4569 t /root/hello/a.out
root@jeff:~# cat /proc/4569/maps
7ffff7a0d000-7ffff7bcd000 r-xp
/lib/x86_64-linux-gnu/libc-2.23.so
7ffff7dd7000-7ffff7dfd000 r-xp
/lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p
00000000 00:00 0