【PWN基础】动态链接和延迟绑定

动态链接和延迟绑定

静态链接

在链接时,将生成的目标文件.o 和需要引用的库文件一起打包到可执行文件中。

此时静态库可以理解为一组目标文件的集合,即很多目标文件压缩打包后形成的文件。

静态链接的特点:

  1. 程序运行时与函数库没有关系了,移植性更好
  2. 资源冗余
  3. 在编译的时候就发生了

动态链接

静态库的空间浪费是一个严重的问题。

clip_image021

程序1和2在静态编译时包含了同样的库函数,但其实不必让每个程序都包含外部连接库,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例即可。

动态库的程序在程序运行时才会被载入,规避了空间浪费的问题。

延迟绑定

提出延迟绑定的概念,是因为:动态链接太慢了。

动态链接比静态链接要慢1%~5%, 原因是:动态链接的工作在运行时完成,每次程序开始运行,动态链接器都要进行一次链接工作,而大量的重定位等复杂操作减慢了启动速度。(所谓链接工作,本质上是找到函数的地址)

为了解决这个问题,延迟绑定被提出。

延迟绑定:函数第一次被用到时,再进行绑定。

ELF使用 PLT(Procedure Linkage Table,过程链接表)技术来实现延迟绑定。

延迟绑定的实现

大方向

引入GOT表 和 PLT表两个核心概念。

首先需要了解的是:当调用外部函数时,如果是第一次调用该函数,会调用链接器,来解析该外部函数的地址,并填入got表中,再跳转到该函数。后续调用该函数,就直接从got表获取地址跳转。

1564557018894

.got

GOT(Global Offset Table,全局偏移表),保存所有外部符号的地址信息。(为全局变量,外部函数等保存地址信息)。

(个人理解:对于变量AAA,使用者借助于GOT表,找到其真实地址)

1564556164123

GOT表除了保存映射信息以外,还保存三个基本信息:

  1. got[0] :本ELF .dynamic 段的装载地址
  2. got[1] :ELF link_map 数据结构描述符的地址
  3. got[2] :_dl_runtime_resolve 函数的地址

这三个基本信息的用途,是帮助我们找到符号的真实地址。