Только две проблемы:
method_getTypeEncoding()
можно вызвать только на Method
, а NativeCallback
- нет. Вы можете передать ему дескриптор существующего метода Objective- C, который имеет ту же сигнатуру, что и добавляемый вами, или использовать Memory.allocUtf8String()
, чтобы указать свою собственную подпись с нуля. - Objective- * Методы 1040 * на уровне C ABI имеют два неявных аргумента, предшествующих аргументам метода. Это:
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()
, чтобы принять его за спин.