Frida Hook Native:jobjectArray 参数解析

版权归作者所有,如有转发,请注明文章出处:cyrus-studio.github.io/blog/

env.js

常用的 JNI 函数在 frida 的 env.js 中都已经定义好了

github.com/frida/frida...

通过下面代码获取 JNIEnv 引用,就可以调用相关的 JNI 函数

bash 复制代码
let env = Java.vm.tryGetEnv()

文档:frida.re/docs/javasc...

获取数组长度

ini 复制代码
let arrLen = env.getArrayLength(objArray)
console.log('array length is: ' + arrLen);

元素类型判断

通过 getObjectClassName 可以获取到对象的类名进而判断该元素的类型。

ini 复制代码
// 获取对象的类名
let className = env.getObjectClassName(objArray)
console.log('className: ' + className);

// 判断是否 jobjectArray
if (className === '[Ljava.lang.Object;') {

}

获取数组元素

ini 复制代码
let element = env.getObjectArrayElement(objArray, i)

Int 元素读取

javascript 复制代码
let intElement = Java.cast(env.getObjectArrayElement(objArray, i), Java.use('java.lang.Integer'))
console.log(`element ${i} value: ${intElement}`);

Long 元素读取

javascript 复制代码
let longElement = Java.cast(env.getObjectArrayElement(objArray, i), Java.use('java.lang.Long'))
console.log(`element ${i} value: ${longElement}`);

Float 元素读取

javascript 复制代码
let floatElement = Java.cast(env.getObjectArrayElement(objArray, i), Java.use('java.lang.Float'))
console.log(`element ${i} value: ${floatElement}`);

Double 元素读取

javascript 复制代码
let doubleElement = Java.cast(env.getObjectArrayElement(objArray, i), Java.use('java.lang.Double'))
console.log(`element ${i} value: ${doubleElement}`);

字符串 元素读取

通过 env.js 中定义的 stringFromJni 函数可以直接获取到字符串对象的值

javascript 复制代码
let stringElement = env.stringFromJni(env.getObjectArrayElement(objArray, i))
console.log(`element ${i} value: ${stringElement}`);

Object 元素读取

javascript 复制代码
let element = env.getObjectArrayElement(objArray, i)

let elementClassName = env.getObjectClassName(element)

// 元素类型转换
let castElement = Java.cast(element, Java.use(elementClassName))

console.log(`element ${i} value: ${castElement}`);

打印 jobjectArray

打印 jobjectArray 的元素类型和值

javascript 复制代码
function printObjectArray(objArray) {
    if (objArray.isNull()) {
        console.log('Object array is null');
        return null;
    }

    // 获取 JNIEnv
    let env = Java.vm.tryGetEnv();
    let className = env.getObjectClassName(objArray);

    // 不是 jobjectArray,则直接打印类型
    if (!className.startsWith('[L')) {
        console.log(`Argument is not a jobjectArray, actual type: ${className}`);
        return;
    }

    let arrLen = env.getArrayLength(objArray);
    let result = `Object array of type ${className}, length: ${arrLen}\n`;

    for (let i = 0; i < arrLen; i++) {
        let element = env.getObjectArrayElement(objArray, i);
        let elementClassName = env.getObjectClassName(element);
        let castElement = Java.cast(element, Java.use(elementClassName));

        result += `  [${i}] ${elementClassName}: ${castElement}\n`;
    }

    console.log(result.trim());
}

hook native 函数并打印 jobjectArray 传参

javascript 复制代码
function hook_native_func(targetAddress) {

    // Hook 目标地址
    Interceptor.attach(targetAddress, {
        onEnter: function (args) {
            console.log('Entering native function at: ' + targetAddress);
            printObjectArray(args[2])
        },

        onLeave: function (retval) {
            console.log('Leaving native function');
        }
    });
}


setImmediate(function () {
    Java.perform(function () {
        var baseAddress = Module.findBaseAddress("libnative-lib.so");
        hook_native_func(baseAddress.add(0x26058))
    });
})

输出如下:

vbnet 复制代码
Entering native function at: 0x77fe13c058
Object array of type [Ljava.lang.Object;, length: 3
  [0] java.lang.Integer: 283
  [1] com.cyrus.example.jniexample.JNIExampleActivity: com.cyrus.example.jniexample.JNIExampleActivity@b8df529
  [2] java.lang.String: HelloWorld
Leaving native function
相关推荐
qq_429879671 小时前
省略号和可变参数模板
开发语言·c++·算法
CodeWithMe2 小时前
【C/C++】std::vector成员函数清单
开发语言·c++
uyeonashi2 小时前
【QT控件】输入类控件详解
开发语言·c++·qt
zh_xuan6 小时前
c++ 单例模式
开发语言·c++·单例模式
利刃大大9 小时前
【在线五子棋对战】二、websocket && 服务器搭建
服务器·c++·websocket·网络协议·项目
喜欢吃燃面9 小时前
C++刷题:日期模拟(1)
c++·学习·算法
SHERlocked939 小时前
CPP 从 0 到 1 完成一个支持 future/promise 的 Windows 异步串口通信库
c++·算法·promise
虚拟之10 小时前
36、stringstream
c++
我很好我还能学10 小时前
【面试篇 9】c++生成可执行文件的四个步骤、悬挂指针、define和const区别、c++定义和声明、将引用作为返回值的好处、类的四个缺省函数
开发语言·c++
南岩亦凛汀11 小时前
在Linux下使用wxWidgets进行跨平台GUI开发
c++·跨平台·gui·开源框架·工程实战教程