首页 > 其他分享 >动态库如何被加载

动态库如何被加载

时间:2023-07-05 23:14:20浏览次数:44  
标签:00 动态 libA 如何 plt got main 加载

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表,key是STRTAB里面符号偏移地址, value是该符号在代码段里的起始地址

STRSZ是STRTAB的长度

我们反汇编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的加载偏移地址0x7ffff7bd9000,0x7ffff7bd96d5 - 0x7ffff7bd9000=0x6d5, 这就是func()函数在libA.so的文本段的地址

 

标签:00,动态,libA,如何,plt,got,main,加载
From: https://www.cnblogs.com/ho966/p/17530551.html

相关文章

  • 22-数码管的动态显示
    1.数码管动态显示不同位的数码管显示不同的数值使用动态扫描的方式,使用6位8段数码管显示1,2,3,4,5,6,选中第一个数码管让其显示1,显示时间位T;经过时间T之后选中第二个数码管显示2,显示时间为T,依次进行相似的操作,显示到6之后,经过时间T之后再显示1显示一个周期所有的时间为6个周......
  • 【干货向】我想试试教会你如何修改Git提交信息
    Git是目前IT行业使用率最高的版本控制系统,相信大家在日常工作中也经常使用,每次Git提交都会包含提交信息,常用的包括说明、提交人和提交时间等,此篇文章主要向大家介绍下如何修改这些信息,这些命令在正常使用时可能不常用,但还是建议收藏以备不时之需。新提交指定提交信息在使用git......
  • 进程概念、进程的并发和并行、同步异步阻塞非阻塞、开启进程Process类,属性,方法、如何
    进程概念#进程、线程都是操作系统中的基本概念,也就是说进程和线程都是操作系统层面的东西,专业术语表达就是进程和线程的使用都是有操作系统来调度的.而不时有我们程序员自己来操控的在操作系统这门课里面,进程和线程是操作系统的概念,协程不是操作系统中的概念,而是我们程序员层......
  • 学不会动态规划——背包篇
    前言终于把线性动态规划学完了,本蒟蒻要开始背包了,祝我好运吧!如果文章有任何问题,欢迎评论或者私信让我知道......
  • 5分钟学会img标签加载图片404错误解决方案
      在开发中,使用<imgsrc="/img/yys.png"/>加载图片时,会有404错误,也就是图片未找到问题。  现将解决办法 总结如下:  当图片未找到或者404时,就会触发<img/>标签的 onerror属性显示其中的图片。1、直接拼写路径方式:<imgsrc="img/yys.png"onerror="javascript......
  • 如何在qt中使用gdal?
    首先是使用MinGW编译的GDAL库,这种貌似比较少见。。可见大家都还是喜欢用vs来编译https://zhuanlan.zhihu.com/p/355864559参考:https://blog.csdn.net/qq_32629895/article/details/105738977(介绍一种简单的在QT(MinGW)中使用gdal的方法)......
  • 创新案例 | 校服行业 的隐形冠军:伊顿纪德如何在关系型销售为主的行业中通过三大策略成
    校服行业作为传统并且B端关系型销售为主的行业,尽管市场规模高达1200亿,但目前行业第一名销售额也只有10亿元,排名前十的校服企业总销售额不到50亿,行业集中度很低,那么在这样一个极度分散,又主要靠学校关系的市场,伊顿纪德是如何冲出重围,成为行业第一的呢?伊顿纪德主要的解决方案包括......
  • django中使用form表单或者ajax提交数据时如何验证csrftoken
    使用form表单来提交数据时,如何验证csrftokenajax提交数据时验证csrftoken在需要提交的html页面引入以下js文件就行引入csrf.js文件<scriptsrc="{%static'js/csrf.js'%}"></script>文件内容:/***根据cookie的name获取对应的值*@paramname*@returns{null}......
  • springboot 加载自定义的属性配置文件 或者xml文件
    1、properties user.propertiesname=zhangshanage=18  2、xml Pen1.xml<?xmlversion="1.0"encoding="utf-8"?><!DOCTYPEpropertiesSYSTEM"http://java.sun.com/dtd/properties.dtd"><properties><......
  • js如何动态清除form表单中input款下的错误信息
    form表单<formaction=""method="post"novalidateid="myform">{%csrf_token%}{%forforminform_obj%}<divclass="form-group"><labelfor="{{form.i......