GOT和PLT原理简析

2024-06-22 05:58
文章标签 原理 简析 got plt

本文主要是介绍GOT和PLT原理简析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

GOT(Global Offset Table)和PLT(Procedure Linkage Table)是Linux系统下面ELF格式的可执行文件中,用于定位全局变量和过程的数据信息。以C程序为例,一个程序可能会包含多个文件,可执行文件的生成过程通常由以下几步组成。

1. 编译器把每个.c文件编译成汇编(.s)文件。

2. 汇编器把每个(.s)文件转换为(.o)文件。

3. 链接器把多个.o文件链接为一个可执行文件(.out)。

.s文件是汇编文件的后缀,一般对此种类型文件的关注不多,不再讨论,重点在.o文件和.out文件。

.c文件中通常有对变量和过程的使用,若是变量和过程定义在当前文件中,则可以使用相对偏移寻址来调用。若是定义在其他文件中,则在编译当前文件时无法获取其地址;若是定义在动态库中,则直到程序被加载、运行时,才能够确定。本文通过《深入理解计算机系统》中讲动态链接一章中的例子,通过gdb的调试,研究调用动态库中函数时的重定位过程。

1. 动态库程序。

addvec.c

void addvec(int *x, int *y, int *z, int n){int i;for(i = 0; i < n; i++)z[i] = x[i] + y[i];
}
通过命令gcc -fPIC -shared addvec.c -o libvec.so可以把上面的程序转换为动态库libvec.so。
2. 调用动态库的主程序。

main.c

#include <stdio.h>int x[2] = {1, 2};
int y[2] = {3, 4};
int z[2];int main(){addvec(x, y, z, 2);printf("z = [%d %d]\n", z[0], z[1]);addvec(x, y, z, 2);printf("z = [%d %d]\n", z[0], z[1]);return 0;
}

通过命令gcc main.c -o main -L./ -lvec生成可执行文件main。-L./ -lvec表示链接当前目录下的动态链接库libvec.so。

使用命令objdump -d -s > main.dmp反汇编main。

反汇编生成的文件中,主要有三个段与对动态库函数addvec的调用有关:.got.plt,.plt和代码段.text。

代码段容易理解,就是程序语句所对应的指令组成的。.got.plt中保存的是数据,为每个动态调用保存一个条目,条目的内容应该是对动态库函数的调用所跳转到的目标地址。由于Linux采用了延迟绑定技术,可执行文件中got.plt中的地址并不是目标地址,而是动态链接器(ld-linux)中的地址。在程序执行的第一次调用时,ld-linux把.got.plt的地址填写正确,之后的调用,就可以使用.got.plt中的目标地址了。.plt段中的内容则是实现跳转操作的代码片段。

代码段:


.got.plt


.plt


源代码中,对于函数的addvec的两次调用,命令为

callq  400580 <addvec@plt>

调用的目标地址是.plt段中的addvec@plt函数。该函数由三条语句组成,其作用分别为:

1. 跳转到地址600af8,这个地址位于.got.plt中。从图中可以看到got.plt起始于600ad0,终止于600b08(600b00 + 8)。并且600af8的内容为86054000,按照小端的读法,其内容为00400586,实际就是下一条(第2条)指令。

2. 第二条指令把当前函数的id(0x2)压入栈中。

3. 第三条指令,跳转到400550,这之后的工作可以视为系统在运行时填充地址600af8的过程。也就是在延迟绑定机制下,第一次执行时,600af8的内容是400586,第二次及之后的内容就会修改为addvec函数的实际地址,可以通过gdb来验证。

可以看到,第一次调用addvec的时候,地址600af8中的内容是0x0000000000400586,第二次调用的时候就变成了0x00007ffff7bd95e5,是addvec的实际入口地址,与预期的相同。

这篇关于GOT和PLT原理简析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1083477

相关文章

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

TL-Tomcat中长连接的底层源码原理实现

长连接:浏览器告诉tomcat不要将请求关掉。  如果不是长连接,tomcat响应后会告诉浏览器把这个连接关掉。    tomcat中有一个缓冲区  如果发送大批量数据后 又不处理  那么会堆积缓冲区 后面的请求会越来越慢。

PHP原理之内存管理中难懂的几个点

PHP的内存管理, 分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理. 而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等. 另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法. 而在我们

Smarty模板执行原理

为了实现程序的业务逻辑和内容表现页面的分离从而提高开发速度,php 引入了模板引擎的概念,php 模板引擎里面最流行的可以说是smarty了,smarty因其功能强大而且速度快而被广大php web开发者所认可。本文将记录一下smarty模板引擎的工作执行原理,算是加深一下理解。 其实所有的模板引擎的工作原理是差不多的,无非就是在php程序里面用正则匹配将模板里面的标签替换为php代码从而将两者

Restful API 原理以及实现

先说说API 再说啥是RESRFUL API之前,咱先说说啥是API吧。API大家应该都知道吧,简称接口嘛。随着现在移动互联网的火爆,手机软件,也就是APP几乎快爆棚了。几乎任何一个网站或者应用都会出一款iOS或者Android APP,相比网页版的体验,APP确实各方面性能要好很多。 那么现在问题来了。比如QQ空间网站,如果我想获取一个用户发的说说列表。 QQ空间网站里面需要这个功能。

laravel框架实现redis分布式集群原理

在app/config/database.php中配置如下: 'redis' => array('cluster' => true,'default' => array('host' => '172.21.107.247','port' => 6379,),'redis1' => array('host' => '172.21.107.248','port' => 6379,),) 其中cl