PLT GOT

简单代码分析
#include <stdio.h>

void print_banner()
{
    printf("Welcome to World of PLT and GOT\n");
}

int main(void)
{
    print_banner();

    return 0;
}

对这个文件编译,链接后形成汇编指令call**<printf函数的地址>**,但是printf函数在glibc动态库,编译和链接阶段没办法知道printf函数加载地址。唯一的办法是运行时重定位。运行时重定位无法修改代码段,只能将printf定位到数据段。编译阶段生成的call命令,通过链接器生成的额外小代码片段,获取printf函数地址。(上述代码生成print_stub)
展开编译链接过程:

编译
每个编译单元都会经历编译和链接两个阶段,编译是将.c源码翻译成汇编指令的中间文件,生成…o文件。
链接
将一个或者多个中间文件通过链接器将他们链接成一个可执行文件。
综上,链接阶段对printf_stub做链接重定位,运行时才对printf做运行重定位。

动态链接PLT GOT

动态链接需要考虑两点,需要存放外部函数的数据段和获取数据段存放函数地址的一小段额外代码。当可执行文件调用多个动态库函数,每个函数都需要这两个东西,这样每样东西就形成一个表,每个函数使用其中一项。存放函数地址的数据表,称为重局偏移表,那个额外代码段表,称为程序链接表。
假设最开始的示例代码test.c增加一个write_file函数,在该函数里面调用glibc的write实现写文件操作。根据前面讨论的PLT和GOT原理,test在运行过程中,调用方(如print_banner和write_file)是如何通过PLT和GOT穿针引线之后,最终调用到glibc的printf和write函数的?

两张表格运行图
最后,这不是真实过程,只是一个模拟。

### `.got.plt` 的作用与原理 在ELF(可执行与可链接格式)文件中,`.got.plt` 是全局偏移(Global Offset Table, GOT)的一部分,主要用于支持延迟绑定(Lazy Binding),这是动态链接器优化函数调用的一种机制。 #### 1. `.got.plt` 的结构和用途 `.got.plt` 区段通常位于程序的 `.got` 段内,并保留特定条目用于 PLT(过程链接)机制。典型的 `.got.plt` 前三个条目具有特殊含义: - **GOT[0]**: 存储的是动态段(`.dynamic`)的地址,供动态链接器使用。 - **GOT[1]**: 存储的是重定位信息的索引,用于解析外部符号。 - **GOT[2]**: 存储的是 `_dl_runtime_resolve` 函数的地址,它是动态链接器中的核心函数,负责在运行时解析未绑定的符号。 后续的 `.got.plt` 条目则对应各个导入函数的地址,在第一次调用某个外部函数时,控制流会跳转到 PLT ,然后通过 `.got.plt` 中的占位符引导至 `_dl_runtime_resolve` 来完成实际地址的解析[^4]。 #### 2. `.got.plt` 和 PLT 的交互机制 当程序首次调用一个外部函数时,例如 `puts()`,控制流首先进入 PLT 项(如 `plt[1]`)。该 PLT 项的第一步操作通常是跳转到对应的 `.got.plt` 条目。如果该函数尚未被解析,`.got.plt` 中存储的是 PLT 中下一条指令的地址,而不是实际的函数地址。这将触发 `_dl_runtime_resolve` 函数来解析函数地址,并更新 `.got.plt` 条目以供后续直接调用。 #### 示例代码:PLTGOT 的典型汇编结构 ```assembly ; PLT[0] push DWORD PTR [rip+0x2009e2] ; GOT[1],模块标识符 jmp QWORD PTR [rip+0x2009e4] ; 跳转到 _dl_runtime_resolve ``` 在上述代码中,`GOT[1]` 提供了指向重定位信息的指针,而 `GOT[2]` 则指向 `_dl_runtime_resolve` 函数,这两个条目是动态链接的关键组成部分[^4]。 #### 3. 动态链接的延迟绑定 延迟绑定的核心思想是按需解析符号地址,避免在程序启动时解析所有外部函数,从而提升性能。`.got.plt` 在此过程中充当了缓存角色:一旦某个函数地址被解析,其值会被写入 `.got.plt` 对应的位置,之后的调用将直接跳转至实际地址,无需再次解析。 #### 4. 安全性和利用场景 在安全领域,尤其是 Pwn 类题目中,`.got.plt` 经常成为攻击目标。由于它存储了函数的实际地址,攻击者可以通过覆盖 `.got.plt` 中的条目劫持控制流。例如,通过格式化字符串漏洞或栈溢出修改 `.got.plt` 中的函数指针,使其指向恶意代码片段(如 shellcode)。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值