Pwn学习随笔( 五 )


下面是一段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(通过这个函数找到运行时函数的地址)
到这里我们还需要知道

  1. _dl_runtime_resolve 是怎么知道要查找 printf 函数的
  2. _dl_runtime_resolve 找到 printf 函数地址之后 , 它怎么知道回填到哪个 GOT 表项
第一个问题 , 在 xxx@plt 中 , 我们在 jmp 之前 push 了一个参数 , 每个 xxx@plt 的 push 的操作数都不一样 , 那个参数就相当于函数的 id , 告诉了 _dl_runtime_resolve 要去找哪一个函数的地址
第二个问题 , 看 .rel.plt 的位置就对应着 xxx@plt 里 jmp 的地址 , 该位置就是偏移量 , 使用readelf -r plt读取elf文件中重定位节信息
Pwn学习随笔

文章插图
在 i386 架构下 , 除了每个函数占用一个 GOT 表项外 , GOT 表项还保留了3个公共表项 , 也即 got 的前3项 , 分别保存:
  • got [0]: 本 ELF 动态段 (.dynamic 段)的装载地址
  • got [1]:本 ELF 的 link_map 数据结构描述符地址 , 包含了进行符号解析需要的当前 ELF 对象的信息 。每个 link_map 都是一条双向链表的一个节点 , 而这个链表保存了所有加载的 ELF 对象的信息 。
  • got [2]:指向动态装载器中 _dl_runtime_resolve 函数的指针 。
动态链接器在加载完 ELF 之后 , 都会将这3地址写到 GOT 表的前3项
Pwn学习随笔

文章插图

Pwn学习随笔

文章插图
通过编写如下所示的代码来帮助理解pltgot这两个表
// 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

经验总结扩展阅读