macOS应用Frida调试:如何通过脚本获取r12结果?
Frida调试macOS应用获取r12值的解决方案
问题分析
你的伪代码流程是:
- 调用
[Helper cfunc]获取一个指针 - 解引用该指针得到实际函数地址
- 调用这个函数得到ObjC对象
- 调用对象的
dataUsingEncoding:0x4(对应NSUTF8StringEncoding)得到最终的r12值
你之前的脚本错误在于直接将[Helper cfunc]的返回值当作函数指针使用,但实际上需要解引用这个指针才能拿到真正的函数入口,这导致了内存访问错误。
正确脚本实现
// 1. 获取[Helper cfunc]返回的指针(指向函数的指针) const funcPtrPtr = ObjC.classes.Helper.cfunc(); // 2. 解引用指针,读取实际函数的内存地址 const actualFuncAddr = ptr(funcPtrPtr).readPointer(); // 3. 用NativeFunction包装实际函数,参数类型选pointer适配macOS 64位调用规范 const actualFunc = new NativeFunction(actualFuncAddr, 'pointer', ['pointer', 'pointer', 'pointer']); // 4. 调用函数获取ObjC对象指针 const objPtr = actualFunc(NULL, NULL, NULL); // 5. 将原生指针转为ObjC对象,调用dataUsingEncoding:方法 const nsObj = new ObjC.Object(objPtr); const r12Data = nsObj.dataUsingEncoding_(0x4); // 0x4对应NSUTF8StringEncoding // 可选:将NSData转成字符串查看内容 const resultStr = r12Data.UTF8String(); console.log("r12对应的NSData实例:", r12Data); console.log("r12内容转字符串:", resultStr);
关键注意点
[Helper cfunc]返回的是指针的指针,必须通过readPointer()解引用才能拿到真正的函数入口地址- 参数类型选择
pointer而非uint8,是因为macOS 64位环境下,原生函数的空参数用指针类型传递更符合调用规范,避免类型宽度不匹配引发的错误 - 函数返回的指针需要用
ObjC.Object()包装后,才能调用Objective-C的实例方法
内容的提问来源于stack exchange,提问作者awalol
相关产品推荐
相关产品推荐

