Frida Hook Native:jobjectArray 参数解析

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

env.js

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

https://github.com/frida/frida-java-bridge/blob/main/lib/env.js

word/media/image1.png

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

let env = Java.vm.tryGetEnv()

word/media/image2.png

文档:https://frida.re/docs/javascript-api/

获取数组长度

let arrLen = env.getArrayLength(objArray)
console.log('array length is: ' + arrLen);

元素类型判断

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

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

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

}

获取数组元素

let element = env.getObjectArrayElement(objArray, i)

Int 元素读取

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

Long 元素读取

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

Float 元素读取

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

Double 元素读取

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

字符串 元素读取

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

word/media/image3.png

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

Object 元素读取

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 的元素类型和值

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 传参

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))
    });
})

输出如下:

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值