hook RegisterNative函数
命令:
frida -U --no-pause -f cn.xiaochuankeji.tieba -l C:\Users\Administrator\Desktop\demo.js
frida -U
--no-pause 直接启动
-f 重新启动app 然后attach
cn.xiaochuankeji.tieba 包名
-l 指定js脚本
C:\Users\Administrator\Desktop\demo.js js脚本路径
打印示例:
[RegisterNatives] java_class: com.izuiyou.network.NetCrypto
name: registerDID sig: ([B)Z fnPtr: 0x99fb432d module_name: libnet_crypto.so
module_base: 0x99fa2000 offset: 0x1232d
.init_array so被加载进来首先执行的地方
JNI_OnLoad init_array节区函数执行完后执行
.fini_array so最后执行的函数
app可以动态调试 用frida脚本去hook 打印出函数地址 == 在libart.so中 RegisterNatives函数下断获取想要的信息
Java层分析某个协议 -> 校验字段 -> 加载so 调用native函数生成 -> IDA分析对应so 找到RegisterNative的第三参数地址
情况1: 动态注册函数的name sig被加密 函数地址可以正常得到
用frida hook RegisterNative函数 打印出name sig address
情况2: JNI_OnLoad函数被处理了(混淆 指令) -> RegisterNative 找不到
IDA快捷键 ctrl+s 跳到 .data区域 看看有没有动态注册函数地址
情况3: 动态注册偏移处 三个字段都被处理 能看到的之后很多函数体
用frida脚本去hook 打印出函数地址
一般不会在反调试函数中做一些重要的运算
某一个函数中有反调试并且函数体积不是很大 -> 尝试把整个函数的调用掉给NOP掉
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);