【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用

04-13 1023阅读

越狱iPhone安装Frida

本文的方法适用于已越狱的iPhone手机

打开Cydia,软件源,编辑(右上角),添加(左上角):https://build.frida.re

【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用

然后搜索Frida,点击安装

【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用

参考:https://blog.csdn.net/boildoctor/article/details/122769942

安装指定版本Frida

iOS上的Frida版本需要和PC上的Frida版本保持一致,所以有时候需要安装指定版本Frida

下载指定版本deb包:

https://github.com/frida/frida/releases

例如:frida_15.2.2_iphoneos-arm.deb

【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用

通过XFTP将deb拷贝至手机/private/var/tmp目录(也就是/tmp目录)

【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用

ssh进入手机 /tmp目录,执行安装:

dpkg -i xx.deb

参考:https://cloud.tencent.com/developer/article/2160543

使用Frida

在iPhone上启动Frida-server后,将iPhone通过USB连接至PC

PC上安装Frida,通过命令行输入命令 或 运行脚本

frida-ls-devices 查看电脑连接的iOS设备信息

【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用

frida-ps -Ua 查看正在运行的应用

【iOS安全】越狱iOS安装Frida | 安装指定版本Frida | Frida使用

frida hook 类函数

  • 函数名以”+”开头的,如:“+ URLWithString:”,可以直接通过类名调用方法,相当于java中的static函数
    #coding=utf-8
    import frida, sys 
    jscode = """
    if(ObjC.available){
        console.log('\\n[*] Starting Hooking');
        var _className = "JDJR_HackersInfo"; 
        var _methodName = "+ judgementJailbreak";
        var hooking = ObjC.classes[_className][_methodName]; 
        console.log('className is: ' + _className + ' and methodName is: ' + _methodName);
        Interceptor.attach(hooking.implementation,{
            onEnter: function(args) {
                //args[0]:self
                //args[1]:The selector
                //args[2]:第一个参数
                
                console.log(' hook success ')
                this._className = ObjC.Object(args[0]).toString();
                this._methodName = ObjC.selectorAsString(args[1]);
                // console.log('Detected call to: ');
                // console.log('[-] Detected call to:  ' + this._className + ' --> ' + this._methodName);
                // console.log('\\n----------------' + this._methodName + '----------------');
                // console.log('arg2:\\n' + ObjC.Object(args[2]).toString());
                //console.log('called from:\\n' + Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\\n') + '\\n');
                //print_arguments(args);
            },
            //onLeave.function(returnValue)被拦截函数调用之后回调 其中returnValue表示原始函数的返回值
            onLeave:function(returnValue){
                // console.log('Return value of: ');
                // console.log(' ' + this._className + ' --> ' + this._methodName);
                // var typeValue = Object.prototype.toString.call(returnValue);
                // console.log("\\t Type of return value: " + typeValue);
                // console.log("\\t Return Value: " + returnValue);
                console.log("old Return Value: " + ObjC.Object(returnValue));
                var newRet = ObjC.classes.NSString.stringWithString_("1");
                returnValue.replace(newRet);
                console.log("new Return Value: " + ObjC.Object(returnValue));
                
            }
        });
    }
    """
    bundle = 'xxx.xxx.xxx'
    device = frida.get_usb_device() #连接usb设备 参数:超时时长
    pid = device.spawn([bundle]) #启动指定bundleId的app
    session = device.attach(pid) #附加到app
    script = session.create_script(jscode) #创建frida javaScript脚本
    script.load() #load脚本到app进程中 这样即注入成功
    device.resume(pid) #恢复app运行
    sys.stdin.read()#读取打印日志
    

    frida hook 实例函数

    • 函数名以“-”开头的需要找到一个实例化的对象,然后再调用方法
      • 如果内存中没有这样的对象

        这种情况需要手动生成一个实例,用法为ObjC.classes.类名.alloc()

      • 如果内存中存在实例化后的对象

        这种情况需要先找出一个类的实例,使用var tmp=ObjC.chooseSync(ObjC.classes.类名),例如:

        ObjC.chooseSync(ObjC.classes.PARSHealthPedometer10thHomeViewController)[0]

        其中[0]表示取找到的实例中的第一个实例,可根据实际情况换成其他的实例。

        #coding=utf-8
        import frida, sys 
        jscode = """
        if(ObjC.available){
            console.log('\\n[*] Starting Hooking');
            // setToken: 有内容
            var _className = "WLRequestInfo"; 
            var _methodName = "- setToken:"; 
            // var hookingclass = ObjC.chooseSync(ObjC.classes[_className])[0]; //如果内存中存在实例化后的对象,需要先找出一个类的实例
            var hookingclass = ObjC.classes[_className].alloc(); //如果内存中没有实例化后的对象,手动实例化
            var hooking = hookingclass[_methodName];
            console.log('className is: ' + _className + ' and methodName is: ' + _methodName);
            Interceptor.attach(hooking.implementation,{
                onEnter: function(args) {
                    //args[0]:self
                    //args[1]:The selector
                    //args[2]:第一个参数
                    // console.log(' hook success ')
                    this._className = ObjC.Object(args[0]).toString();
                    this._methodName = ObjC.selectorAsString(args[1]);
                    // console.log('Detected call to: ');
                    // console.log('[-] Detected call to:  ' + this._className + ' --> ' + this._methodName);
                    
                    // console.log('\\n[-]' + this._className + ' --> ' + this._methodName + ' : ');
                    console.log('\\n----------------' + this._methodName + '----------------');
                    console.log('arg2:\\n' + ObjC.Object(args[2]));
                    console.log('called from:\\n' + Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\\n') + '\\n');
                    //print_arguments(args);
                },
                //onLeave.function(returnValue)被拦截函数调用之后回调 其中returnValue表示原始函数的返回值
                onLeave:function(returnValue){
                    // console.log('Return value of: ');
                    // console.log(' ' + this._className + ' --> ' + this._methodName);
                    // var typeValue = Object.prototype.toString.call(returnValue);
                    // console.log("Type of return value: " + typeValue);
                    // console.log("Return Value: " + returnValue);
                    console.log("Return Value: \\n" + ObjC.Object(returnValue));
                }
            });
        }
        """
        bundle = 'cn.gov.pbc.dcep'
        device = frida.get_usb_device() #连接usb设备 参数:超时时长
        pid = device.spawn([bundle]) #启动指定bundleId的app
        session = device.attach(pid) #附加到app
        script = session.create_script(jscode) #创建frida javaScript脚本
        script.load() #load脚本到app进程中 这样即注入成功
        device.resume(pid) #恢复app运行
        sys.stdin.read()#读取打印日志
        

        参考:https://mabin004.github.io/2018/08/24/%E5%9C%A8iOS%E4%B8%8A%E4%BD%BF%E7%94%A8Frida/

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]