From 205b328286de5a587b6f2377c2e0d72f1db9329f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E4=B8=BD=E6=AC=A3?= Date: Mon, 3 Aug 2020 23:55:24 +0800 Subject: [PATCH 1/2] Add setChild in classloader Add setChild option, you can only create classloader with one argument. Loader can always load class dynamically. --- .../classloaders/ProxyClassLoader.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/classloaders/ProxyClassLoader.java b/xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/classloaders/ProxyClassLoader.java index 69788b3a..4e9d46c2 100644 --- a/xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/classloaders/ProxyClassLoader.java +++ b/xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/classloaders/ProxyClassLoader.java @@ -2,13 +2,23 @@ public class ProxyClassLoader extends ClassLoader { - private final ClassLoader mClassLoader; + private ClassLoader mClassLoader; public ProxyClassLoader(ClassLoader parentCL, ClassLoader appCL) { super(parentCL); mClassLoader = appCL; } + public ProxyClassLoader(ClassLoader parent) + { + super(parent); + } + + public void setChild(ClassLoader child) + { + mClassLoader = child; + } + @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class clazz = null; @@ -21,10 +31,10 @@ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundE if (clazz == null) { clazz = super.loadClass(name, resolve); if (clazz == null) { - throw new ClassNotFoundException(); + throw new ClassNotFoundException("class not found in this scope "+name); } } return clazz; } -} \ No newline at end of file +} From 07700f1f5ba6d74669705b4a214e9fb518fefccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E4=B8=BD=E6=AC=A3?= Date: Tue, 4 Aug 2020 00:09:36 +0800 Subject: [PATCH 2/2] Fix classloader reuse with MIUI12 device Some XiaoMi device with MIUI12 user interface may get classloader reuse and lead crash. In sandvxposed this problem may lead module lose efficacy or crash when run in code of hook. --- .../xposedcompat/methodgen/DynamicBridge.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/methodgen/DynamicBridge.java b/xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/methodgen/DynamicBridge.java index 858df495..48762b1f 100644 --- a/xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/methodgen/DynamicBridge.java +++ b/xposedcompat/src/main/java/com/swift/sandhook/xposedcompat/methodgen/DynamicBridge.java @@ -72,8 +72,22 @@ public static synchronized void hookMethod(Member hookMethod, XposedBridge.Addit } else { hookMaker = defaultHookMaker; } + + ProxyClassLoader loader = new ProxyClassLoader(hookMethod.getDeclaringClass().getClassLoader()); + loader.setChild(DynamicBridge.class.getClassLoader()); + hookMaker.start(hookMethod, additionalHookInfo, - new ProxyClassLoader(DynamicBridge.class.getClassLoader(), hookMethod.getDeclaringClass().getClassLoader()), dexDir == null ? null : dexDir.getAbsolutePath()); + // ----------- + // 如果优先搜索当前类的类加载器,就会有相应方法类加载器复用 + // 并且有的手机魔改了libcore,例如小米MIUI12的部分机型 + // 造成提示XposedBridge.AdditionalHookInfo类加载器不对的问题。 + // 用最简单的方法解决问题,你当然可以直接动态代理AdditionalHookInfo里面的callback + // 也可以合并Elements,你喜欢就行。 + // 但是我们解决问题,优先采用简单粗暴的方法。 + // QQ 647564826 + // hookMethod classloader must be parent + loader, + dexDir == null ? null : dexDir.getAbsolutePath()); hookedInfo.put(hookMethod, hookMaker.getCallBackupMethod()); } DexLog.d("hook method <" + hookMethod.toString() + "> cost " + (System.currentTimeMillis() - timeStart) + " ms, by " + (stub != null ? "internal stub" : "dex maker"));