-
Notifications
You must be signed in to change notification settings - Fork 0
/
dump_root_detection_functions.js
109 lines (86 loc) · 4.34 KB
/
dump_root_detection_functions.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
/*
This frida script just instruemnts the specific classes that i identified in the static analysis
section of the readme that seem to do some kind of root detection.
When a method that belongs to a target class is called in runtime, this script will log the class name,
method name, timestamp, the arguments passed to the method, and the return values.
TO RUN:
frida -U -f com.instagram.android -l dump_root_detection_functions.js
*/
Java.perform(() => {
// Define the target classes/methods to hook
// NOT FOUND!
// print out test and dev keys
//try {
// androidOSBuild = Java.use('android.os.Build');
// console.log("==================================");
// console.log(" output from android.os.Build ");
// console.log("==================================");
//
// console.log("Build.TYPE: " + androidOSBuild.TYPE.value);
// console.log("Build.TAGS: " + androidOSBuild.TAGS.value);
// console.log("Build.VERSION.RELEASE: " + androidOSBuild.VERSION.RELEASE.value); } catch (err) {
// console.log("Error reading android.os.Build: " + err);
//}
const targetClassMethods = {
// class": ["method1", "method2", ...]
// NOT FOUND (not a function)!
//"X.AGo": ["report"],
// NOT FOUND (not a function)!
//"X.03v": ["E4x"],
"X.Tdh": [], // detection done in constructor, instrumented by default
"X.A5o": [], // ^
"X.Riu": [], // ^
// NOT FOUND (not a function)!
//"X.XON": ["A00"]
};
Object.keys(targetClassMethods).forEach(className => {
try {
const targetClass = Java.use(className);
// Iterate through constructors
const constructors = targetClass.class.getDeclaredConstructors();
constructors.forEach(constructor => {
const parameterTypes = constructor.getParameterTypes().map(type => type.getName()).join(', ');
console.log(`Hooking constructor of ${className} with parameters: ${parameterTypes}`);
constructor.implementation = function(...args) {
console.log(`\n======================`);
console.log(`Class: ${className}`);
console.log(`Constructor called with arguments:`);
constructor.getParameterTypes().forEach((argType, index) => {
const argValue = args[index]?.toString() || "null";
console.log(` ${argType.getName()}: ${argValue}`);
});
return this.$init(...args);
};
});
// Iterate through specific root detection methods we identified in static analysis
// const methods = targetClass.class.getDeclaredMethods();
const methods = targetClassMethods[className];
methods.forEach(method => {
const methodName = method.getName();
targetClass[methodName].overloads.forEach(overload => {
// Override the method's implementation
overload.implementation = function (...args) {
console.log(`\n======================`);
console.log(`Class: ${className}`);
console.log(`Method: ${methodName}`);
// Log function parameters with their types and values
console.log(`Parameters:`);
overload.argumentTypes.forEach((argType, index) => {
const argValue = args[index]?.toString() || "null";
console.log(` ${argType.className}: ${argValue}`);
});
// Call the original method and capture the result
const result = overload.apply(this, args);
// Log the return type and value
console.log(`Return:`);
console.log(` ${overload.returnType.className}: ${result?.toString() || "null"}`);
return result;
};
});
});
} catch (err) {
console.log("\n======================")
console.error(`Error hooking class ${className}: ${err.message}`);
}
});
});