frida

Spawn模式

1
2
 复制代码 隐藏代码
frida -U -f 进程名 -l hook.js

attach模式 :

1
2
 复制代码 隐藏代码
frida -U 进程名 -l hook.js

Hook框架模板

1
2
3
4
5
6
7
 复制代码 隐藏代码function main(){
Java.perform(function(){
hookTest1();
});
}

setImmediate(main);

6.Frida常用API

1.Hook普通方法、打印参数和修改返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 复制代码 隐藏代码//定义一个名为hookTest1的函数
function hookTest1(){
//获取一个名为"类名"的Java类,并将其实例赋值给JavaScript变量utils
var utils = Java.use("类名");
//修改"类名"的"method"方法的实现。这个新的实现会接收两个参数(a和b)
utils.method.implementation = function(a, b){
//将参数a和b的值改为123和456。
a = 123;
b = 456;
//调用修改过的"method"方法,并将返回值存储在`retval`变量中
var retval = this.method(a, b);
//在控制台上打印参数a,b的值以及"method"方法的返回值
console.log(a, b, retval);
//返回"method"方法的返回值
return retval;
}
}

2.Hook重载参数

1
2
3
4
5
6
7
8
9
10
11
12
 复制代码 隐藏代码// .overload()
// .overload('自定义参数')
// .overload('int')
function hookTest2(){
var utils = Java.use("com.zj.wuaipojie.Demo");
//overload定义重载函数,根据函数的参数类型填
utils.Inner.overload('com.zj.wuaipojie.Demo$Animal','java.lang.String').implementation = function(a,b){
b = "aaaaaaaaaa";
this.Inner(a,b);
console.log(b);
}
}

3.Hook构造函数

1
2
3
4
5
6
7
8
9
 复制代码 隐藏代码function hookTest3(){
var utils = Java.use("com.zj.wuaipojie.Demo");
//修改类的构造函数的实现,$init表示构造函数
utils.$init.overload('java.lang.String').implementation = function(str){
console.log(str);
str = "52";
this.$init(str);
}
}

4.Hook字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 复制代码 隐藏代码function hookTest5(){
Java.perform(function(){
//静态字段的修改
var utils = Java.use("com.zj.wuaipojie.Demo");
//修改类的静态字段"flag"的值
utils.staticField.value = "我是被修改的静态变量";
console.log(utils.staticField.value);
//非静态字段的修改
//使用`Java.choose()`枚举类的所有实例
Java.choose("com.zj.wuaipojie.Demo", {
onMatch: function(obj){
//修改实例的非静态字段"_privateInt"的值为"123456",并修改非静态字段"privateInt"的值为9999。
obj._privateInt.value = "123456"; //字段名与函数名相同 前面加个下划线
obj.privateInt.value = 9999;
},
onComplete: function(){

}
});
});

}

5.Hook内部类

1
2
3
4
5
6
7
8
9
10
11
 复制代码 隐藏代码function hookTest6(){
Java.perform(function(){
//内部类
var innerClass = Java.use("com.zj.wuaipojie.Demo$innerClass");
console.log(innerClass);
innerClass.$init.implementation = function(){
console.log("eeeeeeee");
}

});
}

6.枚举所有的类与类的所有方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 复制代码 隐藏代码function hookTest7(){
Java.perform(function(){
//枚举所有的类与类的所有方法,异步枚举
Java.enumerateLoadedClasses({
onMatch: function(name,handle){
//过滤类名
if(name.indexOf("com.zj.wuaipojie.Demo") !=-1){
console.log(name);
var clazz =Java.use(name);
console.log(clazz);
var methods = clazz.class.getDeclaredMethods();
console.log(methods);
}
},
onComplete: function(){}
})
})
}

7.枚举所有方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 复制代码 隐藏代码function hookTest8(){
Java.perform(function(){
var Demo = Java.use("com.zj.wuaipojie.Demo");
//getDeclaredMethods枚举所有方法
var methods =Demo.class.getDeclaredMethods();
for(var j=0; j < methods.length; j++){
var methodName = methods[j].getName();
console.log(methodName);
for(var k=0; k<Demo[methodName].overloads.length;k++){
Demo[methodName].overloads[k].implementation = function(){
for(var i=0;i<arguments.length;i++){
console.log(arguments[i]);
}
return this[methodName].apply(this,arguments);
}
}
}
})
}

8.主动调用

静态方法

1
2
 复制代码 隐藏代码var ClassName=Java.use("com.zj.wuaipojie.Demo"); 
ClassName.privateFunc("传参");

非静态方法

1
2
3
4
5
6
7
8
9
10
11
12
asd 复制代码 隐藏代码    var ret = null;
Java.perform(function () {
Java.choose("com.zj.wuaipojie.Demo",{ //要hook的类
onMatch:function(instance){
ret=instance.privateFunc("aaaaaaa"); //要hook的方法
},
onComplete:function(){
//console.log("result: " + ret);
}
});
})
//return ret;
注入模式 描述 命令或参数 优点 主要用途
Spawn模式 将启动App的权利交由Frida来控制,即使目标App已经启动,在使用Frida注入程序时还是会重新启动App 在CLI模式中,Frida通过加上 -f 参数指定包名以spawn模式操作App 适合于需要在App启动时即进行注入的场景,可以在App启动时即捕获其行为 当需要监控App从启动开始的所有行为时使用
Attach模式 在目标App已经启动的情况下,Frida通过ptrace注入程序从而执行Hook的操作 在CLI模式中,如果不添加 -f 参数,则默认会通过attach模式注入App 适合于已经运行的App,不会重新启动App,对用户体验影响较小 在App已经启动,或者我们只关心特定时刻或特定功能的行为时使用