eumnq8 发表于 2021-1-29 14:21:57

frida objc常用脚本

1、打印调用栈
在hook到的函数中加入以下代码:
console.log('tBacktrace:nt' + Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('nt'));

2、调用native函数
var address = Module.findExportByName('libsqlite3.dylib', 'sqlite3_sql');
var sql = new NativeFunction(address, 'char', ['pointer']);
sql(statement);

3、数据类型和转换
如果对一个变量的类型不确定,可以使用如下代码确定其类型:
console.log("Type of args -> " + new ObjC.Object(args).$className)
一些常用的数据类型转换:

【1】NSData转String
var data = new ObjC.Object(args);
Memory.readUtf8String(data.bytes(), data.length());
如果为null的不需要第二个参数

【2】NSData转二进制数据
var data = new ObjC.Object(args);
Memory.readByteArray(data.bytes(), data.length());

【3】遍历NSArray
var array = new ObjC.Object(args);
/*
* Be sure to use valueOf() as NSUInteger is a Number in
* 32-bit processes, and UInt64 in 64-bit processes. This
* coerces it into a Number in the latter case.
*/
var count = array.count().valueOf();
for (var i = 0; i !== count; i++) {
var element = array.objectAtIndex_(i);
}
【4】遍历NSDictionary
var dict = new ObjC.Object(args);
var enumerator = dict.keyEnumerator();
var key;
while ((key = enumerator.nextObject()) !== null) {
var value = dict.objectForKey_(key);
}
【5】NSKeyedArchiver
var parsedValue = ObjC.classes.NSKeyedUnarchiver.unarchiveObjectWithData_(value);

【6】读一个结构体
Memory.readU32(args.add(4));

【7】枚举所有的类
for (var className in ObjC.classes)
    {
      if (ObjC.classes.hasOwnProperty(className))
      {
            send(className);
      }
}

【8】枚举一个类的所有method
if (ObjC.available)
{
    try
    {
      var className = "NSURL";
      var methods = eval('ObjC.classes.' + className + '.$methods');
      for (var i = 0; i < methods.length; i++)
      {
            try
            {
                if (methods.indexOf("fileURLWithPath") > -1)
                console.log("[-] "+methods);
            }
            catch(err)
            {
                console.log("[!] Exception1: " + err.message);
            }
      }
    }
    catch(err)
    {
      console.log("[!] Exception2: " + err.message);
    }
}
【9】Hook一个method
打印参数时需要注意:
args:self
args:The selector (openURL:)
args:The first param
if (ObjC.available)
{
    try
    {
      var className = "JailbreakDetectionVC";
      var funcName = "- isJailbroken";
      var hook = eval('ObjC.classes.' + className + '["' + funcName + '"]');
      console.log("[*] Class Name: " + className);
      console.log("[*] Method Name: " + funcName);
      Interceptor.attach(hook.implementation, {
          onEnter: function(args) {
            console.log("aaaa");
            console.log("param:"+args+" type:"+typeof args);
          },
          onLeave: function(retval) {
            console.log("Return value-> (type:"+typeof retval+",value:"+retval+")");
            newretval = ptr("0x0")
            retval.replace(newretval)
          }
      });
    }
    catch(err)
    {
      console.log("[!] Exception2: " + err.message);
    }
}

页: [1]
查看完整版本: frida objc常用脚本