Hook 普通方法(包括私有、公有、静态)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Java.perform(function () { var hook_cls = Java.use(‘com.threetails.demo.Utils’); hook_cls.normalMethod.implementation = function (a, b) { console.log(“Hook Start…”); send(‘arg0: ‘+ a); send(‘arg1: ‘+ b); send(‘result: ‘+ this.normalMethond(a,b)); return this.normalMethond(a,b); } }); |
Hook 构造方法
1 2 3 4 5 6 7 8 9 10 11 12 | // Hook构造方法时与普通方法类似,只不过将方法名改成了 $init Java.perform(function () { var hook_cls = Java.use(‘com.threetails.demo.Utils’); hook_cls.$init.implementation = function (a, b) { console.log(“Hook Start…”); send(‘arg0: ‘+ a); send(‘arg1: ‘+ b); return this.$init(a, b); } }); |
Hook 重载方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Java.perform(function () { var hook_cls = Java.use(‘com.threetails.demo.Utils’); /* ovldMethod是一个重载方法,必须加上overload(参数类型)才能Hook。 若参数类型为字符串,应该传java.lang.String,因为字符串在java中与int不同,它不是基本类型,而是类。 如果不知道参数类型,可以去掉overload,执行一下进程会抛出错误,在错误提示中可以看到对应的参数类型。*/ hook_cls.ovldMethod.overload(“int”).implementation = function (a) { console.log(“Hook Start…”); send(‘arg0: ‘+ a); send(‘result: ‘+ this.ovldMethod.overload(“int”)(a)); return this.ovldMethod.overload(“int”)(a); } }); |
构造对象参数
如果方法参数的类型并非 java 的内置类型,而是一个自定义类,你又想在 Hook 时传入自定义对象,怎么办?假设现在有个自定义类叫 Dog,它有两个属性:name 和 age。看看下面这个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Java.perform(function () { var hook_cls = Java.use(‘com.threetails.demo.Utils’); // 首先声明一个dog类 var dog_cls = Java.use(‘com.threetails.demo.Dog’); hook_cls.feed.implementation = function (dog_obj) { console.log(“Hook Start…”); send(‘old dog:’+dog_obj); // 调用dog_cls.$new来实例化一个自定义的dog对象 var new_dog = dog_cls.$new(“大黄”, 5); send(‘new dog:’+new_dog); // 调用原方法并将对象参数替换为自定义的dog return this.feed(new_dog); } }); |
修改对象属性
还是以 Dog 类为例, 现在我们需要将传入的 Dog 对象的 age 修改为 1。
正常修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Java.perform(function () { var hook_cls = Java.use(‘com.threetails.demo.Utils’); hook_cls.feed.implementation = function (dog_obj) { console.log(“Hook Start…”); // 需要使用.value来获取属性值 send(dog_obj.age.value); // 需要使用.value来修改属性值 dog_obj.age.value = 1; send(dog_obj.name.value); return this.feed(dog_obj); } }); |
使用反射
修改对象属性还有另外一种方式,也就是使用 java 的反射, 这种方式相对复杂一些。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Java.perform(function () { var hook_cls = Java.use(‘com.threetails.demo.Utils’); // 首先需要声明一个类构造器 var clazz = Java.use(‘java.lang.Class’); hook_cls.feed.implementation = function (dog_obj) { console.log(“Hook Start…”); // 调用Java.cast方法,传入类和类构造器得到类的id,再调用getDeclaredField得到属性id var ageid = Java.cast(dog_obj.getClass(),clazz).getDeclaredField(‘age’); // 设置该属性为可访问 ageid.setAccessible(true); // 调用get方法获取属性值 var old_value = ageid.get(dog_obj); // 此处必须使用console.log才能打印我们需要的值 console.log(old_value); // 调用setInt修改属性值 ageid.setInt(dog_obj, 1); return this.feed(dog_obj); } }); |