news 2026/6/5 2:07:24

深入glibc:图解_dl_fixup函数如何一步步解析动态链接函数(附ret2dlresolve利用原理)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入glibc:图解_dl_fixup函数如何一步步解析动态链接函数(附ret2dlresolve利用原理)

深入glibc:图解_dl_fixup函数如何一步步解析动态链接函数

在Linux系统中,动态链接是一个至关重要的机制,它允许程序在运行时加载共享库中的函数。这个过程看似简单,但背后却隐藏着复杂的机制。本文将带你深入探索glibc中的_dl_fixup函数,揭示动态链接函数解析的全过程。

1. 动态链接的基本原理

当我们在程序中调用一个动态链接的函数时,实际上经历了一个精巧的"延迟绑定"过程。这个过程确保了只有在函数第一次被调用时才会进行解析,后续调用则直接跳转到解析后的地址。

让我们用一个简单的例子来说明这个过程:

#include <unistd.h> int main() { write(1, "Hello\n", 6); return 0; }

编译这个程序后,如果我们查看它的反汇编代码,会发现write函数的调用实际上是通过PLT(Procedure Linkage Table)来实现的。PLT是动态链接机制中的关键组件,它充当了程序与共享库之间的桥梁。

动态链接的核心优势在于:

  • 节省内存:多个程序可以共享同一个库的代码段
  • 灵活性:库可以独立更新而不需要重新编译程序
  • 加载效率:只有实际使用的函数才会被解析和加载

2. PLT和GOT的协作机制

PLT和GOT(Global Offset Table)共同构成了动态链接的基础设施。让我们详细看看它们是如何工作的:

  1. 第一次调用函数时

    • 程序跳转到PLT表项
    • PLT表项跳转到GOT表项
    • 由于是第一次调用,GOT表项指向PLT中的下一条指令
    • 程序压入重定位偏移量(reloc_arg)
    • 跳转到PLT[0],即动态链接器的入口
  2. 后续调用时

    • 程序跳转到PLT表项
    • PLT表项跳转到GOT表项
    • GOT表项此时已经保存了函数的真实地址
    • 直接跳转到目标函数

这个过程中,_dl_runtime_resolve函数扮演了关键角色。它接收两个参数:

  • link_map:包含动态链接信息的结构体
  • reloc_arg:重定位偏移量

_dl_runtime_resolve实际上会调用_dl_fixup函数来完成具体的解析工作。

3. _dl_fixup函数的详细解析

_dl_fixup函数是动态链接解析过程的核心,它位于glibc的elf/dl-runtime.c文件中。让我们逐步分析它的工作原理:

_dl_fixup(struct link_map *l, ElfW(Word) reloc_arg) { // 获取重定位表项 const PLTREL *const reloc = (const void *)(D_PTR(l, l_info[DT_JMPREL]) + reloc_offset); // 获取符号表项 const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; // 检查重定位类型 assert(ELF(R_TYPE)(reloc->info) == ELF_MACHINE_JMP_SLOT); // 查找符号 result = _dl_lookup_symbol_x(strtab + sym->st_name, l, &sym, l->l_scope, version, ELF_RTYPE_CLASS_PLT, flags, NULL); // 计算函数地址 value = DL_FIXUP_MAKE_VALUE(result, sym ? (LOOKUP_VALUE_ADDRESS(result) + sym->st_value) : 0); // 更新GOT表 return elf_machine_fixup_plt(l, result, reloc, rel_addr, value); }

这个过程可以分解为以下几个关键步骤:

  1. 定位重定位表项

    • 通过reloc_arg.rel.plt节中找到对应的重定位表项
    • 这个表项包含了函数在符号表中的索引和重定位类型
  2. 获取符号信息

    • 通过重定位表项中的r_info字段找到符号表项
    • 符号表项包含了函数名在字符串表中的偏移等信息
  3. 符号查找

    • 使用_dl_lookup_symbol_x函数在加载的共享库中查找符号
    • 这个函数会返回包含目标符号的库的基地址
  4. 地址计算与更新

    • 计算函数的实际地址(库基地址 + 符号偏移)
    • 将这个地址写入GOT表的对应条目中

4. 关键数据结构解析

理解动态链接机制需要熟悉几个关键的数据结构:

4.1 link_map结构

link_map是动态链接器的核心数据结构,它包含了加载对象的所有信息:

struct link_map { ElfW(Addr) l_addr; // 库的加载地址 char *l_name; // 库的绝对文件名 ElfW(Dyn) *l_ld; // 动态段地址 struct link_map *l_next, *l_prev; // 链表中前后对象 // ... 其他字段 ... ElfW(Dyn) *l_info[DT_NUM]; // 动态段信息数组 };

其中l_info数组包含了指向各种动态段信息的指针,如:

  • DT_JMPREL:指向PLT重定位表
  • DT_SYMTAB:指向动态符号表
  • DT_STRTAB:指向字符串表

4.2 重定位表项

重定位表项(Elf32_Rel/Elf64_Rela)描述了如何修改指令或数据以正确引用符号:

typedef struct { Elf32_Addr r_offset; // 需要修改的地址(通常是GOT表项) Elf32_Word r_info; // 符号索引和重定位类型 } Elf32_Rel;

r_info字段的高24位是符号索引,低8位是重定位类型。

4.3 符号表项

符号表项(Elf32_Sym/Elf64_Sym)描述了符号的各种属性:

typedef struct { Elf32_Word st_name; // 符号名在字符串表中的偏移 Elf32_Addr st_value; // 符号值(通常是偏移量) Elf32_Word st_size; // 符号大小 unsigned char st_info;// 符号类型和绑定属性 unsigned char st_other;// 符号可见性 Elf32_Section st_shndx;// 相关节索引 } Elf32_Sym;

5. 动态链接的安全考量

理解动态链接机制不仅有助于深入理解Linux系统,也对系统安全有重要意义。动态链接过程中涉及多个数据结构的交互,如果这些数据结构被恶意篡改,就可能导致安全漏洞。

在安全研究中,有一种称为"ret2dlresolve"的技术就是利用了动态链接机制的特性。这种技术允许攻击者在特定条件下控制函数的解析过程,从而执行任意代码。理解_dl_fixup的工作原理是分析和防御这类攻击的基础。

6. 调试动态链接过程

为了更好地理解动态链接的实际工作过程,我们可以使用GDB进行调试。以下是一个简单的调试步骤:

  1. 在PLT表项设置断点:

    break *write@plt
  2. 跟踪第一次调用时的执行流程:

    stepi
  3. 观察GOT表的变化:

    x/x &write@got
  4. 跟踪_dl_runtime_resolve的执行:

    finish

通过这样的调试,我们可以直观地看到动态链接的整个过程,从PLT跳转到GOT,再到_dl_runtime_resolve_dl_fixup的调用,最后GOT表被更新为函数的真实地址。

7. 实际案例分析

让我们通过一个实际的例子来观察动态链接的过程。考虑以下简单的漏洞程序:

#include <unistd.h> #include <stdio.h> #include <string.h> void vuln() { char buf[100]; read(0, buf, 256); } int main() { char buf[100] = "Welcome!\n"; write(1, buf, strlen(buf)); vuln(); return 0; }

编译这个程序时,我们可以观察到:

  • writeread都是动态链接的函数
  • 它们的PLT表项和GOT表项在二进制中是明确可见的
  • 第一次调用这些函数时会触发解析过程

通过分析这个程序的动态链接行为,我们可以更深入地理解_dl_fixup的实际工作方式。

8. 总结与展望

动态链接是现代操作系统中的重要机制,而_dl_fixup函数则是这个机制的核心。通过本文的分析,我们了解了:

  1. PLT和GOT如何协作实现延迟绑定
  2. _dl_runtime_resolve_dl_fixup的调用关系
  3. 动态链接过程中涉及的关键数据结构
  4. 如何调试和观察动态链接的实际过程

理解这些底层机制不仅有助于我们编写更高效的代码,也为深入分析系统安全提供了基础。随着技术的发展,动态链接机制也在不断演进,但基本原理仍然保持着一致性。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/5 2:07:22

一个科技迷的踩点实录:我根据AI落地趋势拿下了对口认证

作为一名深耕科技领域多年的爱好者&#xff0c;我一直保持着对行业前沿动态的敏锐感知。不同于盲目跟风追热点的人&#xff0c;我始终坚信&#xff0c;科技行业的成长核心&#xff0c;从来不是追逐转瞬即逝的风口&#xff0c;而是精准捕捉落地趋势&#xff0c;提前匹配行业刚需…

作者头像 李华
网站建设 2026/6/5 2:01:56

告别黑盒!用开源OpenRAM在28nm工艺上玩转自定义SRAM编译器

开源SRAM编译器OpenRAM在28nm工艺的实战指南在芯片设计领域&#xff0c;SRAM&#xff08;静态随机存取存储器&#xff09;作为SoC和ASIC中不可或缺的组成部分&#xff0c;其性能直接影响整个系统的效率。然而&#xff0c;商业SRAM编译器长期被少数EDA巨头垄断&#xff0c;不仅价…

作者头像 李华
网站建设 2026/6/5 2:01:55

节假日景区人流爆满运维压力大?AI 机器狗自助服务落地,天问智能助力景区无人化减负增效

【智慧文旅运营专项报道】国内各大热门文旅景区每逢周末、法定节假日迎来客流峰值&#xff0c;游客咨询问路、物资寄存、步道巡查、安全劝导等工作集中爆发&#xff0c;人工讲解员、安保、服务人员严重不足&#xff0c;景区人力运维成本居高不下&#xff0c;服务效率难以匹配客…

作者头像 李华
网站建设 2026/6/5 2:01:08

ollama升级最新版操作指南

其实核心就一句话&#xff1a; 去 Ollama官网 下载你电脑相应的版本&#xff0c;然后直接安装即可 注意&#xff1a; 官网下载会很慢&#xff0c;可以使用迅雷去下载&#xff0c;几分钟就搞定了 另外&#xff0c;我在安装的时候出现了安装包不能运行的情况&#xff0c;我这边…

作者头像 李华
网站建设 2026/6/5 2:00:57

精益少管实操指南:3步做到,管理者彻底减负

读懂了精益现场管理少管的本质&#xff0c;避开了践行少管的常见陷阱&#xff0c;很多生产现场管理者依然困惑&#xff1a;到底该怎么做&#xff0c;才能真正实现少管&#xff1f;如何才能放下手中的琐事&#xff0c;从事必躬亲中解脱出来&#xff0c;让员工自主管理、现场自主…

作者头像 李华