准备工作
- 一台真机
- Frida环境
- IDA
- 受害者so文件
核心脚本 Copy过去,不用改,通用的,新建一个natives.js文件粘贴
function hook_RegisterNatives() {
var symbols = Module.enumerateSymbolsSync("libart.so");
var addrRegisterNatives = null;
for (var i = 0; i < symbols.length; i++) {
var symbol = symbols[i];
//_ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi
if (symbol.name.indexOf("art") >= 0 &&
symbol.name.indexOf("JNI") >= 0 &&
symbol.name.indexOf("RegisterNatives") >= 0 &&
symbol.name.indexOf("CheckJNI") < 0) {
addrRegisterNatives = symbol.address;
console.log("RegisterNatives is at ", symbol.address, symbol.name);
}
}
if (addrRegisterNatives != null) {
Interceptor.attach(addrRegisterNatives, {
onEnter: function (args) {
console.log("[RegisterNatives] method_count:", args[3]);
var env = args[0];
var java_class = args[1];
var class_name = Java.vm.tryGetEnv().getClassName(java_class);
//console.log(class_name);
var methods_ptr = ptr(args[2]);
var method_count = parseInt(args[3]);
for (var i = 0; i < method_count; i++) {
var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));
var name = Memory.readCString(name_ptr);
var sig = Memory.readCString(sig_ptr);
var find_module = Process.findModuleByAddress(fnPtr_ptr);
console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, "module_name:", find_module.name, "module_base:", find_module.base, "offset:", ptr(fnPtr_ptr).sub(find_module.base));
}
}
});
}
}
setImmediate(hook_RegisterNatives);
找受害者, 通过命令 frida-PS -U -a 查找真机上所有进程,把包名遍历出来
frida-PS -U -a
Frida Hook命令 Hook谁 就把下面的包名改成谁就好了
frida -U -f com.sankuai.movie -l natives.js
好处
这个命令有两个作用
- 运行的时候 主动调起app 同时注册hook 比传统的hook要快
- 运行的时候 主动调起app 同时注册hook 比传统的hook要快
输出
美团的风控值mtgsig就在这里面哈
常见问题
1. 函数找不到?
- 检查SO是否已加载:Process.enumerateModules()
- 确认函数符号是否被混淆(需计算偏移地址)。
2.如何Hook非导出函数?
- 通过IDA获取函数偏移,结合模块基地址计算绝对地址:
const funcAddr = module.base.add(0x1234);
3. 处理多线程问题
在Java.perform包裹代码确保执行在主线程。
总结
Frida通过动态注入和JavaScript API提供了灵活的SO Hook能力。结合静态分析工具,可高效定位关键函数,实时监控或修改参数/返回值。建议参考官方文档探索更多高级功能。