下面是一段plt
表的示例
Disassembly of section .plt:080482d0 <common@plt>: 80482d0: ff 35 04 a0 04 08pushl0x804a004 80482d6: ff 25 08 a0 04 08jmp*0x804a008跳转到_dl_runtime_resolve这个函数中查找运行时地址它是got表的第三项 , 所以可以看到该地址为08而puts对应的got表的地址为0c 80482dc: 00 00add%al,(%eax) ...080482e0 <puts@plt>: 80482e0: ff 25 0c a0 04 08jmp*0x804a00c从got表的第四项开始 80482e6: 68 00 00 00 00push$0x0这个 push进去的实际上就是在 got 表中的索引 80482eb: e9 e0 ff ff ffjmp80482d0 <_init+0x28>又跳到最上面的 公共 plt080482f0 <__libc_start_main@plt>: 80482f0: ff 25 10 a0 04 08jmp*0x804a010 80482f6: 68 08 00 00 00push$0x8每一个got表项对应的 push 的参数之间的间隔为8 80482fb: e9 d0 ff ff ffjmp80482d0 <_init+0x28>
其中除第一个表项以外 , plt 表的第一条都是跳转到对应的 got 表项 , 而 got 表项的内容我们可以通过 gdb 来看一下 , 如果函数还没有执行的时候 , 这里的地址是对应 plt 表项的下一条命令 , 即 push 0x0(作为参数传入-- 相应函数在 rel.plt
中的偏移)
在想要调用的函数没有被调用过 , 想要调用他的时候 , 是按照这个过程来调用的
xxx@plt -> xxx@got -> xxx@plt -> 公共@plt -> _dl_runtime_resolve(通过这个函数找到运行时函数的地址)
到这里我们还需要知道
- _dl_runtime_resolve 是怎么知道要查找 printf 函数的
- _dl_runtime_resolve 找到 printf 函数地址之后 , 它怎么知道回填到哪个 GOT 表项
第二个问题 , 看 .rel.plt 的位置就对应着 xxx@plt 里 jmp 的地址 , 该位置就是偏移量 , 使用
readelf -r plt
读取elf
文件中重定位节信息文章插图
在 i386 架构下 , 除了每个函数占用一个 GOT 表项外 , GOT 表项还保留了3个公共表项 , 也即 got 的前3项 , 分别保存:动态链接器在加载完 ELF 之后 , 都会将这3地址写到 GOT 表的前3项
- got [0]: 本 ELF 动态段 (.dynamic 段)的装载地址
- got [1]:本 ELF 的 link_map 数据结构描述符地址 , 包含了进行符号解析需要的当前 ELF 对象的信息 。每个 link_map 都是一条双向链表的一个节点 , 而这个链表保存了所有加载的 ELF 对象的信息 。
- got [2]:指向动态装载器中 _dl_runtime_resolve 函数的指针 。
文章插图
文章插图
通过编写如下所示的代码来帮助理解
plt
和got
这两个表// gcc -m32 -no-pie -g -o plt plt.c#include <stdio.h>#include <stdlib.h>int main(int argc, char **argv){puts("hello,world");exit(0);}
使用objdump -h plt
, 查看该文件编译后的所有节的信息plt:file format elf32-i386Sections:Idx NameSizeVMALMAFile offAlgn 10 .rel.plt000000180804832c0804832c0000032c2**2CONTENTS, ALLOC, LOAD, READONLY, DATA 12 .plt000000400804903008049030000010302**4CONTENTS, ALLOC, LOAD, READONLY, CODE 13 .plt.sec000000300804907008049070000010702**4CONTENTS, ALLOC, LOAD, READONLY, CODE 22 .got000000040804bffc0804bffc00002ffc2**2CONTENTS, ALLOC, LOAD, DATA 23 .got.plt000000180804c0000804c000000030002**2CONTENTS, ALLOC, LOAD, DATA
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 四十一 增删查改分页 Java开发学习----MyBatisPlus标准数据层开发
- 中 学习ASP.NET Core Blazor编程系列十——路由
- CC1,3,6回顾
- 图学习【参考资料2】-知识补充与node2vec代码注解
- 二十四 设计模式学习:Spring 中使用到的设计模式
- Java安全之CC3
- TensorFlow深度学习!构建神经网络预测股票价格!?
- JUC学习笔记——共享模型之管程
- Seata Server 1.5.2 源码学习
- 2022极端高温!机器学习如何预测森林火灾?? 万物AI