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"})