Какой параметр я должен передать Фриде `Obj C .api.class_addMethod ()`, чтобы сделать ее счастливой? - PullRequest
0 голосов
/ 02 февраля 2020

Я хочу использовать Frida для добавления метода класса к существующему классу Objective C в ОС Ma 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(), приложенное приложение и Frida REPL оба замерзли, похоже, что указатели неверны.

Я перепробовал много возможных значений параметров в течение всей ночи, но все еще могу понять проблема вне Что не так с моим кодом?

1 Ответ

1 голос
/ 02 февраля 2020

Только две проблемы:

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

...