浅谈GOT表与PLT表
文章目录
- 浅谈GOT表与PLT表
- 1. 实例
- 2. PLT表
- 3. 动态解析
- 4. 总结
浅谈GOT表与PLT表
我们都知道动态链接库是我们程序开发中比较基础的手段,我们将公共的函数封装在一个so库中,即可用减少主程序的大小,也能增加公共代码的复用度。
那么对于一个共享库中的导出变量和函数的使用,是怎么引用和解析的呢?这里就是我们所说的GOT和PLT表的作用,下面我们详细来看一下基本流程和原理。
1. 实例
下面我们从一个最熟悉的例子除非,来讲述相关知识点,例子如下:
#include <stdio.h>int main(int argc, char* argv[])
{printf("hello world.\n");return 0;
}
然后我们需要对这个代码进行编译如下:
$ gcc -g -z lazy elf.c -o elf.o
这里有个非常重要的参数是必须添加的,那就是-z lazy
,需要延迟加载动态库函数,不然我们的调试就看不到效果了(可执行文件加载的时候就已经解析完了共享库函数了)。
2. PLT表
PLT表是过程链接表(Procedure Linkage Table,PLT),这个表的存在就是为了使得代码能够方便的访问共享的函数或者变量,每一个引用的共享函数在PTL表中都会存在一个条目,我们可用看一下程序对PLT的使用,如下:
f$ objdump -d elf.oelf.o: file format elf64-x86-640000000000000510 <puts@plt>:510: ff 25 02 0b 20 00 jmpq *0x200b02(%rip) # 201018 <puts@GLIBC_2.2.5>516: 68 00 00 00 00 pushq $0x051b: e9 e0 ff ff ff jmpq 500 <.plt>000000000000063a <main>:63a: 55 push %rbp63b: 48 89 e5 mov %rsp,%rbp63e: 48 83 ec 10 sub $0x10,%rsp642: 89 7d fc mov %edi,-0x4(%rbp)645: 48 89 75 f0 mov %rsi,-0x10(%rbp)649: 48 8d 3d 94 00 00 00 lea 0x94(%rip),%rdi # 6e4 <_IO_stdin_used+0x4>650: e8 bb fe ff ff callq 510 <puts@plt>655: b8 00 00 00 00 mov $0x0,%eax65a: c9 leaveq65b: c3 retq65c: 0f 1f 40 00 nopl 0x0(%rax)
我们可用看到callq 510 <puts@plt>
这一条汇编代码,对应的源码就是:
printf("hello world.\n");
也就是说的可执行文件中,并没有对导出函数puts
直接进行调用,而是通过一个打桩函数puts@plt
完成对puts
的真实引用,这样就可用做到不用修改任何可执行的代码就可以对动态库已经装载。
3. 动态解析
我们先来看一下动态解析的流程图:
基本流程如下:
- 主程序调用打桩函数
puts@plt
。 puts@plt
代码如下(其中jmpq *0x200b02(%rip) # 0x8201018
这一条语句跳转到GOT表中):
(gdb) disassemble 0x8000510
Dump of assembler code for function puts@plt:0x0000000008000510 <+0>: jmpq *0x200b02(%rip) # 0x82010180x0000000008000516 <+6>: pushq $0x00x000000000800051b <+11>: jmpq 0x8000500
0x8201018
是GOT中的一项,值为0x0000000008000516
,也就是jmpq *0x200b02(%rip)
下一条语句的地址。jmpq 0x8000500
这一条语句跳转到真实的动态解析过程,这个语句代码如下(这个小代码中主要是jmpq *0x200b04(%rip)
跳转语句):
(gdb) x /5i 0x80005000x8000500: pushq 0x200b02(%rip) # 0x82010080x8000506: jmpq *0x200b04(%rip) # 0x82010100x800050c: nopl 0x0(%rax)0x8000510 <puts@plt>: jmpq *0x200b02(%rip) # 0x82010180x8000516 <puts@plt+6>: pushq $0x0
jmpq *0x200b04(%rip) # 0x8201010
调用的GOT表中的动态解析函数_dl_runtime_resolve_xsavec
。_dl_runtime_resolve_xsavec
有两处功能:- 修改GOT表的条目(为了解决不需要每次都动态解析)。
- 跳转到
_IO_puts
执行动态库函数。
当动态解析完成之后,整个调用关系如下:
过程如下:
(gdb) x /3i 0x80006500x8000650 <main+22>: callq 0x8000510 <puts@plt>0x8000655 <main+27>: mov $0x0,%eax0x800065a <main+32>: leaveq(gdb) x /3i 0x80005100x8000510 <puts@plt>: jmpq *0x200b02(%rip) # 0x82010180x8000516 <puts@plt+6>: pushq $0x00x800051b <puts@plt+11>: jmpq 0x8000500(gdb) x /1xg 0x8201018
0x8201018: 0x00007fffff080aa0(gdb) x /5i 0x00007fffff080aa00x7fffff080aa0 <_IO_puts>: push %r130x7fffff080aa2 <_IO_puts+2>: push %r120x7fffff080aa4 <_IO_puts+4>: mov %rdi,%r120x7fffff080aa7 <_IO_puts+7>: push %rbp0x7fffff080aa8 <_IO_puts+8>: push %rbx
4. 总结
下面我们用一个图总结一项可执行文件调用共享库函数的整个调用过程,如下:
浅谈GOT表与PLT表相关推荐
- 浅谈Android Contacts数据库phone_lookup表的设计
转载注明出处:https://blog.csdn.net/skysukai 在Android系统中,联系人数据库是一个比较大的数据库.一次在浏览contact2.db的时候发现,phone_looku ...
- GOT表和PLT表知识详解
作者:海枫 链接:https://www.zhihu.com/question/21249496/answer/126600437 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...
- 支付宝的数据库是MySQL变种_浅谈MySql的储存引擎(表类型)
浅谈mysql的存储引擎(表类型) 什么是MySql数据库 通常意义上,数据库也就是数据的集合,具体到计算机上数据库可以是存储器上一些文件的集合或者一些内存数据的集合. 我们通常说的MySql数据库, ...
- got、plt表介绍
1. GOT表和PLT表 GOT(Global Offset Table,全局偏移表)是Linux ELF文件中用于定位全局变量和函数的一个表.PLT(Procedure Linkage Table, ...
- php链表和联表的区别,PHP_浅谈PHP链表数据结构(单链表),链表:是一个有序的列表,但 - phpStudy...
浅谈PHP链表数据结构(单链表) 链表:是一个有序的列表,但是它在内存中是分散存储的,使用链表可以解决类似约瑟夫问题,排序问题,搜索问题,广义表 单向链表,双向链表,环形链表 PHP的底层是C,当一个 ...
- 浅谈MySQL表类型
小小子的文章写的不错哦. 转载:http://www.xiaoxiaozi.com/2009/07/14/1171/ 浅谈MySQL表类型 MySQL为我们提供了很多表类型供选择,有MyISAM.IS ...
- 浅谈eform自定义表单工具和协同办公系统
浅谈eform自定义表单工具和协同办公系统 提起"协同办公",随便在百度或者Google搜索一下,就能让你看到眼花缭乱的信息,国内的各大协同办公软件厂商都在鼓吹着自己对协同的理解和 ...
- 洛谷P1156 垃圾陷阱 题解浅谈刷表法与填表法
洛谷P1156 垃圾陷阱 题解&浅谈刷表法与填表法 填表法 :就是一般的动态规划,当前点的状态,可以直接用状态方程,根据之前点的状态推导出来. 刷表法:由当前点的状态,更新其他点的状态.需要注 ...
- 浅谈 MySQL 连表查询
浅谈 MySQL 连表查询 连表查询是一把双刃剑, 优点是适应范式, 减少数据冗余; 缺点是连表查询特别是多张表的连表会增加数据库的负担, 降低查询效率. 简介 连表查询就是 2 张表或者多张表的联合 ...
最新文章
- MyEclipse设置JSP页面默认编码方式
- mac svn 可视化界面_svn for mac 操作
- java第二天_进制转换原理和补码存储方式作业
- Java synchronized 详解
- 2440启动代码分析
- SQLServer常用的字符串函数梳理
- java中operationBox_Java使用PDFBox开发包实现对PDF文档内容编辑与保存
- TypeScript,初次见面,请多指教 ?
- 模板 | 年度财务分析报告财务工作汇报PPT
- 最新PHP云购源码+带机器人/控制/教程/去授权说明
- 实用工具系列 - Xshell安装下载与使用
- 安卓系统添加字体库和修改系统默认的字体
- 微场景:移动互联时代的营销革命
- 申报须知,2022年滁州市各区县高新技术企业奖励政策变化,明光市
- selenium爬取中国经济与社会发展统计数据库
- 服务号、订阅号、小程序、企业号(企业微信)的认知与区别
- 安装centos7系统 服务器安装系统
- 软件测试面试,一定要准备的7个高频面试题(附答案,建议收藏)
- 立象Argox A-200 打印机驱动
- 今晚19:00,淘宝自研标准化协议库XQUIC开源直播!
热门文章
- Python初级教程-廖雪峰Python教程
- 远程服务器器获取session 信息失败,该如何应对
- 广告传媒公司那些看得到管不了的事
- UBI车险在全球的发展
- 【东方博宜】【基础】棋盘里的麦子?
- 常用激活函数/损失函数/代价函数
- AI冲击人工:资深翻译3年前就接受了可能到来的失业,原画师被取代后又出现了“AI概念师”...
- lightgbm 安装报错解决
- Vb+access工资管理系统(系统+答辩PPT+论文+开题报告+外文翻译)
- 软件产品著作权登记办理有哪些内容