静态方法和实例方法的hook
不需要管修饰符,不需要区分静态和实例方法,都是使用Java.use
// 实例方法
public String getInfo(){
}
// 静态方法
public static void setFlag(){
}
// 静态方法和实例方法hook
Java.perform(function(){
var money = Java.use("com.jiang.hook.Money");
money.getInfo.implementation = function(a){
console.log(a);
var result = this.getInfo(a);
return result;
}
})
// 脚本启动
frida -U -f com.jiang.app -l hook.js -o log.txt --no-pause
-U: 当前设备
-f: 启动时开始执行
-l: 脚本路径
-o: 输出日志到文件
--no-pause: 主线程启动
函数参数和返回值的修改
// 函数参数和返回值的修改
Java.perform(function(){
var money = Java.use("com.jiang.hook.Money");
money.getInfo.implementation = function(a){
console.log(a);
var result = this.getInfo("修改参数");
return "修改返回值";
}
})
构造方法的hook $init
// 构造方法
public class Money{
public Money(String str, int i){
this.currency = str;
this.amount = i;
}
}
// 使用方式
Money money = new Money("美元", 200);
// 构造方法的hook
Java.perform(function(){
var money = Java.use("com.jiang.hook.Money");
money.$init.implementation = function(a, b){
console.log(a, b);
return this.$init("欧元", 100);
}
})
对象参数的构造与修改 $new
// 对象作为参数
public boolean deposit(Money money){
}
// 对象参数的构造与修改
Java.perform(function(){
var wallet = Java.use("com.jiang.hook.Wallet");
var money = Java.use("com.jiang.hook.Money");
wallet.deposit.implementation = function(a){
console.log(a.getInfo());
return this.deposit(money.$new("美元", 1000));
}
})
HashMap的打印
// HashMap
HashMap hashMap = new HashMap();
hashMap.put("user", "jiangfubang");
// HashMap的打印
Java.perform(function(){
var utils = Java.use("com.jiang.hook.Utils");
utils.shufferMap.implementation = function(a){
console.log(a);
var result = this.shufferMap(a);
console.log(result);
return result;
}
})
// HashMap的遍历
Java.perform(function(){
var utils = Java.use("com.jiang.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(result.toString());
var result = this.shufferMap(a);
console.log(result);
return result;
}
})
重载方法的hook
// 重载方法
public static int getCalc(int i, int j){
return i + j;
}
public static int getCalc(int i, int j, int k){
return i + j + k;
}
// 重载方法的hook
Java.perform(function(){
var utils = Java.use("com.jiang.hook.Utils");
utils.getCalc.overload('int', 'int').implementation = function(a, b){
console.log(a, b);
return this.getCalc(a, b);
}
})
hook方法的所有重载
arguments可以获取参数列表
Java.perform(function(){
var utils = Java.use("com.jiang.hook.Utils");
for(var i=0; i<utils.getCalc.overloads.length; i++){
utils.getCalc.overloads[i].implementation = function(){
var params = "";
for(var j=0; j<arguments.length; j++){
params += arguments[j] + " ";
}
console.log(params);
}
return this.getCalc.apply(this, arguments);
}
})
主动调用
function zhudongdiaoyong(){
Java.perform(function(){
// 静态方法
var money = Java.use("com.jiang.hook.Money");
money.setFlag("jiangfubang");
// 实例方法 创建新对象
var moneyObj = money.$new("卢布", 1000);
console.log(moneyObj.getInfo());
// 实例方法 获取已有对象(Java.choose)
Java.choose("com.jiang.hook.Money", {
onMatch: function(obj){
console.log(obj.getInfo());
},
onComplete: function(){
console.log("内存中的Money对象搜索完毕");
}
});
})
}
函数堆栈的打印
function showStack(){
Java.perform(function(){
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
});
}
获取和修改类的字段
- 静态字段
- 实例字段 创建新对象
- 实例字段 获取已有对象 如果字段名和方法名一样,需要加下划线前缀