我想使用Frida在Mac OS上向现有的Objective C类添加类方法。在阅读Frida docs之后,我尝试了以下代码:
const NSString = ObjC.classes.NSString
function func (n) { console.log(n) }
var nativeCb = new NativeCallback(func, 'void', ['int'])
ObjC.api.class_addMethod(
NSString.handle,
ObjC.selector('onTest:'),
nativeCb,
ObjC.api.method_getTypeEncoding(nativeCb)
)
上面的代码看起来很简单。但是,在ObjC.api.class_addMethod()
调用之后,附加的App和Frida REPL都冻结了,看起来指针不正确。
我整夜尝试了许多可能的参数值,但仍然可以找出问题所在。我的代码有什么问题?
答案 0 :(得分:1)
只有两个问题:
method_getTypeEncoding()
只能在Method
上被调用,而NativeCallback
则不能。您可以将具有与要添加的签名相同签名的现有Objective-C方法的句柄传递给它,或使用Memory.allocUtf8String()
从头开始指定自己的签名。self
:要在其上调用该方法的类/实例。_cmd
:选择器。这是TypeScript中的完整示例:
const { NSAutoreleasePool, NSString } = ObjC.classes;
const onTest = new NativeCallback(onTestImpl, "void", ["pointer", "pointer", "int"]);
function onTestImpl(selfHandle: NativePointer, cmd: NativePointer, n: number): void {
const self = new ObjC.Object(selfHandle);
console.log(`-[NSString onTestImpl]\n\tself="${self.toString()}"\n\tn=${n}`);
}
function register(): void {
ObjC.api.class_addMethod(
NSString,
ObjC.selector("onTest:"),
onTest,
Memory.allocUtf8String("v@:i"));
}
function test(): void {
const pool = NSAutoreleasePool.alloc().init();
try {
const s = NSString.stringWithUTF8String_(Memory.allocUtf8String("yo"));
s.onTest_(42);
} finally {
pool.release();
}
}
function exposeToRepl(): void {
const g = global as any;
g.register = register;
g.test = test;
}
exposeToRepl();
您可以将其粘贴到https://github.com/oleavr/frida-agent-example中,然后在一个运行npm run watch
的终端上,可以使用REPL:frida -n Telegram -l _agent.js
将其加载到正在运行的应用程序中。然后,您可以从REPL中调用register()
来插入新方法,并调用test()
来进行旋转。