Skip to content

Instantly share code, notes, and snippets.

@zzzzfeng
Last active October 17, 2024 05:28
Show Gist options
  • Save zzzzfeng/8043a56bf1351d6222846c1314c2416e to your computer and use it in GitHub Desktop.
Save zzzzfeng/8043a56bf1351d6222846c1314c2416e to your computer and use it in GitHub Desktop.
frida android tricks
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