-
-
Save owlwang/52801c3572135e656428bcbac73876ee to your computer and use it in GitHub Desktop.
frida android tricks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
frida -U --no-pause -l xx.js -f pkgname (or -p pid) | |
# PrintStack 输出当前调用堆栈 | |
var Throwable = null; | |
Java.perform(function () { | |
Throwable = Java.use("java.lang.Throwable"); | |
}); | |
function PrintStack() { | |
var stackElements = Throwable.$new().getStackTrace(); | |
var body = "Stack: " + stackElements[0];//method//stackElements[0].getMethodName() | |
for (var i = 1; i < stackElements.length; i++) { | |
body += "\n at " + stackElements[i]; | |
} | |
console.log("\n\n"+body); | |
}; | |
##############3 | |
#参数路径及数量 太复杂 | |
var CoreHttpManager = Java.use('com.alipay.mobile.common.transport.http.inner.CoreHttpManager'); | |
CoreHttpManager.a.overload('xx').implementation = function(){ | |
var ret = this.a.apply(this, arguments); | |
return ret | |
} | |
写好函数名,参数任意,然后保存。frida打印错误会自动输出参数列表 | |
##### | |
#反射 | |
类变量只能通过类的函数进行操作,或者通过反射 | |
var MIMCUser = Java.use('com.xiaomi.mimc.MIMCUser'); | |
MIMCUser.sendMessage.overload('java.lang.String', '[B', 'java.lang.String', 'boolean').implementation = function(){ | |
var clazz = Java.use("java.lang.Class"); | |
var param = Java.cast(this.getClass(), clazz).getDeclaredField("appAccount"); | |
param.setAccessible(true); | |
console.log("=="+param.get(this)) | |
//param.set(this, 'aaaaaaaaaa') | |
var ret = this.sendMessage.apply(this, arguments); | |
return ret; | |
} | |
其中this.getClass()可以类似用于argument[n] | |
############### | |
#java map to string | |
var Map = Java.use('java.util.HashMap') | |
var args_map = Java.cast(arguments[0], Map) | |
var tags = args_map.toString() | |
argument[0] 为Map<String, String>等类型 | |
############### | |
# output byte array | |
function byteArr2str(ba, w){ | |
if(w){ | |
var string = Java.use('java.lang.String') | |
return string.$new(ba) | |
}else{ | |
var array = Java.use('java.util.Arrays') | |
return array.toString(ba) | |
} | |
} | |
调用 | |
try{ | |
console.log(byteArr2str(ba, true)) | |
}catch(e){ | |
console.log(byteArr2str(ba, false)) | |
} | |
arrays方式需要借助下面函数查看 | |
//array2str | |
function arr(arr){ | |
if (arr != null){ | |
var ret = '' | |
for(var i = 0, len = arr.length; i < len; i++){ | |
ret += String.fromCharCode(arr[i]) | |
} | |
return ret | |
} | |
} | |
或者借助app里面已有的函数进行转换 | |
#################### | |
#android 7+ ssl错误 | |
//========android 7+ | |
try{ | |
var array_list = Java.use("java.util.ArrayList"); | |
var ApiClient = Java.use('com.android.org.conscrypt.TrustManagerImpl'); | |
ApiClient.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6) { | |
var k = array_list.$new(); | |
return k; | |
} | |
}catch (e) { | |
//console.log('universal '+e); | |
} | |
################ | |
#找不到函数,遍历calssloader | |
//find classloader | |
console.log('len '+Java.enumerateClassLoadersSync().length) | |
for(var i=0;i<Java.enumerateClassLoadersSync().length;i++){ | |
var classLoaderToUse = Java.enumerateClassLoadersSync()[i]; | |
Java.classFactory.loader = classLoaderToUse; | |
try{ | |
//classLoaderToUse.findClass('com.xiaomi.zkplug.otp.OtpManager'); | |
Java.classFactory.use("com.mijia.debug.SDKLog"); | |
console.log('succ '+classLoaderToUse); | |
break | |
}catch(e){ | |
//console.log('error '+i); | |
} | |
} | |
还可以切换pid(app多个进程) | |
########################## | |
###### | |
jadx反编译出现defpackage(没有包的类放在此包中)时,要去掉defpackge进行hook | |
#### | |
######子类/初始化函数/生成对象 | |
var MIMCUser = Java.use('com.xiaomi.mimc.MIMCUser$subclass'); | |
MIMCUser.$init.overload() | |
MIMCUser.$new() | |
############ | |
######访问静态变量 | |
var update = Java.use('com.xiaomi.gamecenter.util.o'); | |
console.log(update.f.value) | |
#如果有同名函数,加上下划线https://github.com/frida/frida-java/blob/82bc59a8389ae62a94e65841b34bb003e03f6518/lib/class-factory.js#L810-L813 | |
console.log(update._e.value) | |
#获取所有field/method | |
console.log( Object.getOwnPropertyNames(update.__proto__).join('\n') ); | |
########## | |
###unicode字符混淆## | |
直接从ide中复制出原字符 | |
var root = Java.use("ko.┆⨑"); | |
root["┃"].overload().implementation = function (){ | |
console.log(1) | |
this["┃"].apply(this, arguments) | |
return false; | |
}; | |
### | |
### protobuf协议builder hook | |
不会崩溃的方式 | |
var sevicelogin = Java.use("com.tingdao.model.pb.Account$ServiceLoginReq$Builder"); | |
sevicelogin.setUid.overload('long').implementation = function(){ | |
console.log("==init3 "+arguments[0]); | |
arguments[0] = 11111 | |
this.setUid.apply(this, arguments); | |
return this | |
}; | |
RelationC2S.FollowReq.newBuilder().setTargetUid(uid).setUid(currentUserId).setFollowSourceType(3).build() | |
直接hook setTargetUid,会导致崩溃accessed deleted Global 0x3b72,可以通过hook build函数,通过反射修改相关变量 | |
var test = Java.use("com.aphrodite.model.pb.RelationC2S$FollowReq$Builder"); | |
test.build.overload().implementation = function(){ | |
//arguments[0] = 2009040; | |
var clazz = Java.use("java.lang.Class"); | |
var param = Java.cast(this.getClass(), clazz).getDeclaredField("targetUid_"); | |
param.setAccessible(true); | |
console.log('targetUid_ '+param.get(this)); | |
var target = param.get(this); | |
var param2 = Java.cast(this.getClass(), clazz).getDeclaredField("uid_"); | |
param2.setAccessible(true); | |
console.log('uid_ '+param2.get(this)) | |
var uid = param2.get(this) | |
param.set(this, uid); | |
console.log('targetUid_ '+param.get(this)) | |
param2.set(this, target); | |
console.log('uid_ '+param2.get(this)) | |
var ret = this.build.apply(this, arguments); | |
return ret; | |
}; | |
#### | |
### 动态注册 | |
var fileobserver = Java.use('android.os.FileObserver'); | |
var fileobserverimp = Java.registerClass({ | |
name: 'com.test.FileObservers', | |
//implements:[] | |
superClass: fileobserver, | |
methods: { | |
$init: [ | |
{ | |
returnType: 'void', | |
argumentTypes: ['java.lang.String'], | |
implementation: function (s) { | |
this.$super.$init(s); | |
} | |
} | |
], | |
onEvent: function(e, pathname){console.log('file: '+pathname+' op:'+e)}, | |
} | |
}) | |
var observer = fileobserverimp.$new('/data/data/com.huawei.appmarket/shared_prefs/'); | |
observer.startWatching(); | |
### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment