1.1 Frida-rpc常用脚本

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

  • python程序调用时,传入参数?
  • frida的JavaScript脚本如何获取参数?
  • JavaScript的参数如何转换到 Java中所需的类型?

1.1.1 python传参

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

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

    import frida
    
    rdev = frida.get_remote_device()
    session = rdev.attach("大姨妈")  # com.yoloho.dayima
    
    scr = """
    rpc.exports = {   
        encrypt:function(v1,v2,v3,v4,v5){
        
            console.log(v1,typeof v1);
            console.log(v2,typeof v2);
            console.log(v3,typeof v3);
            console.log(v4,typeof v4);
            console.log(v5,typeof v5);
            
            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("大姨妈")  # com.yoloho.dayima
    
    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,v2){
            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构造相关对象。

    import frida
    
    rdev = frida.get_remote_device()
    session = rdev.attach("大姨妈")  # com.yoloho.dayima
    
    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")
    

1.1.2 JavaScript

在frida的脚本中其实就用编写JavaScript代码,所以我们对于内部的执行过程完全是使用JavaScript语法来实现。

import frida

rdev = frida.get_remote_device()
session = rdev.attach("大姨妈")  # com.yoloho.dayima

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(bytesList){
        // [11,22,33,11,22,42,13,4]
        
        // 先处理拼接好的数据(字节数组)
        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)

1.1.3 frida相关

在编写frida的JavaScript脚本时,我们经常会:

  • 调用Java中已编写的好的类、方法等功能
  • 执行目标方法时,传入相关参数。

这种情况下,就需要使用frida相关API来完成JavaScript和Java中的调用。

import frida

rdev = frida.get_remote_device()
session = rdev.attach("大姨妈")  # com.yoloho.dayima

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

        // 1.整型和字符串直接用
        console.log(v1,v2);
        
        // 2.字节数组
        var v3_obj = Java.array('byte',v3);
        console.log(v3_obj, JSON.stringify(v3_obj));
        
        // 3.TreeMap对象   obj.get("xx")
        var TreeMap = Java.use("java.util.TreeMap");
        var v4_obj = TreeMap.$new();   
        for(let key in v4){
            //console.log(key,v4[key]);
            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()

v3 = [i for i in "wupeiqi".encode('utf-8')]

script.exports.encrypt(10, "wupeiqi", v3, {"name": "root", "age": "18"})
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐