鸽了的frida

Frida上路~~~芜湖

写在前面

记得在我小时候,就常常听师傅讲,什么Frida啦,什么hook啦。属实是给当时的我听出PTSD了,以至于后面再有人说Frida和hook,我都会感叹一声:“nb!”,总是觉得这个东西可能很难,学起来很麻烦,所以就一直没学之至如今,昨天刷b站,看见别人学校re组开组会,讲Frida的用法,唤起了我深处的记忆,而且最近打比赛的题目里好像也能用到Frida,这下不得不学了(

Frida上路~~~芜湖

1.Frida是什么?

  • Frida 是一款开源的动态插桩工具,可以插入一些代码到原生App的内存空间去动态地监视和修改其行为,支持Windows、Mac、Linux、Android或者iOS,从安卓层面来讲,可以实现Java层和NativeHook操作。

2.Frida原理

  • frida注入的原理就是找到目标进程,使用ptrace跟踪目标进程获取mmap,dlpoen,dlsym等函数库的偏移获取mmap在目标进程申请一段内存空间将在目标进程中找到存放frida-agent-32/64.so的空间启动执行各种操作由agent去实现

3.Frida环境配置

  • python

  • vscode

装vscode是因为有代码的提示

然后安装frida,只需要执行

1
2
pip install frida https://pypi.tuna.tsinghua.edu.cn/simple
pip install frida-tools https://pypi.tuna.tsinghua.edu.cn/simple

注意看自己frida的版本,可以使用pip list查看

自己手机的操作系统可以通过adb shell getprop ro.product.cpu.abi查看

然后去frida官方github这里下载对应的版本,操作系统也要选对

然后把这个下载好的文件解压,放到手机根目录data/local/tmp

adb push frida-server /data/local/tmp/

这里差不多就配好环境了

4.Frida基础指令

1
2
3
4
5
6
7
frida-ps -U 查看当前手机运行的进程

frida -U -f 进程名 -l hook.js //Spawn模式 将启动App的权利交由Frida来控制,即使目标App已经启动,在使用Frida注入程序时还是会重新启动App

frida -U 进程名 -l hook.js //attch模式 在目标App已经启动的情况下,Frida通过ptrace注入程序从而执行Hook的操作

logcat |grep "D.zj2595"日志捕获//在adb shell 里

Hook框架模板:

1
2
3
4
5
6
function main(){
Java.perform(function(){
hookTest1();
});
}
setImmediate(main);

5.几个现成的api

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//定义一个名为hookTest1的函数
function hookTest1(){
//获取一个名为"类名"的Java类,并将其实例赋值给JavaScript变量utils
var utils = Java.use("com.zj.wuaipojie.Demo");
//修改"类名"的"method"方法的实现。这个新的实现会接收两个参数(a和b)
utils.a.overload("java.lang.String").implementation = function(str){
//将参数a和b的值改为123和456。
//a = 123;
//b = 456;
str="牛逼"
//调用修改过的"method"方法,并将返回值存储在`retval`变量中
var retval = this.a(str);
//在控制台上打印参数a,b的值以及"method"方法的返回值
console.log(str, retval);
//返回"method"方法的返回值
return retval;
}
}

//定义一个名为hookTest2的函数
function hookTest2(){
//获取一个名为"类名"的Java类,并将其实例赋值给JavaScript变量utils
var utils = Java.use("com.zj.wuaipojie.Demo");
//修改"类名"的"method"方法的实现。这个新的实现会接收两个参数(a和b)
utils.Inner.overload("com.zj.wuaipojie.Demo$Animal","java.lang.String").implementation = function(a,str){
//将参数a和b的值改为123和456。
//a = 123;
//b = 456;
str="otto"
//调用修改过的"method"方法,并将返回值存储在`retval`变量中
var retval = this.Inner(a,str);
//在控制台上打印参数a,b的值以及"method"方法的返回值
console.log(str);
//返回"method"方法的返回值
//return retval;
}
}
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);
}
}
function hookTest4(){
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 = 99;
},
onComplete: function(){

}
});
});

}


function hookTest6(){
Java.perform(function(){
//内部类
var innerClass = Java.use("com.zj.wuaipojie.Demo$InnerClass");
console.log(innerClass);
innerClass.$init.implementation = function(){
console.log("eeeeeeee");
}

});
}


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(){}
})
})
}

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);
}
}
}
})
}
function hookTest9(){//主动调用静态方法
Java.perform(function(){
var ClassName=Java.use("com.zj.wuaipojie.Encode");
var ret=ClassName.encode("aa");
console.log(ret);
//非静态方法的主动调用
// var ret = null;

// Java.choose("com.zj.wuaipojie.Demo",{ //要hook的类
// onMatch:function(instance){
// ret=instance.privateFunc("aaaaaaa"); //要hook的方法
// },
// onComplete:function(){
// //console.log("result: " + ret);
// }

// })
// //return ret;

})
}

function main(){
Java.perform(function(){
hookTest9();
});
}
setImmediate(main);

其实我就是跟着52破解里的教程学的frida,只看了第一节,所以先写到这里。


鸽了的frida
http://example.com/2023/11/09/非常好frida,使我的hook旋转!!!!/
作者
FUX1AOYUN
发布于
2023年11月9日
许可协议