首页
社区
课程
招聘
[求助]Xposed中动态加载的类如何Hook
发表于: 2025-5-5 22:57 1986

[求助]Xposed中动态加载的类如何Hook

2025-5-5 22:57
1986

本来想hook 某音极速版app的,从application中 attachBaseContext 方法开始,正常的基类Activity都能hook到,但是这个字节的app好像使用动态加载技术,商城部分的代码都是app打开后动态加载,我在加载后再设置classloader也不行,后面动态加载的类都hook不到会报错,由于对xposed还是不是很熟有没大佬解答下如何解决


这是是hook动态载入的类报错错误提示 java.lang.NoSuchFieldError: no type "LJ;" found and so no field "hooker" could be found in class "LLSPHooker_;" or its superclasses

这是原app的动态加载类
com.bytedance.mira.hook.delegate.DyMiraClassLoader
public class DyMiraClassLoader extends PathClassLoader implements InterfaceC1310253h {
    public static final DyMiraClassLoader sInstance = new DyMiraClassLoader(Mira.class.getClassLoader());
    public Method findResourceMethod;
    public Method findResourcesMethod;
    public ClassLoader pathClassLoader;

    @Override // X.InterfaceC1310253h
    public void onHookInstall() {
    }

    public static synchronized ClassLoader getHostClassLoader() {
        DyMiraClassLoader dyMiraClassLoader;
        synchronized (DyMiraClassLoader.class) {
            dyMiraClassLoader = sInstance;
        }
        return dyMiraClassLoader;
    }

    private void setPathClassLoader(ClassLoader classLoader) {
        this.pathClassLoader = classLoader;
    }

    @Override // dalvik.system.BaseDexClassLoader, java.lang.ClassLoader
    public Class<?> findClass(String str) {
        return ClassLoaderHelper.findClass(str);
    }

    public DyMiraClassLoader(ClassLoader classLoader) {
        super("", "", classLoader);
        this.findResourcesMethod = MethodUtils.getAccessibleMethod(ClassLoader.class, "findResources", String.class);
        this.findResourceMethod = MethodUtils.getAccessibleMethod(ClassLoader.class, "findResource", String.class);
        this.pathClassLoader = classLoader;
    }

    @Override // dalvik.system.BaseDexClassLoader, java.lang.ClassLoader
    public String findLibrary(String str) {
        String findLibrary = super.findLibrary(str);
        if (!TextUtils.isEmpty(findLibrary)) {
            return findLibrary;
        }
        Iterator it = new ConcurrentHashMap(PluginLoader.sCachedPluginClassLoader).entrySet().iterator();
        while (it.hasNext()) {
            Object value = ((Map.Entry) it.next()).getValue();
            try {
                String str2 = (String) MethodUtils.invokeMethod(value, "findLibraryFromCurrent", str);
                try {
                    StringBuilder sb = StringBuilderCache.get();
                    sb.append("DyMiraClassLoader laster.findLibrary, name=");
                    sb.append(str);
                    sb.append(", classLoader=");
                    sb.append(value);
                    MiraLogger.LIZJ("mira/so", StringBuilderCache.release(sb));
                } catch (Exception unused) {
                }
                findLibrary = str2;
            } catch (Exception unused2) {
            }
            if (!TextUtils.isEmpty(findLibrary)) {
                break;
            }
        }
        return findLibrary;
    }

    @Override // dalvik.system.BaseDexClassLoader, java.lang.ClassLoader
    public URL findResource(String str) {
        URL url = null;
        if (TextUtils.isEmpty(str)) {
            return null;
        }
        if (this.pathClassLoader == null) {
            this.pathClassLoader = Mira.getAppContext().getClass().getClassLoader();
        }
        Method method = this.findResourceMethod;
        if (method != null) {
            try {
                url = (URL) method.invoke(this.pathClassLoader, str);
            } catch (Throwable unused) {
            }
        }
        if (url == null && this.findResourceMethod != null) {
            Iterator it = new ConcurrentHashMap(PluginLoader.sCachedPluginClassLoader).entrySet().iterator();
            while (it.hasNext()) {
                try {
                    url = (URL) this.findResourceMethod.invoke(((Map.Entry) it.next()).getValue(), str);
                } catch (Throwable unused2) {
                }
                if (url != null) {
                    break;
                }
            }
        }
        if (url != null) {
            return url;
        }
        return super.findResource(str);
    }

    @Override // dalvik.system.BaseDexClassLoader, java.lang.ClassLoader
    public Enumeration<URL> findResources(String str) {
        Enumeration<URL> enumeration = null;
        if (TextUtils.isEmpty(str)) {
            return null;
        }
        if (this.pathClassLoader == null) {
            this.pathClassLoader = Mira.getAppContext().getClass().getClassLoader();
        }
        Method method = this.findResourcesMethod;
        if (method != null) {
            try {
                enumeration = (Enumeration) method.invoke(this.pathClassLoader, str);
            } catch (Throwable unused) {
            }
        }
        if (enumeration == null && this.findResourcesMethod != null) {
            Iterator it = new ConcurrentHashMap(PluginLoader.sCachedPluginClassLoader).entrySet().iterator();
            while (it.hasNext()) {
                try {
                    enumeration = (Enumeration) this.findResourcesMethod.invoke(((Map.Entry) it.next()).getValue(), str);
                } catch (Throwable unused2) {
                }
                if (enumeration != null) {
                    break;
                }
            }
        }
        if (enumeration != null) {
            return enumeration;
        }
        return super.findResources(str);
    }

    public static synchronized boolean installHook(Application application) {
        synchronized (DyMiraClassLoader.class) {
            try {
                Context baseContext = application.getBaseContext();
                if (baseContext == null) {
                    MiraLogger.LIZIZ("mira/init", "DyMiraClassLoader mBase is null", null);
                    return false;
                }
                Object readField = FieldUtils.readField(baseContext, "mPackageInfo");
                if (readField == null) {
                    StringBuilder sb = StringBuilderCache.get();
                    sb.append("DyMiraClassLoader cl=");
                    sb.append(baseContext.getClass());
                    MiraLogger.LIZIZ("mira/init", StringBuilderCache.release(sb), null);
                    return false;
                }
                StringBuilder sb2 = StringBuilderCache.get();
                sb2.append("DyMiraClassLoader patch: mBase cl=");
                sb2.append(baseContext.getClass());
                sb2.append("; mPackageInfo cl=");
                sb2.append(readField.getClass());
                MiraLogger.LIZ("mira/init", StringBuilderCache.release(sb2));
                ClassLoader classLoader = (ClassLoader) FieldUtils.readField(readField, "mClassLoader");
                if (classLoader == null) {
                    StringBuilder sb3 = StringBuilderCache.get();
                    sb3.append("DyMiraClassLoader cl=");
                    sb3.append(baseContext.getClass());
                    sb3.append("; mpi cl=");
                    sb3.append(readField.getClass());
                    MiraLogger.LIZIZ("mira/init", StringBuilderCache.release(sb3), null);
                    return false;
                }
                if (classLoader instanceof DyMiraClassLoader) {
                    return true;
                }
                DyMiraClassLoader dyMiraClassLoader = sInstance;
                if (dyMiraClassLoader.getParent() != classLoader) {
                    dyMiraClassLoader.setPathClassLoader(classLoader);
                    try {
                        Field field = FieldUtils.getField(ClassLoader.class, "parent");
                        if (field != null) {
                            GlobalProxyLancet.com_ss_android_ugc_aweme_lancet_FieldLancet_set(field, dyMiraClassLoader, classLoader);
                        }
                    } catch (Exception e) {
                        StringBuilder sb4 = StringBuilderCache.get();
                        sb4.append("ReflectUtils classloader=");
                        sb4.append(dyMiraClassLoader);
                        sb4.append(",updateClassLoaderParent fail!!!");
                        MiraLogger.LIZIZ("mira/init", StringBuilderCache.release(sb4), e);
                    }
                    MiraLogger.LIZ("mira/init", "DyMiraClassLoader patch: update instance parent classloader~");
                }
                DyMiraClassLoader dyMiraClassLoader2 = sInstance;
                FieldUtils.writeField(readField, "mClassLoader", dyMiraClassLoader2);
                ThreadMethodProxy.currentThread().setContextClassLoader(dyMiraClassLoader2);
                MiraLogger.LIZ("mira/init", "DyMiraClassLoader patch: patch mClassLoader ok");
                return true;
            } catch (Throwable th) {
                GlobalProxyLancet.com_ss_android_ugc_aweme_lancet_ThrowableLancet_thrPrintStackTrace(th);
                return false;
            }
        }
    }

    @Override // java.lang.ClassLoader
    public Class<?> loadClass(String str, boolean z) {
        return super.loadClass(str, z);
    }
}



[培训]科锐逆向工程师培训第53期2025年7月8日开班!

最后于 2025-5-6 20:48 被简biu编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 228
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
我有字节apphook经验,你hook classloader打印加载的类的位置,不对,你都知道hook啥了应该已经过了这一步了,我之前hook的部分也是动态加载的,我在一开始hook开始也会报错,但是后面加载了还是正常hook到了,try catch掉就行,或者判断是你要hook的类被加载时才开始hook
2025-5-16 17:44
0
游客
登录 | 注册 方可回帖
返回