Frida Hook动态加载的DEX里的方法,需要切换到ClassLoader
下。
Java
package com.github.lastingyang.androiddemo.Activity;import android.content.Intent;import android.os.Bundle;import android.widget.Toast;import com.example.androiddemo.Dynamic.AbstractC0000CheckInterface;import dalvik.system.DexClassLoader;import java.io.File;import java.io.IOException;public class FridaActivity5 extends BaseFridaActivity {private AbstractC0000CheckInterface DynamicDexCheck = null;@Override // com.github.lastingyang.androiddemo.Activity.BaseFridaActivitypublic String getNextCheckTitle() {return "当前第5关";}/* JADX WARNING: Removed duplicated region for block: B:30:0x0045 *//* JADX WARNING: Removed duplicated region for block: B:33:0x004d *//* JADX WARNING: Removed duplicated region for block: B:37:0x0058 A[SYNTHETIC, Splitter:B:37:0x0058] *//* JADX WARNING: Removed duplicated region for block: B:42:0x0060 A[Catch:{ IOException -> 0x005c }] *//* JADX WARNING: Removed duplicated region for block: B:47:? A[RETURN, SYNTHETIC] *//* Code decompiled incorrectly, please refer to instructions dump. */public static void copyFiles(android.content.Context r2, java.lang.String r3, java.io.File r4) {/*// Method dump skipped, instructions count: 106*/throw new UnsupportedOperationException("Method not decompiled: com.github.lastingyang.androiddemo.Activity.FridaActivity5.copyFiles(android.content.Context, java.lang.String, java.io.File):void");}private void loaddex() {File filesDir = getFilesDir();if (!filesDir.exists()) {filesDir.mkdir();}String str = filesDir.getAbsolutePath() + File.separator + "DynamicPlugin.dex";File file = new File(str);try {if (!file.exists()) {file.createNewFile();copyFiles(this, "DynamicPlugin.dex", file);}} catch (IOException e) {e.printStackTrace();}try {AbstractC0000CheckInterface checkInterface = (AbstractC0000CheckInterface) new DexClassLoader(str, filesDir.getAbsolutePath(), null, getClassLoader()).loadClass("com.example.androiddemo.Dynamic.DynamicCheck").newInstance();this.DynamicDexCheck = checkInterface;if (checkInterface == null) {Toast.makeText(this, "loaddex Failed!", 1).show();}} catch (Exception e2) {e2.printStackTrace();}}public AbstractC0000CheckInterface getDynamicDexCheck() {if (this.DynamicDexCheck == null) {loaddex();}return this.DynamicDexCheck;}/* access modifiers changed from: protected */@Override // ponentActivity, androidx.ponentActivity, com.github.lastingyang.androiddemo.Activity.BaseFridaActivity, androidx.appcompat.app.AppCompatActivity, androidx.fragment.app.FragmentActivitypublic void onCreate(Bundle bundle) {super.onCreate(bundle);loaddex();}@Override // com.github.lastingyang.androiddemo.Activity.BaseFridaActivitypublic void onCheck() {if (getDynamicDexCheck() == null) {Toast.makeText(this, "onClick loaddex Failed!", 1).show();} else if (getDynamicDexCheck().check()) {CheckSuccess();startActivity(new Intent(this, FridaActivity6.class));finishActivity(0);} else {super.CheckFailed();}}}
这段代码首先加载DynamicPlugin.dex,然后调用其中的getDynamicDexCheck().check()
。这里就要hook的是check,但是check不在当前Dex环境下,而是在DynamicPlugin下,因此要先切换到DynamicPlugin下。
Frida JS
function hook_dyn_dex() {Java.perform(function() {Java.enumerateClassLoaders({onMatch : function(loader) {try {if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {Java.classFactory.loader = loader;console.log(loader);}} catch (error) {}}, onComplete : function() {}});var DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");DynamicCheck.check.implementation = function() {var result = this.check();console.log("DynamicCheck.check:", result);return true;}})}
首先是枚举所有的ClassLoader
,其次找到包含DynamicCheck
的ClassLoader
,最后把这个ClassLoader
加载到当前loader
。
如果觉得《Frida Hook Java动态加载DEX方法》对你有帮助,请点赞、收藏,并留下你的观点哦!