如何hook动态加载的dex?

常见的 DEX 加载方式包括 DexClassLoaderPathClassLoaderBaseDexClassLoader,可以通过 Hook 这些类的方法来劫持 DEX 加载过程。


1. 使用 Xposed/LSPosed Hook DexClassLoader

在 Android 设备上,如果目标 App 使用 DexClassLoader 进行动态加载 DEX,可以用 Xposed Hook 其 loadClass 方法:

XposedHelpers.findAndHookMethod(
    "dalvik.system.DexClassLoader",
    lpparam.classLoader,
    "loadClass",
    String.class,
    new XC_MethodHook() {
        @Override
        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
            String className = (String) param.args[0];
            XposedBridge.log("Loading class: " + className);
        }

        @Override
        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            Class<?> loadedClass = (Class<?>) param.getResult();
            XposedBridge.log("Loaded class: " + (loadedClass != null ? loadedClass.getName() : "null"));
        }
    }
);

适用场景

  • 目标 App 通过 DexClassLoader 动态加载 DEX。
  • 可以使用 Xposed/LSPosed。

2. Hook BaseDexClassLoader 以拦截所有 DEX 加载

Android 5.0 以上,DexClassLoaderPathClassLoader 继承自 BaseDexClassLoader,可以直接 Hook BaseDexClassLoader 构造函数:

XposedHelpers.findAndHookConstructor(
    "dalvik.system.BaseDexClassLoader",
    lpparam.classLoader,
    String.class, String.class, String.class, ClassLoader.class,
    new XC_MethodHook() {
        @Override
        protected void beforeHookedMethod(MethodHookParam param) {
            String dexPath = (String) param.args[0];
            XposedBridge.log("Loading DEX file: " + dexPath);
        }
    }
);

适用场景

  • 适用于 DexClassLoaderPathClassLoader,通用性更强。

3. Hook dalvik.system.InMemoryDexClassLoader

从 Android 8.0 (API 26) 开始,可以使用 InMemoryDexClassLoader 直接从字节数组加载 DEX:

XposedHelpers.findAndHookConstructor(
    "dalvik.system.InMemoryDexClassLoader",
    lpparam.classLoader,
    ByteBuffer.class, ClassLoader.class,
    new XC_MethodHook() {
        @Override
        protected void beforeHookedMethod(MethodHookParam param) {
            XposedBridge.log("Loading DEX from memory!");
        }
    }
);

适用场景

  • 适用于 Android 8.0 及以上,目标 App 可能使用 InMemoryDexClassLoader 加载 DEX。

4. Inline Hook DexFile.loadDex(适用于非 Xposed 场景)

如果你无法使用 Xposed,可以使用 Inline Hook(如 Frida、Inline Hook 框架)直接 Hook DexFile.loadDex()

void* (*orig_loadDex)(const char*, const char*, int);
void* my_loadDex(const char* dexPath, const char* odexPath, int flags) {
    LOGD("Hooked loadDex: %s", dexPath);
    return orig_loadDex(dexPath, odexPath, flags);
}

void hook_loadDex() {
    void* addr = dlsym(RTLD_DEFAULT, "DexFile_loadDex");
    if (addr) {
        HOOK_FUNCTION(addr, my_loadDex, orig_loadDex);
    }
}

适用场景

  • 目标 App 可能调用 DexFile.loadDex() 直接加载 DEX。

5. 使用 Frida 动态 Hook DexClassLoader

如果没有 Xposed,可以用 Frida 进行动态 Hook:

Java.perform(function() {
    var DexClassLoader = Java.use("dalvik.system.DexClassLoader");
    DexClassLoader.$init.implementation = function(dexPath, optimizedDirectory, libraryPath, parent) {
        console.log("Loading DEX: " + dexPath);
        return this.$init(dexPath, optimizedDirectory, libraryPath, parent);
    };
});

适用场景

  • 目标设备已 Root,可以使用 Frida 进行动态 Hook。

总结

方法适用场景适用工具
Hook DexClassLoader.loadClass()目标 App 使用 DexClassLoader 加载 DEXXposed/LSPosed
Hook BaseDexClassLoader 构造方法拦截所有 DEX 加载方式Xposed/LSPosed
Hook InMemoryDexClassLoader适用于 Android 8+Xposed/LSPosed
Inline Hook DexFile.loadDex()低级拦截 DEX 加载Inline Hook
Frida Hook DexClassLoader目标设备已 RootFrida

function hookTest9(){
    Java.perform(function(){
        Java.enumerateClassLoaders({
           onMatch:function(loader){
                try{
                    if(loader.loadClass("com.alexw.app")){
                        Java.classFactory.loader=loader;
                        var app=Java.use("com.alexw.app");
                        console.log(app);
                        app.sayHello.implementation=function(){
                            return "bye";
                        }
                    }catch(error){

                    }
                },
                onComplete:function(){

                }
           }
        });
    });
}

https://bbs.kanxue.com/thread-229657.htm
高质量文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值