Frida的相关API学习记录

01 静态方法和实列方法的Hook

不需要区分修饰符,也不需要区分静态和实列方法,Hook代码的写法一模一样的

var money = Java.use("com.xiaojianbang.hook.Money");
    //hook实例方法
    money.getInfo.implementation = function () {
        var result = this.getInfo();
        console.log("money.getInfo result: ", result)
        return result;
    }
    //hook静态方法
    money.setFlag.implementation = function (a) {
        console.log("money.setFlag param: ", a);
        return this.setFlag(a);
    }

02函数参数和返回值的修改

var money = Java.use("com.xiaojianbang.hook.Money");
    var str = Java.use("java.lang.String");
    money.getInfo.implementation = function () {
        var result = this.getInfo();
        console.log("money.getInfo result: ", result);
     `  return str.$new("xiaojianbang");`
        //上述字符串"xiaojianbang"是JS的string,而被hook的Java方法返回值是Java的String
        //因此,可以主动调用Java方法转成Java的String
        //但是为了方便起见,通常会直接直接返回JS的string,这时frida会自动处理,代码类似如下
        //return "xiaojianbang";
        //Java的类型可以调用Java的方法,JS的类型可以调用JS的方法
        //区分清楚何时是Java的类型,何时是JS的类型,有助于代码的编写
        //frida在参数传递的处理上也类似
    }
    money.setFlag.implementation = function (a) {
        console.log("money.setFlag param: ", a);
        return this.setFlag("xiaojianbang");
    }

03构造方法的hook $init

 var money=Java.use("类名全路径");
	 money.$init.implementation=function(a,b){
 		return this.$init("参数1","参数2")
 	 }

04 对象参数的构造与修改 $new

 var wallet=Java.use("类名全路径");
 var money=Java.use("类名全路径");
 //对象修改
wallet.deposit.implementation=function(a){
     return this.deposit(money.$new("1","2"));
}
//参数修改
 var wallet = Java.use("com.xiaojianbang.hook.Wallet");
    wallet.deposit.implementation = function (a) {
      `  a.setAmount(2000);`
        console.log("wallet.deposit param: ", a.getInfo());
        return this.deposit(a);
    }

05HashMap打印

var utils = Java.use("com.xiaojianbang.hook.Utils");
    var stringBuilder = Java.use("java.lang.StringBuilder");
    utils.shufferMap.implementation = function (a) {
        var key = a.keySet();
        var it = key.iterator();
        var result = stringBuilder.$new();
        while(it.hasNext()){
            var keystr = it.next();
            var valuestr = a.get(keystr);
            result.append(valuestr);
        }
        console.log("utils.shufferMap param: ", result.toString());
        var result = this.shufferMap(a);
        console.log("utils.shufferMap result: ", result);
        return result;
    }

06 方法重载的Hook

var utils = Java.use("com.xiaojianbang.hook.Utils");
    utils.getCalc.overload('int', 'int').implementation = function (a, b) {
        console.log("utils.getCalc param: ", a, b);
        return this.getCalc(a, b);
    }
    utils.getCalc.overload('int', 'int', 'int').implementation = function (a, b, c) {
        console.log("utils.getCalc param: ", a, b, c);
        return this.getCalc(a, b, c);
    }
    utils.getCalc.overload('int', 'int', 'int', 'int').implementation = function (a, b, c, d) {
        console.log("utils.getCalc param: ", a, b, c, d);
        return this.getCalc(a, b, c, d);
    }

07 hook方法的所有加载

 var utils = Java.use("com.xiaojianbang.hook.Utils");
   ` var overloadsArr = utils.getCalc.overloads;`
    for (var i = 0; i < overloadsArr.length; i++) {
        overloadsArr[i].implementation = function () {
            showStacks();
            var params = "";
            for (var j = 0; j < arguments.length; j++) {
                params += arguments[j] + " ";
            }
            console.log("utils.getCalc is called! params is: ", params);
            // if(arguments.length == 2){
            //     return this.getCalc(arguments[0], arguments[1]);
            // }else if(arguments.length == 3){
            //     return this.getCalc(arguments[0], arguments[1], arguments[2]);
            // }else if(arguments.length == 4){
            //     return this.getCalc(arguments[0], arguments[1], arguments[2], arguments[3]);
            // }
            console.log(this);
            return this.getCalc.apply(this, arguments);
        }
    }

08 主动调用

  1. 静态方法,直接调用
 var money = Java.use("com.xiaojianbang.hook.Money");
 money.setFlag("xiaojianbang");
  1. 实列方法,方法1为创建新对象(一般不用)\
var moneyObj = money.$new("卢布", 1000);
    console.log(moneyObj.getInfo());
  1. 实列方法,获取已有对象(Java.choose)
    Java.choose
  Java.choose("类名全路径",{
	  onMatch: function (obj){
            console.log(obj.getInfo());
        },
        onComplete: function (){
            console.log("内存中的Money对象搜索完毕");
        }
    });

09 获取和修改类的字段名

  1. 静态字段
    value
var money = Java.use("com.xiaojianbang.hook.Money");
        console.log(money.flag.value);
        money.flag.value = "VX: xiaojianbang8888";
        console.log(money.flag.value);
  1. 实例字段 创建新对象(一般不用)
 var moneyObj = money.$new("欧元", 2000);
        console.log(moneyObj.currency.value);
        moneyObj.currency.value = "xiaojianbang currency";
        console.log(moneyObj.currency.value);
  1. 实列字段,获取已有对象(正常用)
Java.choose("com.xiaojianbang.hook.Money", {
            onMatch: function (obj) {
                console.log("Java.choose Money: ", obj.currency.value);
            }, onComplete: function () {
            }
        });
        // 如果字段名和方法名一样 需要加下划线前缀
        ` Java.choose`
        Java.choose("com.xiaojianbang.hook.BankCard", {
            onMatch: function (obj) {
                console.log("Java.choose BankCard: ", obj._accountName.value);
            }, onComplete: function () {

            }
        });

10 hook内部类与匿名类

$ 内部类

Java.choose("com.xiaojianbang.hook.Wallet$InnerStructure", {
            onMatch: function (obj) {
				console.log(
							"Java.choose Wallet$InnerStructure: ", obj.bankCardsList.value
					);
        	    }, onComplete: function () {
            }
        });

$1 匿名类

 var money$1 = Java.use("com.xiaojianbang.app.MainActivity$1");
        money$1.getInfo.implementation = function () {
            var result = this.getInfo();
            console.log("money.getInfo result: ", result);
            return result;
        }

11 枚举所有已加载的类与枚举类的所有方法

   1. 枚举的是已经加载的类,没有加载的类不会出现
   2. 出现的类,你也不一定能够hook到,原因是类加载器的关系
`Java.enumerateLoadedClassesSync()`
console.log(Java.enumerateLoadedClassesSync().join("\n"));
        var wallet = Java.use("com.xiaojianbang.hook.Wallet");
        var methods = wallet.class.getDeclaredMethods();
        var constructors = wallet.class.getDeclaredConstructors();
        var fields = wallet.class.getDeclaredFields();
        var classes = wallet.class.getDeclaredClasses();

12 hook类的所有方法

.overloads

 function hookFunc(methodName) {
        console.log(methodName);
        var overloadsArr = utils[methodName].overloads;
        for (var j = 0; j < overloadsArr.length; j++) {
            overloadsArr[j].implementation = function () {
                var params = "";
                for (var k = 0; k < arguments.length; k++) {
                    params += arguments[k] + " ";
                }
                console.log("utils." + methodName + " is called! params is: ", params);
                return this[methodName].apply(this, arguments);
            }
        }
    }
    var utils = Java.use("com.xiaojianbang.hook.Utils");
    var methods = utils.class.getDeclaredMethods();
    for (var i = 0; i < methods.length; i++) {
        var methodName = methods[i].getName();
        hookFunc(methodName);
    }

13 注入类 Java.registerClass(一般不用这个)

 const MyWeirdTrustManager = Java.registerClass({
        name: 'com.xiaojianbang.app.MyRegisterClass',
        implements: [Java.use("com.xiaojianbang.app.TestRegisterClass")],
        fields: {
            description: 'java.lang.String',
            limit: 'int',
        },
        methods: {
            $init() {
                console.log('Constructor called');
            },
            test1: [{
                returnType: 'void',
                argumentTypes: [],
                implementation() {
                    console.log('test1 called');
                }
            }, {
                returnType: 'void',
                argumentTypes: ['java.lang.String', 'int'],
                implementation(str, num) {
                    console.log('test1(str, num) called', str, num);
                }
            }],
            test2(str, num) {
                console.log('test2(str, num) called', str, num);
                return null;
            },
        }
    });
    var myObj = MyWeirdTrustManager.$new();
    myObj.test1();
    myObj.test1("xiaojianbang1", 100);
    myObj.test2("xiaojianbang2", 200);
    myObj.limit.value = 10000;
    console.log(myObj.limit.value);

14 Frida 注入dex

   Java.openClassFile("/data/local/tmp/patch.dex").load();
    var test = Java.use("com.xiaojianbang.myapplication.Test");
    var utils = Java.use("com.xiaojianbang.hook.Utils");
    utils.shufferMap.implementation = function (map) {
        var result = test.print(map);
        console.log(result);
        return result;
    }

15 hook枚举类(Java.choose)

Java.choose("com.xiaojianbang.app.Season", {
        onMatch: function (obj) {
            console.log(obj.ordinal());
        }, onComplete: function () {

        }
    })
    console.log(Java.use("com.xiaojianbang.app.Season").values());

16 Frida写文件

var ios = new File("/sdcard/xiaojianbang.txt", "w");
ios.write("xiaojianbang is very good!!!\n");
ios.flush();
ios.close();

17 Java.cast

向上转型的,不能用toString直接得到结果,比如Map、List类型的打印
    var utils = Java.use("com.xiaojianbang.hook.Utils");
    utils.shufferMap2.implementation = function (map) {
        console.log("map: ", map);
        var result = Java.cast(map, Java.use("java.util.HashMap"));
        console.log("map: ", result);
        return this.shufferMap2(result);
    }

18 数组的构建

//Java.array("Ljava.lang.Object;", ...)
var utils = Java.use("com.xiaojianbang.hook.Utils");
//console.log(
//	utils.myPrint(["xiaojianbang", "QQ:24358757", "VX:xiaojianbang8888", "公众号:非攻code"])
//);
var strarr = Java.array(
	"Ljava.lang.String;", 
	["xiaojianbang", "QQ:24358757", "VX:xiaojianbang8888", "公众号:非攻code"]
);
console.log(utils.myPrint(strarr));

19 Object数组的构建

可变参数本质上就是数组,按数组处理即可
    只需要处理基本数据类型的包装,其他的Frida会处理
var utils = Java.use("com.xiaojianbang.hook.Utils");
var bankCard = Java.use("com.xiaojianbang.hook.BankCard");
var bankCardObj = bankCard.$new("xiaojianbang", "123456789", "CBDA", 1, "15900000000");
var integer = Java.use("java.lang.Integer");
var boolean = Java.use("java.lang.Boolean");
//var objarr = Java.array(
//	"Ljava.lang.Object;", 
//	["xiaojianbang", integer.$new(30), boolean.$new(true), bankCardObj]
//);
console.log(
utils.myPrint(["xiaojianbang", integer.$new(30), boolean.$new(true), bankCardObj])
);

20 ArrayList的主动调用

var arrayList = Java.use("java.util.ArrayList").$new();
    var integer = Java.use("java.lang.Integer");
    var boolean = Java.use("java.lang.Boolean");
    var bankCard = Java.use("com.xiaojianbang.hook.BankCard");
    var bankCardObj = bankCard.$new("xiaojianbang", "123456789", "CBDA", 1, "15900000000");
    arrayList.add("xiaojianbang");
    arrayList.add(integer.$new(30));
    arrayList.add(boolean.$new(true));
    arrayList.add(bankCardObj);
    var utils = Java.use("com.xiaojianbang.hook.Utils");
    console.log(utils.myPrint(arrayList));

21 hook动态加载的dex(Java.enumerateClassLoaders)

Java.enumerateLoadedClassesSync()枚举已加载类的结果中有,但是hook报错找不到类,可以尝试枚举ClassLoader,切换ClassLoader来hook
可以查看加载的dex所在路径
Java.enumerateClassLoaders({
    onMatch: function (loader) {
        try {
            Java.classFactory.loader = loader;
            var dynamic = Java.use("com.xiaojianbang.app.Dynamic");
            console.log("dynamic: ", dynamic);
            //console.log(dynamic.$new().sayHello());
            dynamic.sayHello.implementation = function () {
                console.log("hook dynamic.sayHello is run!");
                return "xiaojianbang";
            }
        } catch (e) {
            console.log(loader);
        }
    },
    onComplete: function () {}
});

22 让hook只在指定函数内生效

 var mainActivity = Java.use("com.xiaojianbang.app.MainActivity");
    var stringBuilder = Java.use('java.lang.StringBuilder');
    mainActivity.generateAESKey.implementation = function () {
        console.log("mainActivity.generateAESKey is called!");
        stringBuilder.toString.implementation = function () {
            var result = this.toString();
            console.log(result);
            return result;
        };
        var result = this.generateAESKey.apply(this, arguments);
        stringBuilder.toString.implementation = null;  //取消hook
        return result;
    };
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值