Android PLT Hook 笔记

PLT Hook,全称是 Procedure Linkage Table Hook,是 Native 层最经典、最稳定的 Hook 技术之一。它不直接修改函数指令,而是通过修改 ELF 文件中的 GOT 表,来"偷梁换柱",实现对外部函数调用的拦截。

下面我们结合与 Inline Hook 的对比,从底层原理到代码落地,把它彻底讲透。

🎯 为什么选择 PLT Hook?

在 Native Hook 的众多流派中,PLT Hook 因其独特的优势和局限性,有自己最擅长的应用场景。

特性维度 PLT Hook (GOT/PLT Hook) Inline Hook
核心原理 修改GOT表中的函数地址 修改函数前几条指令,写入跳转代码
实现复杂度 较低。不涉及指令修复,逻辑清晰 极高。需处理指令重定位、多架构兼容、指令缓存等
稳定性 极高。业界公认成熟稳定,可部署到生产环境 相对较低。易出现兼容性问题
Hook范围 仅能拦截对动态库的外部调用 (如fopenpthread_create 可以 Hook 任意函数,包括内部函数和静态函数
典型应用 I/O监控、网络监控、线程监控(如 Matrix、xHook) 复杂的性能监控、游戏外挂、逆向工程

简单来说,如果你的目标是监控应用调用了哪些系统 API(如文件读写、网络请求、线程创建),PLT Hook 是首选,因为它足够简单和安全

⚙️ 核心原理:从ELF到GOT的"移花接木"

PLT Hook 的整个流程,依赖于 Linux 系统动态链接的实现机制。我们可以把它的工作流程拆解为三步:

  • 第一步:查找目标函数的"门牌号" (GOT表偏移) 在 ELF 文件中,.rel.plt 节(重定位表)专门记录了所有需要重定位的外部函数信息。通过 readelf -r 命令,我们可以找到目标函数(如 fwrite)在 GOT 表中的偏移量,例如 0x2FE0
  • 第二步:定位运行时的"真实地址" (基址 + 偏移) 当 SO 被加载到内存后,它的起始地址(基址)是动态变化的。我们可以通过读取 /proc/<pid>/maps 文件,找到目标 SO 的基址。 运行时函数GOT地址 = 基址 + 偏移量 。这个地址里,存放的就是真正 fwrite 函数的地址。
  • 第三步:执行"移花接木" (修改GOT)
    1. 权限修改 :代码段通常是只读的。我们需要先调用 mprotect 将包含目标 GOT 项的内存页权限改为可写(PROT_READ | PROT_WRITE)。
    2. 地址替换 :直接向计算出的 GOT 地址中,写入我们自定义的 Hook 函数(如 my_fwrite)的地址。
    3. 缓存同步 :ARM 架构有指令缓存,为确保 CPU 读取到最新的指令,需调用 __builtin___clear_cache 清除缓存。

完成这三步后,当程序执行流通过 PLT 跳转到 GOT 表获取 fwrite 地址时,拿到的就是 my_fwrite 的地址,从而成功进入我们的 Hook 函数。

💻 实战代码要点

虽然实际项目中更推荐直接使用成熟的框架(如爱奇艺的 xHook 、微信 Matrix 的 ELF Hook 或 Facebook 的 PLT Hook),但理解其核心代码有助于你更好地驾驭它们。一个典型的 PLT Hook 核心操作如下:

c 复制代码
// 假设已通过maps解析出目标函数在GOT表中的运行时地址:got_addr
// 假设自定义的Hook函数为:my_function

// 1. 修改内存页权限
uintptr_t page_start = PAGE_START((uintptr_t)got_addr);
mprotect((void*)page_start, PAGE_SIZE, PROT_READ | PROT_WRITE);

// 2. 替换GOT表项 (got_addr中存储的就是原函数地址)
void** got_item = (void**)got_addr;
void* original_function = *got_item; // 如果需要原函数,先保存
*got_item = (void*)my_function;       // 替换为Hook函数

// 3. 清除指令缓存
__builtin___clear_cache((void*)page_start, (void*)PAGE_END(got_addr));

💡 总结

PLT Hook 之所以经典,是因为它巧妙地利用了系统已有的动态链接机制。它不是侵入式地修改代码,而是"欺骗"了程序查找函数地址的过程,因此稳定性极高。在 Android 性能优化的战场上,它是你监控 I/O、网络、线程等系统调用的"特种部队",精准且可靠。

相关推荐
城东米粉儿2 小时前
leakcanary原理
android
龙之叶2 小时前
Android ADB Shell 常用命令
android·adb
城东米粉儿3 小时前
Android 图片内存问题分析、定位
android
之歆3 小时前
MySQL 主从复制完全指南
android·mysql·adb
独行soc4 小时前
2026年渗透测试面试题总结-25(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
城东米粉儿5 小时前
Android KOOM 笔记
android
城东米粉儿5 小时前
android 内存优化笔记
android
无巧不成书02186 小时前
Kotlin Multiplatform(KMP)核心解析
android·开发语言·kotlin·交互·harmonyos
前路不黑暗@6 小时前
Java项目:Java脚手架项目的地图的POJO
android·java·开发语言·spring boot·学习·spring cloud·maven