如何使用Frida JavaScript API调用被hook函数参数的类方法
Frida调用Event类toString()方法实现方案
分两种常见场景给出对应实现:
场景1:Event为Android Java层类
直接通过Frida的Java API即可调用,示例代码如下:
Java.perform(function() { // 替换为compute方法所在类的完整类名 const TargetClazz = Java.use('com.example.your_package.TargetClass'); TargetClazz.compute.implementation = function(size, event) { // 直接调用event实例的toString方法 const eventContent = event.toString(); console.log('Event打印结果:', eventContent); // 执行原方法逻辑并返回结果 return this.compute(size, event); } })
场景2:Event为Native层C++类
需要先确认toString()的调用方式,分两种情况处理:
子情况A:toString为导出符号
先通过nm/objdump等工具拿到toString和compute方法的mangled符号,直接调用即可,示例代码:
// 替换为你的so名称、compute和toString方法的实际符号 const libPath = 'libyour_target.so'; const computeSym = '_Z7computeiP5Event'; const toStringSym = '_ZNK5Event8toStringEv'; Interceptor.attach(Module.getExportByName(libPath, computeSym), { onEnter: function(args) { this.eventPtr = args[1]; // 构造NativeFunction,成员函数第一个参数默认传this指针 const toStringFunc = new NativeFunction( Module.getExportByName(libPath, toStringSym), 'pointer', // 返回值如果是std::string则为指针,返回char*也为指针 ['pointer'] // 入参为Event*类型的this指针 ); const resultPtr = toStringFunc(this.eventPtr); // 如果toString返回char*直接读 const eventStr = Memory.readUtf8String(resultPtr); // 如果toString返回std::string,用下面的代码读取 // const eventStr = Memory.readUtf8String(Memory.readPointer(resultPtr)); console.log('Native Event打印结果:', eventStr); } })
子情况B:toString为虚函数
提前用逆向工具确认toString在Event类虚函数表中的偏移量,从实例的虚表中取对应函数地址调用即可:
const VIRTUAL_FUNC_OFFSET = 0x10; // 替换为实际的toString虚表偏移 Interceptor.attach(Module.getExportByName(libPath, computeSym), { onEnter: function(args) { const eventPtr = args[1]; // 取虚表首地址 const vtable = Memory.readPointer(eventPtr); // 取对应偏移的函数地址 const toStringAddr = Memory.readPointer(vtable.add(VIRTUAL_FUNC_OFFSET)); const toStringFunc = new NativeFunction(toStringAddr, 'pointer', ['pointer']); const resultPtr = toStringFunc(eventPtr); const eventStr = Memory.readUtf8String(resultPtr); console.log('Native Event打印结果:', eventStr); } })
内容的提问来源于stack exchange,提问作者Kalamada
相关产品推荐
相关产品推荐

