HashMap的put方法

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var hashMap = Java.use("java.util.HashMap");
hashMap.put.implementation = function(a,b){
if(a.equals("username")){
showStacks()
console.log("hashMap.put: ",a,b);
}
return this.put(a,b);
}
});

ArrayList的add方法

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var arrayList = Java.use("java.util.ArrayList");
arrayList.add.overload('java.lang.Object').implementation = function (a){
if(a.equals("username=55353")){
showStacks();
console.log("arrayList.add: ",a);
}
return this.add(a);
}
});

TextUtils的isEmpty方法

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var textUtils = Java.use("android.text.TextUtils");
textUtils.isEmpty.implementation = function(a){
if(a=="S128DF1572465B890OE3F7A13167KLEI"){
showStacks();
console.log("textUtils.isEmpty: ",a);
}
return this.isEmpty(a);
}

});

Log方法

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var log = Java.use("android.util.Log");
log.w.overload('java.lang.String', 'java.lang.String').implementation = function (a,b) {
showStacks();
console.log("low.w: ",a,b);
return this.w(a,b);
}
}
});

Collections的sort方法

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var collections = Java.use("java.util.Collections");
collections.sort.overload('java.util.List').implementation = function(a){
showStacks();
var result = Java.cast(a,Java.use("java.util.ArrayList"));
console.log("collections.sort List: ", result.toString());
return this.sort(a);
}
collections.sort.overload('java.util.List', 'java.util.Comparator').implementation = function(a,b){
showStacks();
var result = Java.cast(a,Java.use("java.util.ArrayList"));
console.log("collections.sort List: ", result.toString());
return this.sort(a,b);
}
});

JSONObject的put、getString方法

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var jSONObject = Java.use("org.json.JSONObject");
jSONObject.put.overload('java.lang.String', 'java.lang.Object').implementation = function (a,b){
showStacks();
console.log("JSONObject.put: ",a,b);
return this.put(a,b);
}

jSONObject.getString.implementation = function(a){
showStacks();
console.log("JSONObject.getString: ",a);
var result = this.getString(a);
console.log("jSONObject.getString result: ",result);
return result;
}
});

Toast的show方法

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var toast = Java.use("android.widget.Toast");
toast.show.implementation = function (){
showStacks();
console.log("toast.show: ");
return this.show();
}

});

Base64

Java.perform(function(){
function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var base64 = Java.use("android.util.Base64");
base64.encodeToString.overload('[B', 'int').implementation = function (a,b){
showStacks();
console.log("base64.encodeToString: ",JSON.stringify(a));
var result = this.encodeToString(a,b);
console.log(result);
return result;
}

});

String的getBytes方法、isEmpty方法

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}
var str = Java.use("java.lang.String");
str.getBytes.overload().implementation = function(){
showStacks();
var result = this.getBytes();
var newStr = str.$new(result);
console.log("str.getBytes result: ",newStr);
return result;
}
str.getBytes.overload('java.lang.String').implementation = function(a){
showStacks();
var result = this.getBytes(a);
var newStr = str.$new(result,a);
console.log("str.getBytes result: ",newStr);
return result;
}


});

String的构造函数的Hook

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var stringFactory = Java.use("java.lang.StringFactory");
stringFactory.newStringFromString.implementation = function(a){
showStacks();
var retval = this.newStringFromString(a);
console.log("stringFactory.newStringFromString: ",retval);
return retval;
}
stringFactory.newStringFromChars.overload('[C').implementation = function(a){
showStacks();
var retval = this.newStringFromChars(a);
console.log("stringFactory.newStringFromChars: ",retval);
return retval;
}
});

StringBuilder的Hook(线程不安全)

Java.perform(function(){

function showStacks(){
console.log(
Java.use("androit.util.Log")
.getStackString(
Java.use("java.util.Throwable").$new()
)
);
}

var sb = Java.use("java.lang.StringBuilder");
sb.toString.implementation = function(){
var retval = this.toString();
if(retval.indexOf("Encrypt") != -1){
showStacks();
}
console.log("StringBuilder.toString: ",retval);
return retval;
}
});

StringBuffer的Hook(线程安全)

Java.perform(function(){

function showStacks(){
console.log(
Java.use("androit.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var sb = Java.use("java.lang.StringBuffer");
sb.toString.implementation = function(){
var retval = this.toString();
if(retval.indexOf("username") != -1){
showStacks();
}
console.log("StringBuffer.toString: ", retval);
return retval;
}
});

findViewById

Java.enumerateLoadedClassesSync() 枚举所有已加载的类
var classArr = Java.enumerateLoadedClassesSync();
for(var i = 0; i < classArr.length; i++) {
console.log(classArr[i]);
}
frida -U -f com.dodonew.online -l HookDemo.js -o log.txt --no-pause
-f 代码让frida帮我们重新启动app,一开始就注入js
--no-pause 直接运行主线程,中途不暂停
R$id 内部类访问
R$id.btn_login.value 类的属性访问
Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var btn_login_id = Java.use("com.dodonew.online.R$id").btn_login.value;
console.log("btn_login_id",btn_login_id);
var appCompatActivity = Java.use("android.support.v7.app.AppCompatActivity");
appCompatActivity.findViewById.implementation = function(a){
if(a==btn_login_id){
showStacks();
console.log("appCompatActivity.findViewById: ",a);
}
return this.findViewById(a);
}
});

setOnClickListener

hook这个函数,对比id控件,打印函数堆栈

Java.perform(function(){

function showStacks(){
console.log(
Java.use("android.util.Log")
.getStackTraceString(
Java.use("java.util.Throwable").$new()
)
);
}

var btn_login_id = Java.use("com.dodonew.online.R$id").btn_login.value;
console.log("btn_login_id", btn_login_id);
var view = Java.use("android.view.View");
view.setOnClickListener.implementation = function(a){
if(this.getId() == btn_login_id){
showStacks();
console.log("view id: "+ this.getId());
console.log("view.setOnClickListener is called");
}
return this.setOnClickListener(a);
}
});