Frida Hook Java

基础Hook脚本框架

1
2
3
4
5
6
7
8
9
10
11
12
function hook_java() {
Java.perform(function () {

console.log("hook_java");
});
}

function main() {
hook_java();
}

setImmediate(main);

Hook一个Java层函数

Hook一个Java层函数,修改函数返回值或参数

  • java.use,查找类
  • implementation
  • overload,有重载函数时用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function hook_java() {
Java.perform(function () {
var LoginActivity = Java.use("com.example.androiddemo.Activity.LoginActivity");
console.log(LoginActivity);
LoginActivity.a.overload('java.lang.String', 'java.lang.String').implementation = function (str, str2) {
var result = this.a(str, str2); //调用原来的函数
console.log("LoginActivity.a:", str, str2, result);
return result;
};

var FridaActivity1 = Java.use("com.example.androiddemo.Activity.FridaActivity1");
console.log(FridaActivity1);

//hook函数,没有调用原来的函数,直接返回值
FridaActivity1.a.implementation = function (barr) {
console.log("FridaActivity1.a");
return "R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL=";
};

console.log("hook_java");
});
}

调用static函数和非static函数

调用静态函数和非静态函数

  • 调用static函数:类名.方法名
  • 调用非static函数:java.choose
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function call_FridaActivity2() {
//主动调用函数
Java.perform(function () {
var FridaActivity2 = Java.use("com.example.androiddemo.Activity.FridaActivity2");
//调用static静态函数
FridaActivity2.setStatic_bool_var();

//调用static静态函数
Java.choose("com.example.androiddemo.Activity.FridaActivity2", {
onMatch: function (instance) {
instance.setBool_var();
},
onComplete: function () {

}
});
});
}

设置static成员变量和非static成员变量的值

设置成员变量

  • 设置静态成员变量的值:类名.变量名.value
  • 设置非静态成员变量的值:通过实例对象.变量名.value
  • 设置有相同函数名的成员变量的值:变量名前加下划线, _变量名.value
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function call_FridaActivity3() {
Java.perform(function () {
var FridaActivity3 = Java.use("com.example.androiddemo.Activity.FridaActivity3");
FridaActivity3.static_bool_var.value = true; //设置静态成员变量

console.log(FridaActivity3.static_bool_var.value);

Java.choose("com.example.androiddemo.Activity.FridaActivity3", {
onMatch: function (instance) {
//设置非静态成员变量的值
instance.bool_var.value = true;
//设置有相同函数名的成员变量的值
instance._same_name_bool_var.value = true;
console.log(instance.bool_var.value, instance._same_name_bool_var.value);
},
onComplete: function () {

}
});
});
}

Hook内部类,枚举函数

Hook内部类:

  • 使用$来分隔类名和内部类名

  • com.example.androiddemo.Activity.FridaActivity4$InnerClasses

枚举函数:

  • 获取申明的方法getDeclaredMethods()

  • var all_methods = InnerClasses.class.getDeclaredMethods();

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
function hook_InnerClasses() {
Java.perform(function () {
//hook内部类
var InnerClasses = Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses");
console.log(InnerClasses);
InnerClasses.check1.implementation = function () {
return true;
};
InnerClasses.check2.implementation = function () {
return true;
};
InnerClasses.check3.implementation = function () {
return true;
};
InnerClasses.check4.implementation = function () {
return true;
};
InnerClasses.check5.implementation = function () {
return true;
};
InnerClasses.check6.implementation = function () {
return true;
};
});
}

function hook_mul_function() {
Java.perform(function () {
//hook 类的多个函数
var class_name = "com.example.androiddemo.Activity.FridaActivity4$InnerClasses";
var InnerClasses = Java.use(class_name);
var all_methods = InnerClasses.class.getDeclaredMethods();
//过滤、分割成只剩函数名
for (var i = 0; i < all_methods.length; i++) {
var method = (all_methods[i]);
var methodStr = method.toString();
var substring = methodStr.substr(methodStr.indexOf(class_name) + class_name.length + 1);
var methodname = substring.substr(0, substring.indexOf("("));
console.log(methodname);
//通过函数名Hook
InnerClasses[methodname].implementation = function () {
console.log("hook_mul_function:", this);
return true;
}

}

});
}

查找接口,Hook动态加载的dex

查找接口:

  • 使用console.log(instance.getDynamicDexCheck());,返回的是[]
  • 查看类的名字.$className

Hook动态加载的dex:

  • 枚举ClassLoader类加载器:Java.enumerateClassLoaders

  • 如果Hook一个动态加载的dex中的类是出现ClassNotFoundException错误,就要切换一下ClassLoader,去加载动态的dex

  • 切换ClassLoader:Java.classFactory.loader = loader;

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
function hook_dyn_dex() {
Java.perform(function () {
var FridaActivity5 = Java.use("com.example.androiddemo.Activity.FridaActivity5");
Java.choose("com.example.androiddemo.Activity.FridaActivity5", {
onMatch: function (instance) {
console.log(instance.getDynamicDexCheck().$className);
}, onComplete: function () {

}
});


//hook 动态加载的dex
Java.enumerateClassLoaders({
onMatch: function (loader) {
try {
if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {
console.log(loader);
Java.classFactory.loader = loader; //切换classloader
}
} catch (error) {

}

}, onComplete: function () {

}
});

var DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");
console.log(DynamicCheck);
DynamicCheck.check.implementation = function () {
console.log("DynamicCheck.check");
return true;
}
});
}

枚举Class

枚举加载了的Class:

  • 枚举同一个包目录下的Class:Java.enumerateLoadedClasses
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
function hook_FridaActivity6() {
Java.perform(function () {
var Frida6Class0 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class0");
Frida6Class0.check.implementation = function () {
return true;
};
var Frida6Class1 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class1");
Frida6Class1.check.implementation = function () {
return true;
};
var Frida6Class2 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class2");
Frida6Class2.check.implementation = function () {
return true;
};
});
}

function hook_mul_class() {
Java.perform(function () {
Java.enumerateLoadedClasses({
onMatch: function (name, handle) {
if (name.indexOf("com.example.androiddemo.Activity.Frida6") >= 0) {
console.log(name);
var fridaclass6 = Java.use(name);
fridaclass6.check.implementation = function () {
console.log("frida 6 check:", this);
return true;
};
}

}, onComplete: function () {

}
})
});
}

Hook.js完整代码

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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
function hook_java() {
Java.perform(function () {
var LoginActivity = Java.use("com.example.androiddemo.Activity.LoginActivity");
console.log(LoginActivity);
LoginActivity.a.overload('java.lang.String', 'java.lang.String').implementation = function (str, str2) {
var result = this.a(str, str2); //调用原来的函数
console.log("LoginActivity.a:", str, str2, result);
return result;
};

var FridaActivity1 = Java.use("com.example.androiddemo.Activity.FridaActivity1");
console.log(FridaActivity1);

//hook函数,没有调用原来的函数,直接返回值
FridaActivity1.a.implementation = function (barr) {
console.log("FridaActivity1.a");
return "R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL=";
};

console.log("hook_java");
});
}

function call_FridaActivity2() {
//主动调用函数
Java.perform(function () {
var FridaActivity2 = Java.use("com.example.androiddemo.Activity.FridaActivity2");
FridaActivity2.setStatic_bool_var(); //调用静态函数

Java.choose("com.example.androiddemo.Activity.FridaActivity2", {
onMatch: function (instance) {
instance.setBool_var();
},
onComplete: function () {

}
});
});
}

function call_FridaActivity3() {
Java.perform(function () {
var FridaActivity3 = Java.use("com.example.androiddemo.Activity.FridaActivity3");
FridaActivity3.static_bool_var.value = true; //设置静态成员变量

console.log(FridaActivity3.static_bool_var.value);

Java.choose("com.example.androiddemo.Activity.FridaActivity3", {
onMatch: function (instance) {
//设置非静态成员变量的值
instance.bool_var.value = true;
//设置有相同函数名的成员变量的值
instance._same_name_bool_var.value = true;
console.log(instance.bool_var.value, instance._same_name_bool_var.value);
},
onComplete: function () {

}
});
});
}

function hook_InnerClasses() {
Java.perform(function () {
//hook内部类
var InnerClasses = Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses");
console.log(InnerClasses);
InnerClasses.check1.implementation = function () {
return true;
};
InnerClasses.check2.implementation = function () {
return true;
};
InnerClasses.check3.implementation = function () {
return true;
};
InnerClasses.check4.implementation = function () {
return true;
};
InnerClasses.check5.implementation = function () {
return true;
};
InnerClasses.check6.implementation = function () {
return true;
};
});
}

function hook_mul_function() {
Java.perform(function () {
//hook 类的多个函数
var class_name = "com.example.androiddemo.Activity.FridaActivity4$InnerClasses";
var InnerClasses = Java.use(class_name);
var all_methods = InnerClasses.class.getDeclaredMethods();
for (var i = 0; i < all_methods.length; i++) {
var method = (all_methods[i]);
var methodStr = method.toString();
var substring = methodStr.substr(methodStr.indexOf(class_name) + class_name.length + 1);
var methodname = substring.substr(0, substring.indexOf("("));
console.log(methodname);

InnerClasses[methodname].implementation = function () {
console.log("hook_mul_function:", this);
return true;
}

}

});
}

function hook_dyn_dex() {
Java.perform(function () {
var FridaActivity5 = Java.use("com.example.androiddemo.Activity.FridaActivity5");
Java.choose("com.example.androiddemo.Activity.FridaActivity5", {
onMatch: function (instance) {
console.log(instance.getDynamicDexCheck().$className);
}, onComplete: function () {

}
});


//hook 动态加载的dex
Java.enumerateClassLoaders({
onMatch: function (loader) {
try {
if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {
console.log(loader);
Java.classFactory.loader = loader; //切换classloader
}
} catch (error) {

}

}, onComplete: function () {

}
});

var DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");
console.log(DynamicCheck);
DynamicCheck.check.implementation = function () {
console.log("DynamicCheck.check");
return true;
}
});
}

function hook_FridaActivity6() {
Java.perform(function () {
var Frida6Class0 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class0");
Frida6Class0.check.implementation = function () {
return true;
};
var Frida6Class1 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class1");
Frida6Class1.check.implementation = function () {
return true;
};
var Frida6Class2 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class2");
Frida6Class2.check.implementation = function () {
return true;
};
});
}

function hook_mul_class() {
Java.perform(function () {
Java.enumerateLoadedClasses({
onMatch: function (name, handle) {
if (name.indexOf("com.example.androiddemo.Activity.Frida6") >= 0) {
console.log(name);
var fridaclass6 = Java.use(name);
fridaclass6.check.implementation = function () {
console.log("frida 6 check:", this);
return true;
};
}

}, onComplete: function () {

}
})
});
}

function main() {
hook_java();
}

setImmediate(main);