墨锋
Published on 2025-03-29 / 4 Visits
0
0

[翻译]FRIDA官方文档-示例-iOS

iOS

Objective-C 方法调用规范

Frida 通过将 Objective-C 方法选择器中的 : 替换为 _ 来提供封装调用:

 // 调用 +[NSJSONSerialization dataWithJSONObject:options:error:]
 ObjC.classes.NSJSONSerialization.dataWithJSONObject_options_error_(...)
 ​
 // NSString *helloWorldString = @"Hello, World!";
 var helloWorldString = ObjC.classes.NSString.stringWithString_("Hello, World!");
 ​
 // 调用 [helloWorldString characterAtIndex:0]
 helloWorldString.characterAtIndex_(0)

提示:若运行结果不符合预期,可能是操作了错误的数据类型。可通过以下命令确认实际类型:

 console.log('args[2] 类型 -> ' + new ObjC.Object(args[2]).$className)

数据类型转换

NSData 转字符串

 const data = new ObjC.Object(args[2]);
 data.bytes().readUtf8String(data.length());

提示:若字符串以 null 结尾,可不指定字节长度参数

NSData 转二进制数据

 const data = new ObjC.Object(args[2]);
 data.bytes().readByteArray(data.length(

集合操作

遍历 NSArray

 const array = new ObjC.Object(args[2]);
 /* 
  * 必须使用 valueOf() 转换,因为 NSUInteger 在
  * 32 位进程中是 Number 类型,在 64 位进程中
  * 是 UInt64 类型
  */
 const count = array.count().valueOf();
 for (let i = 0; i !== count; i++) {
   const element = array.objectAtIndex_(i);
 }

遍历 NSDictionary

 const dict = new ObjC.Object(args[2]);
 const enumerator = dict.keyEnumerator();
 let key;
 while ((key = enumerator.nextObject()) !== null) {
   const value = dict.objectForKey_(key);
 }

解档 NSKeyedArchiver

 const parsedValue = ObjC.classes.NSKeyedUnarchiver.unarchiveObjectWithData_(value);

内存操作

读取结构体数据

 // 读取 args[0] 指针偏移 4 字节处的 uint32 值
 args[0].add(4).readU32();

UI 交互示例

iOS 7 弹窗实现

 const UIAlertView = ObjC.classes.UIAlertView;
 const view = UIAlertView.alloc().initWithTitle_message_delegate_cancelButtonTitle_otherButtonTitles_(
     'Frida',
     'Hello from Frida',
     NULL,
     'OK',
     NULL);
 view.show();
 view.release();

iOS 8+ 弹窗实现

 // 定义作为 handler 参数的 Block
 const handler = new ObjC.Block({
   retType: 'void',
   argTypes: ['object'],
   implementation() {}
 });
 ​
 // 获取类引用
 const UIAlertController = ObjC.classes.UIAlertController;
 const UIAlertAction = ObjC.classes.UIAlertAction;
 const UIApplication = ObjC.classes.UIApplication;
 ​
 // 使用 GCD 在主线程执行
 ObjC.schedule(ObjC.mainQueue, () => {
   // 使用枚举数值指定弹窗样式
   const alert = UIAlertController.alertControllerWithTitle_message_preferredStyle_('Frida', 'Hello from Frida', 1);
   const defaultAction = UIAlertAction.actionWithTitle_style_handler_('OK', 0, handler);
   alert.addAction_(defaultAction);
   UIApplication.sharedApplication().keyWindow().rootViewController()
     .presentViewController_animated_completion_(alert, true, NULL);
 });

方法拦截示例

监控 openURL: 调用

 const openURL = ObjC.classes.UIApplication['- openURL:'];
 ​
 Interceptor.attach(openURL.implementation, {
   onEnter(args) {
     // Objective-C 方法参数结构:
     // 0: 'self'
     // 1: 方法选择器 (openURL:)
     // 2: NSURL 参数
     const url = new ObjC.Object(args[2]).absoluteString().toString();
     console.log('正在打开 URL: ' + url);
   }
 });

关键术语说明:

  1. 选择器(Selector) - Objective-C 的方法名标识

  2. Block - Objective-C 的匿名函数对象

  3. GCD (Grand Central Dispatch) - iOS 的多线程技术

  4. 主线程队列(mainQueue) - UI 操作必须执行的线程队列

  5. NSKeyedArchiver - 苹果的对象序列化方案


原文链接:iOS | Frida • A world-class dynamic instrumentation toolkit

翻译来源:DeepSeek


Comment