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();
for(let i = 0; i < methods.length; i++) { console.log(methods[i].getName()); } console.log("======================================"); for(let i =0; i < constructors.length; i++) { console.log(constructors[i].getName()); } console.log("======================================"); for(let i = 0; i < fields.length; i++) { console.log(fields[i].getName()); } console.log("======================================"); for(let i = 0; i < classes.length; i++) { console.log(classes[i].getName()); } console.log("======================================"); for(let i = 0; i < classes.length; i++) { console.log(classes[i].getName()); //classes[i] 这里得到的已经是类的字节码,不需要再.class var Wallet$InnerStructure = classes[i].getDeclaredFields(); for(let j = 0; j < Wallet$InnerStructure.length; j++){ console.log(Wallet$InnerStructure[j].getName()); } }
hook类的所有方法
Java.perform(function(){ functionhookFunc(methodName){ console.log(methodName); var overloadsArr = utils[methodName].overloads; for(var i=0;i<overloadsArr.length;i++){ overloadsArr[i].implementation = function () { var params = ""; for(var k = 0; k < arguments.length; k++){ params += arguments[k] + " "; } console.log(params); returnthis[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); } });
publicclassTest{ public static void print(){ Log.d("xiaojianbang","这自己注入的代码"); } }
编译过后推送到手机
adb push xxx.dex /data/local/tmp
注入dex
Java.perform(function(){ 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; } });
Java.perform(function(){ var ios = newFile("/data/data/com.xiaojianbang.app/xiaojianbang.txt","a+"); ios.write("xiaojianbang is very good!!!\n"); ios.flush(); ios.close(); });
Java.cast
//向上转型的,不能用toStirng直接得到结果,比如Map、List类型的打印 Java.perform(function(){ 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); returnthis.shufferMap2(result); } });
数组的构建
Java.perform(function(){ varUtils = Java.use("com.xiaojianbang.hook.Utils"); var strarr = Java.array( "Ljava.lang.String;", ["xiaojianbang","QQ: 24358757","VX: xiaojianbang8888","公众号: 非code"] ); var retval = Utils.myPrint(strarr); console.log(retval); });
可变参数的构造
// Object数组的构建 // 可变参数本质上就是数组, 按数组处理即可 // 只需要处理基本数据类型的包装,其他的Frida会处理 Java.perform(function(){ var utils = Java.use("com.xiaojianbang.hook.Utils"); var money = Java.use("com.xiaojianbang.hook.Money").$new("xiaojianbang", 20000); varBool = Java.use("java.lang.Boolean"); var integer = Java.use("java.lang.Integer"); var retval2 = utils.myPrint(["xiaojianbang", integer.$new(100),Bool.$new(true),money]) console.log(retval2); });
ArrayList的主动调用
Java.perform(function(){ varBool = Java.use("java.lang.Boolean"); var integer = Java.use("java.lang.Integer"); var money = Java.use("com.xiaojianbang.hook.Money").$new("xiaojianbang", 20000); var arrayList = Java.use("java.util.ArrayList").$new(); varUtils = Java.use("com.xiaojianbang.hook.Utils"); arrayList.add("xiaojianbang"); arrayList.add(integer.$new(100)); arrayList.add(Bool.$new(false)); arrayList.add(money); console.log("arrayList: ",arrayList.toString()); var retval3 = Utils.myPrint(arrayList); console.log(retval3); });
hook动态加载的dex(Java.enumerateClassLoaders)
//Java.enumerateLoadedClassSync()枚举已加载的类的结果中有,但是hook报错找不到类,可以切换ClassLoader来hook Java.perform(function(){ Java.enumerateClassLoaders({ onMatch: function (loader){ try{ Java.classFactory.loader = loader var dynamic = Java.use("com.xiaojianbang.app.Dynamic"); console.log("dynamic: ", dynamic); dynamic.sayHello.implementation = function (){ console.log("hook dynamic.sayHello is run!"); return"xiaojianbang"; } }catch (e){ console.log(loader); } }, onComplete: function (){
} }); });
让hook只在指定的函数内生效
Java.perform(function(){ 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; } });
hook定位接口的实现类
Java.perform(function(){ var classes = Java.enumerateLoadedClassesSync(); for (const index in classes) { let className = classes[index]; if(className.indexOf("com.xiaojianbang") === -1) continue; try { let clazz = Java.use(className); let resultArr = clazz.class.getInterfaces(); //console.log("resultArr: ", resultArr); if(resultArr.length === 0) continue; for (let i = 0; i < resultArr.length; i++) { if(resultArr[i].toString().indexOf("com.xiaojianbang.app.TestRegisterClass") !== -1){ console.log(className, resultArr); } } }catch (e) {console.log("Didn't find class: " + className);} } });
hook定位抽象类的实现
Java.perform(function(){ var classes = Java.enumerateLoadedClassesSync(); for (const index in classes) { let className = classes[index]; if(className.indexOf("com.xiaojianbang") === -1) continue; try { let clazz = Java.use(className); let resultClass = clazz.class.getSuperclass(); console.log("resultClass: ", className, resultClass); if(resultClass == null) continue; if(resultClass.toString().indexOf("com.xiaojianbang.app.TestAbstract") !== -1){ console.log(className, resultClass); } } catch (e) {} } });