Frida-RPC 调用

demo

frida-rpc通过调用已加载到内存中的函数,直接获取到结果:

import frida

rdev = frida.get_remote_device()
session = rdev.attach("大姨妈")

scr = """
    rpc.exports = {   
        encrypt(j2, str){
             var res;

             Java.perform(function () {
                var Crypt = Java.use("com.yoloho.libcore.util.Crypt");  
                res = Crypt.encrypt_data(j2, str);
             });

             return res;
        }
    }
    """
script = session.create_script(scr)
script.load()

sign = script.exports.encrypt(0,"38a6b024user/login8GGjp1eHdaK4e22QpCp0kfg==")
print(sign)

解释:在最外层使用rpc.exports导出了encrypt方法的定义,所以在script.exports里就能调用encrypt方法。

类型的处理

在执行frida-rpc时,会涉及到参数类型的处理和转换:

在python中给frida的JavaScript脚本传入参数时,一般有如下几种情况:

  • 字符串/整型/浮点型等直接传递

    import frida
    
    rdev = frida.get_remote_device()
    session = rdev.attach("大姨妈")  
    
    scr = """
    rpc.exports = {   
        encrypt:function(v1,v2,v3,v4,v5){
            console.log(v1,typeof v1);
            var v6 = parseInt(v5);
            console.log(v6,typeof v6);
        }
    }
    """
    script = session.create_script(scr)
    script.load()
    
    # 调用
    script.exports.encrypt(100, "wupeiqi", 19.2, -10, "-1")
    
  • 列表/字典 直接传递

    import frida
    
    rdev = frida.get_remote_device()
    session = rdev.attach("大姨妈") 
    
    scr = """
    rpc.exports = {   
        encrypt:function(v1,v2){
            console.log(v1,typeof v1, v1[0], v1[1]);
            console.log(v2,typeof v2, v2.name, v2.age);
            
            for(let key in v1){
                console.log(key, v1[key] )
            }
            
            for(let key in v2){
                console.log(key, v2[key] )
            }
        }
    }
    """
    script = session.create_script(scr)
    script.load()
    
    script.exports.encrypt([11, 22, 33], {"name": 123, "age": 456})
    
  • 字节,无法直接传递,需转换为列表

    import frida
    
    rdev = frida.get_remote_device()
    session = rdev.attach("大姨妈")  # com.yoloho.dayima
    
    scr = """
    rpc.exports = {   
        encrypt:function(v1){
            console.log(v1, typeof v1);
            // 转换为java的字节数组
            var bs = Java.array('byte', v1);
            console.log(JSON.stringify(bs))
        }
    }
    """
    script = session.create_script(scr)
    script.load()
    
    arg_bytes = "武沛齐".encode('utf-8')
    byte_list = [i for i in arg_bytes]
    script.exports.encrypt(byte_list)
    
  • 某个类的对象,无法直接传递,可以将参数传入,然后在JavaScript调用frida api构造相关对象。

构造StringBuilder对象:

import frida

rdev = frida.get_remote_device()
session = rdev.attach("大姨妈")  

scr = """
rpc.exports = {   
    encrypt:function(v1,v2){

        const StringBuilder = Java.use('java.lang.StringBuilder');;
        var obj = StringBuilder.$new();
        obj.append(v1);
        obj.append(v2);
        var result = obj.toString();
        console.log(result);
    }
}
"""
script = session.create_script(scr)
script.load()

script.exports.encrypt("武沛齐", "666")

构造TreeMap对象:

import frida

rdev = frida.get_remote_device()
session = rdev.attach("大姨妈")  

scr = """
rpc.exports = {   
    encrypt:function(v4){    
        var TreeMap = Java.use("java.util.TreeMap");
        var v4_obj = TreeMap.$new();   
        for(let key in v4){
            v4_obj.put(key,v4[key])
        }
        
        console.log(v4_obj)
        console.log( v4_obj.get("name") )
        console.log( v4_obj.get("age") )
        
        var keyset = v4_obj.keySet();
        var it = keyset.iterator();
        while(it.hasNext()){
            var keystr = it.next().toString();
            var valuestr = v4_obj.get(keystr).toString();
            console.log(keystr, valuestr);
        }  
    }
}
"""
script = session.create_script(scr)
script.load()

script.exports.encrypt( {"name": "root", "age": "18"})
  • JavaScript相当于中介,用于连接python与java,可以完成一些数据的转换工作:

    import frida
    
    rdev = frida.get_remote_device()
    session = rdev.attach("大姨妈")  # com.yoloho.dayima
    
    scr = """
    rpc.exports = {   
        encrypt:function(bytesList){
            // 先处理拼接好的数据(字节数组)
            var bArr = [];
            for(var i=0; i<bytesList.length; i+=2){
                var item = (parseInt(bytesList[i],16) << 4) + parseInt(bytesList[i+1],16);
                bArr.push(item);
            }
            
            console.log(bArr);
                    
            // 转换为java的字节数组
            var bs = Java.array('byte', bArr);
        }
    }
    """
    script = session.create_script(scr)
    script.load()
    arg_bytes = "wupeiqi".encode('utf-8')
    byte_list = [i for i in arg_bytes]
    script.exports.encrypt(byte_list)
    





【PS:Android 逆向进阶专栏地址:https://blog.csdn.net/dafan0/category_12682484.html】

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值