forked from CreditTone/hooker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
edit_text.js
97 lines (93 loc) · 4.22 KB
/
edit_text.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
function methodInBeat(invokeId, timestamp, methodName, executor) {
var startTime = timestamp;
var androidLogClz = Java.use("android.util.Log");
var exceptionClz = Java.use("java.lang.Exception");
var threadClz = Java.use("java.lang.Thread");
var currentThread = threadClz.currentThread();
var stackInfo = androidLogClz.getStackTraceString(exceptionClz.$new());
var str = ("------------startFlag:" + invokeId + ",objectHash:"+executor+",thread(id:" + currentThread.getId() +",name:" + currentThread.getName() + "),timestamp:" + startTime+"---------------\n");
str += methodName + "\n";
str += stackInfo.substring(20);
str += ("------------endFlag:" + invokeId + ",usedtime:" + (new Date().getTime() - startTime) +"---------------\n");
console.log(str);
};
function makeClass(className) {
var classClz = Java.use("java.lang.Class");
var forNameFunc = classClz.forName.overload("java.lang.String");
return forNameFunc.call(classClz, className);
};
function isClass(obj, superClzName) {
var objClz = obj.getClass();
var superClz = makeClass(superClzName);
return superClz.isAssignableFrom(objClz);
};
function classExists(className) {
var exists = false;
try {
var clz = Java.use(className);
exists = true;
} catch(err) {
//console.log(err);
}
return exists;
};
Java.perform(function() {
var androidLogClz = Java.use("android.util.Log");
var exceptionClz = Java.use("java.lang.Exception");
var textViewClz = Java.use("android.widget.TextView");
var charSequenceClz = Java.use("java.lang.CharSequence");
if (textViewClz.setText) {
var setTextFunc = textViewClz.setText.overload("java.lang.CharSequence");
setTextFunc.implementation = function(v0) {
var startTime = new Date().getTime();
setTextFunc.call(this, v0);
if (isClass(this, "android.widget.EditText")) {
var clz = this.getClass().getName();
var viewId = this.getId();
console.log("EditTextClz: " + clz);
console.log("ViewId: " + viewId);
console.log("text: " + v0);
var invokeId = Math.random().toString(36).slice( - 8);
var executor = this.hashCode();
methodInBeat(invokeId, startTime, 'android.widget.EditText.setText()', executor);
}
};
}
//EditText的getText继承自TextView
if (textViewClz.getText) {
var getTextFunc = textViewClz.getText.overload();
getTextFunc.implementation = function() {
var startTime = new Date().getTime();
var editable = getTextFunc.call(this);
if (isClass(this, "android.widget.EditText")) {
var clz = this.getClass().getName();
var viewId = this.getId();
console.log("EditTextClz: " + clz);
console.log("ViewId: " + viewId);
console.log("Text: " + Java.cast(editable, charSequenceClz));
var invokeId = Math.random().toString(36).slice( - 8);
var executor = this.hashCode();
methodInBeat(invokeId, startTime, 'android.widget.EditText.getText()', executor);
}
return editable;
};
}
//AppCompatEditText 有自定义的getText所以单独hook
if (classExists("androidx.appcompat.widget.AppCompatEditText")) {
var appCompatEditTextClz = Java.use("androidx.appcompat.widget.AppCompatEditText");
var appCompatEditTextClzGetTextFunc = appCompatEditTextClz.getText.overload();
appCompatEditTextClzGetTextFunc.implementation = function() {
var startTime = new Date().getTime();
var editable = appCompatEditTextClzGetTextFunc.call(this);
var clz = this.getClass().getName();
var viewId = this.getId();
console.log("EditTextClz: " + clz);
console.log("ViewId: " + viewId);
console.log("Text: " + Java.cast(editable, charSequenceClz));
var invokeId = Math.random().toString(36).slice( - 8);
var executor = this.hashCode();
methodInBeat(invokeId, startTime, 'androidx.appcompat.widget.AppCompatEditText.getText()', executor);
return editable;
};
}
});