ELF动态链接强操作

跟着本文一起操作,你将明白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   


ELF动态链接强操作


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


ELF动态链接强操作

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 


上一篇:再记一次 应用服务器 CPU 暴高事故分析


下一篇:位运算