frida调试iOS(修改参数,调用其他函数)

763 阅读1分钟

(1)在onEnter中****修改函数的参数

修改字符串类型和数字类型的参数,frida脚本:

onEnter(log, args, state) {
    log(`-[UserInfoManager svr_resetPassword:${ObjC.Object(args[2])} oldPassword:${ObjC.Object(args[3])} resetType:${args[4]} completion:${args[5]}]--1`);

    try {
        // 替换args[2]为"11111111"
        var newStr = ObjC.classes.NSString.stringWithString_("11111111");
        args[2] = newStr;
        // 将 args[4] 替换为 0x2
        args[4] = ptr(0x2);
    } catch (error) {
        log(`替换password--Error: ${error.message}`);
    }
    log(`-[UserInfoManager svr_resetPassword:${ObjC.Object(args[2])} oldPassword:${ObjC.Object(args[3])} resetType:${args[4]} completion:${args[5]}]--2`);

  }

实现字符串参数替换:

var newStr = ObjC.classes.NSString.stringWithString_("11111111");
args[2] = newStr;

实现数字参数替换:

args[4] = ptr(0x2);

(2)在某函数内调用其他函数

在函数-[TSRootViewController viewDidLoad]的onLeave中调用+[TSInstallationController handleAppInstallFromFile:completion:]函数,并传递参数:

onLeave(log, retval, state) {

    log("-[TSRootViewController viewDidLoad]--onLeave");
    try {
      const className = 'TSInstallationController';
      const methodName = 'handleAppInstallFromFile:completion:';

      // 要传递的参数
      const ipaFilePath = ObjC.classes.NSString.stringWithString_("/var/mobile/Downloads/test-ipa-scan.ipa");

      const completionBlock = ptr(0x0);
      log("test--0-1");

      const TSInstallationController = ObjC.classes.TSInstallationController;
      log("test--0-2--TSInstallationController="+TSInstallationController);

      // 获取方法引用
      const handleAppInstallFromFileCompletion = TSInstallationController['+ handleAppInstallFromFile:completion:'];
      log("test--0-3--handleAppInstallFromFileCompletion="+handleAppInstallFromFileCompletion);

      // 调用方法
      handleAppInstallFromFileCompletion.call(TSInstallationController, ipaFilePath, completionBlock);
      log("Successfully installed");

    } catch (error) {
      log("Error calling handleAppInstallFromFile:", error);
    }


}

(3)监控网络函数-[NSMutableURLRequest setHTTPBody:]

打印请求的url和body中的数据

  onEnter(log, args, state) {
    try{
        this.curTime = (Date.now()).toString() + '.' + Math.round(Math.random() * 10000).toString();

        // log('hook--time:'+this.curTime+'==method_1:'+`-[NSMutableURLRequest setHTTPBody:]`);
        log('hook--time:'+this.curTime+'==method_2:'+`-[NSMutableURLRequest setHTTPBody:${ObjC.Object(args[2])}]`);

        // 打印 URLRequest 中的 URL
        var request = ObjC.Object(args[0]);  // 获取 NSMutableURLRequest 对象
        var url = request.URL();  // 获取 URL 属性
        if (url) {
            log('hook--time:' + this.curTime + '==URL: ' + url.absoluteString().toString());  // 打印 URL
        } else {
            log('hook--time:' + this.curTime + '==URL is null or undefined');
        }
        
        var exp = args[2];
        if (!exp && typeof(exp)!="undefined" && exp!=0)
        {
          // alert("is--null");
        }
        else{
          var objcData = ObjC.Object(args[2]);  //NSData
          if( objcData && objcData.length()>1){
            var strBody = objcData.bytes().readUtf8String(objcData.length()); //NSData 转换成 string
            log('hook--time:'+this.curTime+'=='+"--parameter--=" + strBody);
            // log('hook--time:'+this.curTime+'=='+"--return--=" + strBody);

          }
          else {

          }
        }

        log('hook--time:'+this.curTime+'=='+'Backtrace:\n\t' + Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n\t'));

    }
    catch(err){

    }

  },