关于 frida-17
面向 Frida 17 JavaScript 脚本编写与审查的参考技能,整理了 API 移除项、替代写法和常见兼容性问题。
主要功能
- 01Frida 17 API 迁移指导
- 02NativePointer 内存操作
- 03Java bridge 示例
- 04脚本兼容性检查清单
适用场景
- 01将脚本升级到 Frida 17
- 02检查脚本中的已移除 API
- 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— 自定义十六进制转储函数请改用dumpHexptr— 指针构造函数简写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)— 返回 ArrayBufferreadPointer()、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 脚本时,请检查以下内容:
-
Module.findBaseAddress()->Process.findModuleByName().base -
Module.getBaseAddress()->Process.getModuleByName().base -
Module.findExportByName(null, name)->Process.findModuleByName('libc.so').findExportByName(name) -
Module.findExportByName(lib, name)->Process.findModuleByName(lib).findExportByName(name) -
Module.enumerateExports(lib)->Process.getModuleByName(lib).enumerateExports() -
Module.enumerateSymbols(lib)->Process.getModuleByName(lib).enumerateSymbols() -
Memory.readU32(ptr)->ptr.readU32() -
toUInt32()->toInt32()(toUInt32 从未存在) -
function hexdump()->function dumpHex()(名称冲突) - Java byte[] 与
writeByteArray()搭配使用 -> 手动进行十六进制转换
参考资料
评论
支持 Markdown