mcpField
F
frida-native-hooks

frida-native-hooks

github.com/rudra-ravi开发7114 次安装25 周前更新
代码仓库

关于 frida-native-hooks

Frida Native Hooks 是使用 Frida 调查原生函数和内存行为的技能,指导从定位目标到追踪或替换函数,并安全处理内存。

主要功能

  1. 01查找模块并解析函数地址
  2. 02使用 Interceptor 钩子追踪调用
  3. 03替换原生函数行为
  4. 04使用回溯和有界 Stalker 跟踪
  5. 05安全替换参数

适用场景

  1. 01追踪文件或网络 API 调用
  2. 02调查符号已剥离的函数
  3. 03检查原生调用边界的调用方
  4. 04修改参数或替换函数行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rudra-ravi/frida-skills --skill frida-native-hooks

安装后在 Claude Code 中输入/frida-native-hooks确认已加载。

附带文件agents/openai.yamlreferences/native-patterns.md

详细介绍

Frida 原生钩子

当目标是原生函数或内存行为时,使用此技能。

先发现

  1. 确定进程架构和模块:
    console.log(Process.arch, Process.platform, Process.pointerSize);
    for (const m of Process.enumerateModules()) console.log(m.name, m.base, m.size);
    
  2. 尽可能通过 Frida API 解析地址:
    const mod = Process.getModuleByName("libtarget.so");
    const fn = mod.getExportByName("target_function");
    
  3. 如果名称已剥离,先搜索导入项/导出项,然后搜索符号、字符串和字节模式。
  4. 在 ARM/Thumb 上,优先使用 Frida API 返回的地址,以正确处理指令集细节。

钩子模式

const target = Process.getModuleByName("libc.so").getExportByName("open");

Interceptor.attach(target, {
  onEnter(args) {
    this.path = args[0].readUtf8String();
    console.log("[open] path=", this.path);
  },
  onLeave(retval) {
    console.log("[open] fd=", retval.toInt32());
  }
});

替换规则

  • 使用 Interceptor.attach() 进行跟踪,以及轻量级的参数/返回值修改。
  • 完全替换行为时,使用 Interceptor.replace()。
  • 仅在热函数需要更低开销时使用 Interceptor.replaceFast();通过返回的指针调用原函数。
  • 使用 NativeFunction 封装原函数,并确保 ABI、返回类型和参数类型正确。
  • 仅当刚安装的钩子必须在同一脚本中立即调用时,才调用 Interceptor.flush()。

实践模式

  • 优先钩取边界函数,而非内部函数:导出的 API、导入的 libc/crypto/TLS 调用、文件/网络/系统调用包装函数,然后是应用特有的已剥离函数。
  • 名称已剥离时,结合静态字符串、导入项、反汇编器交叉引用、运行时模块加载日志,以及 Stalker/调用者摘要进行分析。
  • 尽早使用 Thread.backtrace(),查明是谁调用了 open、connect、SSL_write、CCCrypt、strcmp 或 memcmp 等通用边界函数。
  • 仅针对范围明确的问题使用 Stalker:指定线程、指定函数调用期间,并先查看调用/代码块摘要,再进行指令级跟踪。
  • 如果反 Frida 检查涉及 /proc、ptrace、已加载模块扫描、线程名称、端口或符号/字符串扫描,应将其视为原生层工作。

内存安全

  • 除非已确认缓冲区大小,否则不要向现有缓冲区写入更长的字符串。
  • 优先分配新字符串并替换指针参数。
  • 在所需生命周期内保持已分配的替换字符串可访问:
    const keepalive = [];
    Interceptor.attach(target, {
      onEnter(args) {
        const s = Memory.allocUtf8String("replacement");
        keepalive.push(s);
        args[0] = s;
      }
    });
    
  • 如果之后还要使用 retval/参数数据,请在回调中复制数据。

原生分析清单

  • 解析地址前确认模块已加载。
  • 通过头文件、反编译器、调试符号或观察到的调用约定验证函数签名。
  • 读取指针前检查其是否为 null 且可读。
  • 日志应包含足够的上下文,以证明调用路径正确。
  • 修改应有回滚途径:分离钩子、还原、重启或移除 Gadget 配置。

参考资料

阅读 references/native-patterns.md,查看涵盖导出项、导入项、模式扫描、回溯、替换和性能说明的模板。

评论

支持 Markdown