当前位置: 首页 > news >正文

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
http://www.dtcms.com/a/107462.html

相关文章:

  • SQL Server 增删改查详解
  • 使用pytesseract和Cookie登录古诗文网~(python爬虫)
  • 从Hugging Face下载Qwen/Qwen2-Audio-7B-Instruct模型到本地运行,使用python实现一个音频转文字的助手
  • 树莓派超全系列教程文档--(21)用户配置
  • 芋道源码——Spring Cloud Bus RocketMQ 入门
  • 《全栈+双客户端Turnkey方案》架构设计图
  • 软件版本号递增应该遵循的规范
  • 分层防御:对称与非对称加密如何守护数字世界
  • 0402-对象和类(访问器 更改器 日期类)
  • 北方算网获邀在中关村论坛发言 解析人工智能+产业落地核心路径
  • 【数据库原理及安全实验】实验一 数据库安装与创建
  • openEuler24.03 LTS下安装HBase集群
  • YOLO学习笔记 | 基于YOLOv5的车辆行人重识别算法研究(附matlab代码)
  • Ubuntu 22.04 安装和运行 EDK2 超详细教程
  • 门控循环单元(GRU)基础学习与实例:电影评论情感分类
  • 微信小程序开发-01.介绍
  • Java 基础-29-final关键字-详解
  • 当网页受到DDOS网络攻击有哪些应对方法?
  • 【mysql 的安装及使用】
  • SuperMap GIS基础产品FAQ集锦(20250402)
  • 02_使用Docker在服务器上部署Jekins实现项目的自动化部署
  • Docker Registry 清理镜像最佳实践
  • 06-21-自考数据结构(20331)- 查找技术-动态查找例题分析
  • 02-Docker 使用
  • libevent 核心数据结构
  • AI 数字人短视频数字人源码部署揭秘:开启虚拟内容创作新纪元​
  • 工作后考研
  • 为什么在Transformer模型处理的输入维度会因为图像分辨率大小的不同而导致patch数量的变化,但是不需要修改模型的维度参数?
  • C语言数组知识点
  • 【C语言】深入理解指针(四):回调函数与qsort函数的奥秘