Frida 主动加载apk
最近遇到一个app,该app会动态加载assets目录下的apk文件,之后再通过反射调用apk的dex中的类的方法。
我想hook动态加载的类的方法,所以需要切换到对应的loader(参考:https://blog.csdn.net/qq_39441603/article/details/126732909);
但是,如果直接切换loader并hook类的方法,由于apk未被加载,会报错提示类不存在(TypeError: cannot read property ‘overload’ of undefined)。
如果等待app自己去加载apk中的dex,确实是可以hook,但是app自己加载完dex之后,我想hook的方法已经被调用完了,hook就没意义了。
所以需要用Frida去主动加载apk,代码示例如下:
jscode = """
Java.perform(function () {
// 主动加载apk
var DEXCL = null
var DEXFactory = null
function loadAPK(path) {
var ActivityThread = Java.use("android.app.ActivityThread");
var app = ActivityThread.currentApplication();
Java.classFactory.cacheDir = "/data/data/" + app.getPackageName() + "/cache";
Java.classFactory.codeCacheDir = "/data/data/" + app.getPackageName() + "/code_cache";
var DexClassLoader = Java.use("dalvik.system.DexClassLoader");
DEXCL = DexClassLoader.$new(path, Java.classFactory.codeCacheDir, null, DexClassLoader.getSystemClassLoader());
DEXFactory = Java.ClassFactory.get(DEXCL);
DEXFactory.cacheDir = "/data/data/" + app.getPackageName() + "/cache";
DEXFactory.codeCacheDir = "/data/data/" + app.getPackageName() + "/code_cache";
}
// 这里为了简便直接硬编码了apk路径,其实可以通过 enumerateClassLoaders找class获取到apk路径
loadAPK('/data/user_de/0/com.google.android.gms/app_chimera/m/00000009/CronetDynamite.apk');
Java.enumerateClassLoaders({
onMatch: function (loader) {
try {
// cronet apk contains class: org.chromium.net.AndroidNetworkLibrary
if (loader.findClass("org.chromium.net.AndroidNetworkLibrary")) {
// should be: /data/user_de/0/com.google.android.gms/app_chimera/m/00000009/CronetDynamite.apk
if (loader.toString().indexOf("CronetDynamite") != -1) {
Java.classFactory.loader = loader;
send("loader: " + loader);
// console.log(loader);
}
}
} catch (error) {
}
}, onComplete: function () {
}
});
// android.net.http.X509TrustManagerExtensions.checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, java.lang.String) : java.util.List
var class_name = 'android.net.http.X509TrustManagerExtensions';
var DymClass = DEXFactory.use(class_name);
const ArrayList = Java.use("java.util.ArrayList");
DymClass.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String').implementation = function (arg1, arg2, arg3) {
var bt = Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new());
if (bt.indexOf("dh.a") != -1) {
// if (1) {
console.log("Backtrace:" + bt);
send('orin arg1 : ' + arg1);
send('orin arg2 : ' + arg2);
send('orin arg3 : ' + arg3);
const res = ArrayList.$new();
for (let cert of arg1) {
res.add(cert);
}
return res;
}
return this.checkServerTrusted(arg1, arg2, arg3);
}
});
"""
参考:http://www.manongjc.com/detail/23-ufhpuglczgmhgxs.html