mcpField
F
frida-17

frida-17

github.com/yfe404开发52.6k 次安装44 周前更新
代码仓库

关于 frida-17

面向 Frida 17 JavaScript 脚本编写与审查的参考技能,整理了 API 移除项、替代写法和常见兼容性问题。

主要功能

  1. 01Frida 17 API 迁移指导
  2. 02NativePointer 内存操作
  3. 03Java bridge 示例
  4. 04脚本兼容性检查清单

适用场景

  1. 01将脚本升级到 Frida 17
  2. 02检查脚本中的已移除 API
  3. 03在 hook 中处理 Java 字节数组

安装

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

$npx skills add https://github.com/yfe404/frida-17-skill --skill frida-17

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

详细介绍

Frida 17 脚本指南

本指南可帮助编写和修复兼容 Frida 17.0.0(于 2025 年 5 月发布)的 Frida 脚本。

Frida 17 中的重大变更

1. 静态 Module 方法 — 已移除
// OLD - No longer works in Frida 17
Module.findBaseAddress('libriver.so')
Module.getBaseAddress('libriver.so')
Module.findExportByName(null, 'open')
Module.findExportByName('libc.so', 'open')
Module.getExportByName(null, 'open')
Module.ensureInitialized('libc.so')
Module.enumerateExports('libc.so')
Module.enumerateSymbols('libc.so')

// NEW - Use Process and instance methods instead
var lib = Process.findModuleByName('libriver.so');  // returns Module or null
var lib = Process.getModuleByName('libriver.so');   // throws if not found
lib.base                                             // module base address
lib.findExportByName('open')                        // returns address or null
lib.getExportByName('open')                         // throws if not found
lib.enumerateExports()                              // returns array
lib.enumerateSymbols()                              // returns array
2. 静态 Memory 方法 — 已移除
// OLD - No longer works
Memory.readU32(ptr)
Memory.writeU32(ptr, value)

// NEW - Use NativePointer instance methods
ptr.readU32()
ptr.writeU32(value)
3. 旧版枚举 API — 已移除
// OLD - Callback style removed
Process.enumerateModules({ onMatch: fn, onComplete: fn })
Process.enumerateModulesSync()

// NEW - Returns array directly
Process.enumerateModules()
4. 保留的函数名称 — 请勿覆盖

以下是 Frida 内置函数。使用这些名称定义自定义函数会导致: TypeError: cannot define variable 'hexdump'

保留名称:

  • hexdump — 自定义十六进制转储函数请改用 dumpHex
  • ptr — 指针构造函数简写
  • NULL — 空指针常量
// BAD - conflicts with built-in
function hexdump(ptr, len) { ... }

// GOOD - use different name
function dumpHex(ptr, len) { ... }

NativePointer 方法(Frida 17 中有效)

转换:

  • toInt32() — 转换为有符号 32 位整数
  • toNumber() — 转换为 JavaScript 数字
  • toString([radix]) — 转换为字符串

不可用:

  • toUInt32() — 不存在;对于小于 2^31 的数值,请使用 toInt32()

内存读取:

  • readU8()、readS8()、readU16()、readS16()
  • readU32()、readS32()、readU64()、readS64()
  • readByteArray(length) — 返回 ArrayBuffer
  • readPointer()、readCString()、readUtf8String()

内存写入:

  • writeU8(value)、writeS8(value) 等
  • writeByteArray(bytes) — bytes 必须是 ArrayBuffer 或 JS 数组
  • writePointer(ptr)、writeUtf8String(str)

指针运算:

  • add(rhs)、sub(rhs)、and(rhs)、or(rhs)、xor(rhs)
  • shr(n)、shl(n)、not()
  • isNull()、equals(rhs)、compare(rhs)

Java Bridge API(Frida 17 中未变更)

Java.perform(function() {
    var MyClass = Java.use('com.example.MyClass');

    // Hook with overload
    MyClass.myMethod.overload('int', 'java.lang.String').implementation = function(a, b) {
        console.log('Called with: ' + a + ', ' + b);
        // Call original
        return this.myMethod.overload('int', 'java.lang.String').call(this, a, b);
    };

    // Hook all overloads
    MyClass.myMethod.overloads.forEach(function(overload) {
        overload.implementation = function() {
            return overload.apply(this, arguments);
        };
    });
});

Java byte[] 处理: Java 字节数组不能直接传递给 Memory.alloc().writeByteArray()。 请手动转换:

// BAD - throws "expected a buffer-like object"
var hex = dumpHex(Memory.alloc(javaByteArray.length).writeByteArray(javaByteArray), len);

// GOOD - iterate and convert
var hex = "";
for (var i = 0; i < javaByteArray.length; i++) {
    hex += ("0" + (javaByteArray[i] & 0xff).toString(16)).slice(-2);
}

Frida 17 的常见模式

等待库加载
function waitForLibrary(libName, callback) {
    var lib = Process.findModuleByName(libName);
    if (lib) {
        callback(lib.base);
        return;
    }
    var pollInterval = setInterval(function() {
        var lib = Process.findModuleByName(libName);
        if (lib) {
            clearInterval(pollInterval);
            callback(lib.base);
        }
    }, 500);
}
Hook libc 函数
var libc = Process.findModuleByName('libc.so');
var open = libc ? libc.findExportByName('open') : null;
if (open) {
    Interceptor.attach(open, {
        onEnter: function(args) {
            console.log('open(' + args[0].readCString() + ')');
        }
    });
}
自定义十六进制转储函数
function dumpHex(ptr, len) {
    if (!ptr || ptr.isNull()) return 'null';
    try {
        var bytes = ptr.readByteArray(len);
        if (!bytes) return 'null';
        var arr = new Uint8Array(bytes);
        var hex = '';
        for (var i = 0; i < arr.length; i++) {
            hex += ('0' + arr[i].toString(16)).slice(-2);
        }
        return hex;
    } catch (e) {
        return 'error: ' + e;
    }
}

Frida 17 兼容性检查清单

审查 Frida 脚本时,请检查以下内容:

  1. Module.findBaseAddress() -> Process.findModuleByName().base
  2. Module.getBaseAddress() -> Process.getModuleByName().base
  3. Module.findExportByName(null, name) -> Process.findModuleByName('libc.so').findExportByName(name)
  4. Module.findExportByName(lib, name) -> Process.findModuleByName(lib).findExportByName(name)
  5. Module.enumerateExports(lib) -> Process.getModuleByName(lib).enumerateExports()
  6. Module.enumerateSymbols(lib) -> Process.getModuleByName(lib).enumerateSymbols()
  7. Memory.readU32(ptr) -> ptr.readU32()
  8. toUInt32() -> toInt32()(toUInt32 从未存在)
  9. function hexdump() -> function dumpHex()(名称冲突)
  10. Java byte[] 与 writeByteArray() 搭配使用 -> 手动进行十六进制转换

参考资料

评论

支持 Markdown