动态库如何被加载

linux的可执行文件都是ELF格式,它肯定是会有个section.interp, 这里面保存的是动态链接器的路径。

 

 

我们在执行这个ELF格式的可执行文件时,内核会先根据.interp节找到动态链接器,然后把控制权交给动态链接器,由动态链接器去加载依赖的动态库。

1、链接器如何找到依赖的动态库

搞一个简单的小程序

A.cpp生成动态库libA.so

#include <stdio.h>
void func()
{
    printf("this is libA funcC\n");
}

g++ -fpic -shared A.cpp -o libA.so

 main.cpp生成可执行文件main

#include <stdio.h>
extern void func();
int main()
{
    func();
    return 0;
}

g++ main.cpp -o main -L./ -lA -Wl,-rpath=./

main文件里有个.dynamic的节,这里就包含了它依赖的动态库信息,我们反汇编看看,执行objdump -j .dynamic -S main,得到如下图1

通过readelf -d main可以更直观的查看,得到如下图2

 

1中第一行是600dd8: 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00

2中第一行是0x0000000000000001 (NEEDED)   共享库:[libA.so]

下面分析下怎么从图1得到图2的:

1中第一个字节01表示类型,这里类型是NEEDED,就是依赖的动态库, 0x01表示动态库名称的偏移地址,要在string table里查找,string stable就是一个存放所有符号字符串的地方,即图2中的STRTAB

2中有以下四行

 0x000000006ffffef5 (GNU_HASH)           0x400298

 0x0000000000000005 (STRTAB)             0x4003a8

 0x0000000000000006 (SYMTAB)             0x4002d0

 0x000000000000000a (STRSZ)              151 (bytes)

GNU_HASH 是一个hash table, key是符号名称,value是该符号在符号表即SYMTAB里的索引

STRTAB就是存放符号字符串名称的数组

SYMTAB是符号表,是一个key-value表,keySTRTAB里面符号偏移地址, value是该符号在代码段里的起始地址

STRSZSTRTAB的长度

我们反汇编0X01+0X4003a8 0X01+0X4003A8+151的字符串,

objdump -s --start-address=0X4003a9 --stop-address=0X40043f main

得到如下图,里面正是所依赖的动态库libA.so名称

 

当动态链接器看到libA.so这些依赖的动态库名称后,就会去找这些动态库加载,寻找的路径优先级依次是:

1) rpath

2) LD_LIBRARY_PATH环境变量目录

3) /etc/ld.so.conf配置路径

4) /lib  /usr/lib

2、外部函数如何被调用

先介绍三个section

.got ---- (Global Offset Table)全局偏移表,链接器将外部符号存在这里

.got.plt ---- 这是got专门为plt准备的节,可当做是got的一部分,它包含plt表所需的地址

.plt ---- (Procedure Linkage Table)程序链接表,它里面都是关于每个外部函数的一小段代码,就是去.got.plt查找外部函数地址

在可执行文件main中,并不知道外部声明的函数func()的真实地址,就使用func()&plt代替,

 

再看看func()&plt有啥

 

 

0x601028.got.plt里的地址, .plt.got.plt一一对应

执行objdump -j .got.plt -S main

记住这里0x601028的数据。

我们执行gdb ./main,gdb看下运行时这里是啥,

变成了一个虚拟内存地址,

执行i proc mapping 找到libA.so的加载偏移地址0x7ffff7bd90000x7ffff7bd96d5 - 0x7ffff7bd9000=0x6d5, 这就是func()函数在libA.so的文本段的地址

 

posted @ 2023-07-05 22:56  ho966  阅读(132)  评论(0编辑  收藏  举报