Frida使用
1.一个简单固定的Frida写法-所有练习apk下载
function main(){Java.perform(function(){hookTest1();});
}//延迟多少秒执行main函数
setTimeout(main,1000);//1000 = 1秒//定义一个名为hookTest1的函数
function hookTest1(){console.log("测试-为所欲为区");
}
2.拦截普通方法,修改值并返回
//正向关键代码
//按钮1执行 我们需要用frida中hook这个函数
private void add(String num1, String num2) {double sum = number1 + number2;
}
//1.先通过Java.use函数得到frida01类 var Jfrida01 = Java.use("com.zero.frida01.add"); //2.通过类名定位到add函数,通过implementation关键字访问和修改方法的具体实现//3.其中function(a,b)可以看作成add(a,b),function()括号里面参数是可变的,//具体个数和我们要修改的方法有关,如果add函数需要传3个参数,那么就是function(a,b,c)Jfrida01.add.implementation = function(a,b){ //4.为所欲为区,我们可以在这里做任何我们想做的事情,劫持,修改,打印数据为明文 console.log("打印传入的a的值 = " + a); console.log("打印传入的b的值 = " + b); //5.修改传入的数据a = 3b = 9//6.使用原add方法,重新计算,相当于不管用户传入什么数据,我只执行3+9的命令var res = this.add(a,b); console.log("最终结果res = " + res ); //7.返回结果,因为add函数本身是有返回值的,如果没有返回值,APP运行的时候会报错 return res;
3.拦截构造函数
//1.通过包名+类名获取User类对象 var User = Java.use("com.roysue.roysueapplication.User"); //2.和普通方法差不多,唯一区别就是用$init代替了方法名,注意$init格式固定,统一代指构造函数 //3.大家注意到没,下面的function(name,age),其实用function(a,b)也行,不影响,其他的也一样User.$init.implementation = function(name,age){ console.log("打印原始传入的a的值 = " + a); console.log("打印原始传入的b的值 = " + b); //4.修改值的时候要注意格式一样,不然会出错name = "小翼"; age = 12; //5.最终要执行原本的init方法否则运行时会报异常导致原程序无法正常运行。 this.$init(name,age);
4.拦截方法重载
当原程序有几个相同方法名,但形参个数不同时,使用overload
//正向代码: printInfo方法名相同,传入的形参不同
public class StudentInfo {// 打印学生姓名和年龄public void printInfo(String name, int age) {System.out.println("Student Name: " + name + ", Age: " + age);}// 打印年龄public void printInfo(int age) {System.out.println("Age: " + age);}
}
//1.通过包名+类名定位到关键类
var JStudentInfo = Java.use('com.example.StudentInfo');//2.通过overload关键字钩挂新方法
var JprintInfo1= JStudentInfo .printInfo.overload('java.lang.String','int');
var JprintInfo2 = JStudentInfo .printInfo.overload('int');// 3.针对每个重载版本进行操作,接下来和普通方法没区别
JprintInfo1.implementation = function(str) {//为所欲为区
};JprintInfo2.implementation = function(i) {//为所欲为区
};
5.主动调用具有static关键字的函数,和没有static关键字的函数
//正向代码
public class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}// 静态方法public static void printSchoolName(String schoolName) {System.out.println("School Name: " + schoolName);}// 非静态方法public void printStudentInfo() {System.out.println("Student Name: " + this.name + ", Age: " + this.age);}
}
// Frida 脚本调用静态方法
Java.perform(function () {var Student = Java.use('com.example.Student'); // 替换为实际的包名和类名Student.printSchoolName.overload('java.lang.String').call('Greenwood High');
});// Frida 脚本调用非静态方法
Java.perform(function () {var Student = Java.use('com.example.Student'); // 替换为实际的包名和类名var student = Student.$new('Alice', 20); // 创建 Student 对象student.printStudentInfo(); // 调用非静态方法
});