From 5828f7275f2000302d0fd721198d37d1fae811de Mon Sep 17 00:00:00 2001 From: swift_gan Date: Fri, 22 Mar 2019 10:27:33 +0800 Subject: [PATCH 1/5] [SandHook]convert all inner hookers to sandhook --- edxp-sandhook/build.gradle | 2 +- .../riru/edxp/sandhook/entry/Router.java | 54 ++++++++++++------- .../entry/bootstrap/AppBootstrapHookInfo.java | 7 ++- .../entry/bootstrap/SysBootstrapHookInfo.java | 8 ++- .../entry/bootstrap/WorkAroundHookInfo.java | 1 + .../entry/hooker/HandleBindAppHooker.java | 12 ++--- .../hooker/LoadedApkConstructorHooker.java | 9 ++-- .../entry/hooker/OnePlusWorkAroundHooker.java | 7 +-- .../hooker/StartBootstrapServicesHooker.java | 8 +-- .../entry/hooker/SystemMainHooker.java | 8 +-- 10 files changed, 71 insertions(+), 45 deletions(-) diff --git a/edxp-sandhook/build.gradle b/edxp-sandhook/build.gradle index c409c4a65..b6053f56a 100644 --- a/edxp-sandhook/build.gradle +++ b/edxp-sandhook/build.gradle @@ -24,7 +24,7 @@ dependencies { compileOnly files("libs/framework-stub.jar") implementation project(':edxp-common') implementation project(':xposed-bridge') - implementation 'com.swift.sandhook:hooklib:3.2.2' + implementation 'com.swift.sandhook:hooklib:3.2.7' compileOnly project(':dexmaker') } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/Router.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/Router.java index d7c126ceb..b2a4af398 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/Router.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/Router.java @@ -4,7 +4,6 @@ import android.text.TextUtils; import com.elderdrivers.riru.edxp.config.EdXpConfigGlobal; -import com.elderdrivers.riru.edxp.util.Utils; import com.elderdrivers.riru.edxp.sandhook.config.SandHookEdxpConfig; import com.elderdrivers.riru.edxp.sandhook.config.SandHookProvider; import com.elderdrivers.riru.edxp.sandhook.core.HookMain; @@ -14,9 +13,9 @@ import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.SysInnerHookInfo; import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.WorkAroundHookInfo; import com.elderdrivers.riru.edxp.sandhook.entry.hooker.SystemMainHooker; +import com.elderdrivers.riru.edxp.util.Utils; import com.swift.sandhook.SandHookConfig; import com.swift.sandhook.xposedcompat.XposedCompat; -import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge; import java.util.concurrent.atomic.AtomicBoolean; @@ -31,6 +30,12 @@ public class Router { private static volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false); + static boolean useSandHook; + + static { + useSandHook = EdXpConfigGlobal.getHookProvider() instanceof SandHookProvider; + } + public static void prepare(boolean isSystem) { // this flag is needed when loadModules @@ -81,33 +86,46 @@ public static void startBootstrapHook(boolean isSystem) { Utils.logD("startBootstrapHook starts: isSystem = " + isSystem); ClassLoader classLoader = XposedBridge.BOOTCLASSLOADER; if (isSystem) { - HookMain.doHookDefault( + if (useSandHook) { + XposedCompat.addHookers(classLoader, SysBootstrapHookInfo.hookItems); + } else { + HookMain.doHookDefault( Router.class.getClassLoader(), classLoader, SysBootstrapHookInfo.class.getName()); - XposedCompat.addHookers(classLoader, SysBootstrapHookInfo.hookItems); + } } else { - HookMain.doHookDefault( - Router.class.getClassLoader(), - classLoader, - AppBootstrapHookInfo.class.getName()); - XposedCompat.addHookers(classLoader, AppBootstrapHookInfo.hookItems); + if (useSandHook) { + XposedCompat.addHookers(classLoader, AppBootstrapHookInfo.hookItems); + } else { + HookMain.doHookDefault( + Router.class.getClassLoader(), + classLoader, + AppBootstrapHookInfo.class.getName()); + } } } public static void startSystemServerHook() { -// HookMain.doHookDefault( -// Router.class.getClassLoader(), -// SystemMainHooker.systemServerCL, -// SysInnerHookInfo.class.getName()); - XposedCompat.addHookers(SystemMainHooker.systemServerCL, SysInnerHookInfo.hookItems); + if (useSandHook) { + XposedCompat.addHookers(SystemMainHooker.systemServerCL, SysInnerHookInfo.hookItems); + } else { + HookMain.doHookDefault( + Router.class.getClassLoader(), + SystemMainHooker.systemServerCL, + SysInnerHookInfo.class.getName()); + } } public static void startWorkAroundHook() { - HookMain.doHookDefault( - Router.class.getClassLoader(), - XposedBridge.BOOTCLASSLOADER, - WorkAroundHookInfo.class.getName()); + if (useSandHook) { + XposedCompat.addHookers(XposedBridge.BOOTCLASSLOADER, WorkAroundHookInfo.hookItems); + } else { + HookMain.doHookDefault( + Router.class.getClassLoader(), + XposedBridge.BOOTCLASSLOADER, + WorkAroundHookInfo.class.getName()); + } } public static void onEnterChildProcess() { diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/AppBootstrapHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/AppBootstrapHookInfo.java index 09a15f136..ee352801f 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/AppBootstrapHookInfo.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/AppBootstrapHookInfo.java @@ -7,11 +7,14 @@ public class AppBootstrapHookInfo implements KeepMembers { public static String[] hookItemNames = { - OnePlusWorkAroundHooker.class.getName() + OnePlusWorkAroundHooker.class.getName(), + HandleBindAppHooker.class.getName(), + LoadedApkConstructorHooker.class.getName(), }; public static Class[] hookItems = { HandleBindAppHooker.class, - LoadedApkConstructorHooker.class + LoadedApkConstructorHooker.class, + OnePlusWorkAroundHooker.class }; } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/SysBootstrapHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/SysBootstrapHookInfo.java index 7befb2eaa..c9b0fbc1a 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/SysBootstrapHookInfo.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/SysBootstrapHookInfo.java @@ -8,12 +8,16 @@ public class SysBootstrapHookInfo implements KeepMembers { public static String[] hookItemNames = { - OnePlusWorkAroundHooker.class.getName() + OnePlusWorkAroundHooker.class.getName(), + HandleBindAppHooker.class.getName(), + SystemMainHooker.class.getName(), + LoadedApkConstructorHooker.class.getName() }; public static Class[] hookItems = { HandleBindAppHooker.class, SystemMainHooker.class, - LoadedApkConstructorHooker.class + LoadedApkConstructorHooker.class, + OnePlusWorkAroundHooker.class }; } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/WorkAroundHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/WorkAroundHookInfo.java index 4602349eb..7d255730d 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/WorkAroundHookInfo.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/WorkAroundHookInfo.java @@ -9,5 +9,6 @@ public class WorkAroundHookInfo implements KeepMembers { }; public static Class[] hookItems = { + OnePlusWorkAroundHooker.class }; } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/HandleBindAppHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/HandleBindAppHooker.java index ce987cc76..72c3099c9 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/HandleBindAppHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/HandleBindAppHooker.java @@ -7,14 +7,13 @@ import android.content.res.CompatibilityInfo; import com.elderdrivers.riru.common.KeepMembers; -import com.elderdrivers.riru.edxp.util.Utils; import com.elderdrivers.riru.edxp.Main; import com.elderdrivers.riru.edxp.sandhook.entry.Router; +import com.elderdrivers.riru.edxp.util.Utils; import com.swift.sandhook.SandHook; import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethodBackup; -import com.swift.sandhook.annotation.HookMode; import com.swift.sandhook.annotation.Param; import com.swift.sandhook.annotation.SkipParamCheck; import com.swift.sandhook.annotation.ThisObject; @@ -27,8 +26,8 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME; -import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader; import static com.elderdrivers.riru.edxp.sandhook.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME; +import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader; // normal process initialization (for new Activity, Service, BroadcastReceiver etc.) @HookClass(ActivityThread.class) @@ -45,7 +44,7 @@ public class HandleBindAppHooker implements KeepMembers { @HookMethod("handleBindApplication") public static void hook(@ThisObject ActivityThread thiz, @Param("android.app.ActivityThread$AppBindData") Object bindData) throws Throwable { if (XposedBlackListHooker.shouldDisableHooks("")) { - SandHook.callOriginByBackup(backup, thiz, bindData); + backup(thiz, bindData); return; } try { @@ -96,10 +95,11 @@ public static void hook(@ThisObject ActivityThread thiz, @Param("android.app.Act } catch (Throwable t) { Router.logE("error when hooking bindApp", t); } finally { - SandHook.callOriginByBackup(backup, thiz, bindData); + backup(thiz, bindData); } } - public static void backup(Object thiz, Object bindData) { + public static void backup(Object thiz, Object bindData) throws Throwable { + SandHook.callOriginByBackup(backup, thiz, bindData); } } \ No newline at end of file diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/LoadedApkConstructorHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/LoadedApkConstructorHooker.java index 8121d63d3..46daac80f 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/LoadedApkConstructorHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/LoadedApkConstructorHooker.java @@ -47,13 +47,12 @@ public static void hook(@ThisObject Object thiz, ActivityThread activityThread, boolean includeCode, boolean registerPackage) throws Throwable { if (XposedBlackListHooker.shouldDisableHooks("")) { - SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); - + backup(thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); return; } Router.logD("LoadedApk# starts"); - SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); + backup(thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); try { LoadedApk loadedApk = (LoadedApk) thiz; @@ -105,7 +104,7 @@ public static void hook(@ThisObject Object thiz, ActivityThread activityThread, public static void backup(Object thiz, ActivityThread activityThread, ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, - boolean includeCode, boolean registerPackage) { - + boolean includeCode, boolean registerPackage) throws Throwable { + SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); } } \ No newline at end of file diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/OnePlusWorkAroundHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/OnePlusWorkAroundHooker.java index d0995649b..9066a1126 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/OnePlusWorkAroundHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/OnePlusWorkAroundHooker.java @@ -3,6 +3,7 @@ import com.elderdrivers.riru.common.KeepMembers; import com.elderdrivers.riru.edxp.Main; import com.elderdrivers.riru.edxp.sandhook.entry.Router; +import com.swift.sandhook.SandHook; import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethodBackup; @@ -40,7 +41,7 @@ public class OnePlusWorkAroundHooker implements KeepMembers { static Method backup; @HookMethod("inCompatConfigList") - public static boolean hook(int type, String packageName) { + public static boolean hook(int type, String packageName) throws Throwable { if (XposedBridge.disableHooks || Router.forkCompleted) { return backup(type, packageName); } @@ -48,7 +49,7 @@ public static boolean hook(int type, String packageName) { return false; } - public static boolean backup(int type, String packageName) { - return false; + public static boolean backup(int type, String packageName) throws Throwable { + return (boolean) SandHook.callOriginByBackup(backup, null, type, packageName); } } \ No newline at end of file diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/StartBootstrapServicesHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/StartBootstrapServicesHooker.java index 39a69266e..082d0d36c 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/StartBootstrapServicesHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/StartBootstrapServicesHooker.java @@ -38,7 +38,7 @@ public class StartBootstrapServicesHooker implements KeepMembers { public static void hook(@ThisObject Object systemServer) throws Throwable { if (XposedBridge.disableHooks) { - SandHook.callOriginByBackup(backup, systemServer); + backup(systemServer); return; } @@ -71,11 +71,11 @@ public static void hook(@ThisObject Object systemServer) throws Throwable { } catch (Throwable t) { Router.logE("error when hooking startBootstrapServices", t); } finally { - SandHook.callOriginByBackup(backup, systemServer); + backup(systemServer); } } - public static void backup(Object systemServer) { - + public static void backup(Object systemServer) throws Throwable { + SandHook.callOriginByBackup(backup, systemServer); } } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/SystemMainHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/SystemMainHooker.java index 5b9ae61b3..c5d6d1fd5 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/SystemMainHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/SystemMainHooker.java @@ -33,10 +33,10 @@ public class SystemMainHooker implements KeepMembers { @HookMethod("systemMain") public static ActivityThread hook() throws Throwable { if (XposedBridge.disableHooks) { - return (ActivityThread) SandHook.callOriginByBackup(backup, null); + return backup(); } Router.logD("ActivityThread#systemMain() starts"); - ActivityThread activityThread = (ActivityThread) SandHook.callOriginByBackup(backup, null); + ActivityThread activityThread = backup(); try { // get system_server classLoader systemServerCL = Thread.currentThread().getContextClassLoader(); @@ -49,7 +49,7 @@ public static ActivityThread hook() throws Throwable { return activityThread; } - public static ActivityThread backup() { - return null; + public static ActivityThread backup() throws Throwable { + return (ActivityThread) SandHook.callOriginByBackup(backup, null); } } \ No newline at end of file From e616da055311f58f9a53838164d3fd389abd85c1 Mon Sep 17 00:00:00 2001 From: swift_gan Date: Fri, 22 Mar 2019 13:32:53 +0800 Subject: [PATCH 2/5] SandHook: tweak DexMaker --- .../external/com/android/dx/DexMaker.java | 71 ++++++++++++++++--- .../methodgen/HookerDexMaker.java | 4 +- .../methodgen/HookerDexMakerNew.java | 4 +- .../sandhook/xposedcompat/utils/DexLog.java | 36 +++------- 4 files changed, 76 insertions(+), 39 deletions(-) diff --git a/dexmaker/src/main/java/external/com/android/dx/DexMaker.java b/dexmaker/src/main/java/external/com/android/dx/DexMaker.java index 037cb428a..62efd8458 100644 --- a/dexmaker/src/main/java/external/com/android/dx/DexMaker.java +++ b/dexmaker/src/main/java/external/com/android/dx/DexMaker.java @@ -230,7 +230,7 @@ TypeDeclaration getTypeDeclaration(TypeId type) { * Modifier#FINAL} and {@link Modifier#ABSTRACT}. */ public void declare(TypeId type, String sourceFile, int flags, - TypeId supertype, TypeId... interfaces) { + TypeId supertype, TypeId... interfaces) { TypeDeclaration declaration = getTypeDeclaration(type); int supportedFlags = Modifier.PUBLIC | Modifier.FINAL | Modifier.ABSTRACT | AccessFlags.ACC_SYNTHETIC; @@ -471,8 +471,23 @@ private ClassLoader generateClassLoader(File result, File dexCache, ClassLoader } } + public ClassLoader loadClassDirect(ClassLoader parent, File dexCache, String dexFileName) { + File result = new File(dexCache, dexFileName); + // Check that the file exists. If it does, return a DexClassLoader and skip all + // the dex bytecode generation. + if (result.exists()) { + return generateClassLoader(result, dexCache, parent); + } else { + return null; + } + } + public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOException { - return generateAndLoad(parent, dexCache, null); + return generateAndLoad(parent, dexCache, generateFileName(), false); + } + + public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String dexFileName) throws IOException { + return generateAndLoad(parent, dexCache, dexFileName, false); } /** @@ -500,9 +515,8 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOE * @param dexCache the destination directory where generated and optimized * dex files will be written. If null, this class will try to guess the * application's private data dir. - * @param fileName the name of dex file */ - public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fileName) throws IOException { + public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String dexFileName, boolean deleteOld) throws IOException { if (dexCache == null) { String property = System.getProperty("dexmaker.dexcache"); if (property != null) { @@ -516,13 +530,17 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil } } - if (fileName == null || fileName.isEmpty()) - fileName = generateFileName(); - File result = new File(dexCache, fileName); - // Check that the file exists. If it does, return a DexClassLoader and skip all - // the dex bytecode generation. + File result = new File(dexCache, dexFileName); + if (result.exists()) { - return generateClassLoader(result, dexCache, parent); + if (deleteOld) { + try { + deleteOldDex(result); + } catch (Throwable throwable) { + } + } else { + return generateClassLoader(result, dexCache, parent); + } } /* @@ -532,7 +550,14 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil * * TODO: load the dex from memory where supported. */ + + File parentDir = result.getParentFile(); + if (!parentDir.exists()) { + parentDir.mkdirs(); + } + result.createNewFile(); + JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result)); JarEntry entry = new JarEntry(DexFormat.DEX_IN_JAR_NAME); byte[] dex = generate(); @@ -544,6 +569,32 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil return generateClassLoader(result, dexCache, parent); } + public void deleteOldDex(File dexFile) { + dexFile.delete(); + String dexDir = dexFile.getParent(); + File oatDir = new File(dexDir, "/oat/"); + File oatDirArm = new File(oatDir, "/arm/"); + File oatDirArm64 = new File(oatDir, "/arm64/"); + if (!oatDir.exists()) + return; + String nameStart = dexFile.getName().replaceAll(".jar", ""); + doDeleteOatFiles(oatDir, nameStart); + doDeleteOatFiles(oatDirArm, nameStart); + doDeleteOatFiles(oatDirArm64, nameStart); + } + + private void doDeleteOatFiles(File dir, String nameStart) { + if (!dir.exists()) + return; + File[] oats = dir.listFiles(); + if (oats == null) + return; + for (File oatFile:oats) { + if (oatFile.isFile() && oatFile.getName().startsWith(nameStart)) + oatFile.delete(); + } + } + DexFile getDexFile() { if (outputDex == null) { DexOptions options = new DexOptions(); diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java index f5d410afe..465b25330 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java @@ -190,7 +190,7 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo, HookWrapper.HookEntity hookEntity = null; //try load cache first try { - ClassLoader loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName); + ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(mDexDirPath), dexName); if (loader != null) { hookEntity = loadHookerClass(loader, className); } @@ -222,7 +222,7 @@ private HookWrapper.HookEntity doMake(String className, String dexName) throws E } // Create the dex file and load it. try { - loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName); + loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName, true); } catch (IOException e) { //can not write file byte[] dexBytes = mDexMaker.generate(); diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java index 38fad272d..a6aa08a46 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java @@ -150,7 +150,7 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo, HookWrapper.HookEntity hookEntity = null; //try load cache first try { - ClassLoader loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName); + ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(mDexDirPath), dexName); if (loader != null) { hookEntity = loadHookerClass(loader, className); } @@ -176,7 +176,7 @@ private HookWrapper.HookEntity doMake(String className, String dexName) throws E } // Create the dex file and load it. try { - loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName); + loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName, true); } catch (IOException e) { //can not write file byte[] dexBytes = mDexMaker.generate(); diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/utils/DexLog.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/utils/DexLog.java index 9aefa8883..be45ace5f 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/utils/DexLog.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/utils/DexLog.java @@ -9,14 +9,10 @@ public class DexLog { public static final String TAG = "SandXposed"; - public static volatile boolean DEBUG = true; + public static volatile boolean DEBUG = false; public static int v(String s) { - if (DEBUG) { - return Log.v(TAG, s); - } else { - return 0; - } + return Log.v(TAG, s); } public static int i(String s) { @@ -24,7 +20,11 @@ public static int i(String s) { } public static int d(String s) { - return Log.d(TAG, s); + if (DEBUG) { + return Log.d(TAG, s); + } else { + return 0; + } } public static void printMethodHookIn(Member member) { @@ -34,33 +34,19 @@ public static void printMethodHookIn(Member member) { } public static void printCallOriginError(Member member) { - if (DEBUG && member != null) { - Log.d("SandHook", "method <" + member.toString() + "> call origin error!"); - } + Log.e("SandHook", "method <" + member.toString() + "> call origin error!"); } public static int w(String s) { - if (DEBUG) { - return Log.w(TAG, s); - } else { - return 0; - } + return Log.w(TAG, s); } public static int e(String s) { - if (DEBUG) { - return Log.e(TAG, s); - } else { - return 0; - } + return Log.e(TAG, s); } public static int e(String s, Throwable t) { - if (DEBUG) { - return Log.e(TAG, s, t); - } else { - return 0; - } + return Log.e(TAG, s, t); } From be8da25aa20a0061e8eb8adc472c58fec806f99e Mon Sep 17 00:00:00 2001 From: swift_gan Date: Fri, 22 Mar 2019 10:27:33 +0800 Subject: [PATCH 3/5] SandHook: convert all inner hookers to sandhook --- edxp-sandhook/build.gradle | 2 +- .../riru/edxp/sandhook/entry/Router.java | 54 ++++++++++++------- .../entry/bootstrap/AppBootstrapHookInfo.java | 7 ++- .../entry/bootstrap/SysBootstrapHookInfo.java | 8 ++- .../entry/bootstrap/WorkAroundHookInfo.java | 1 + .../entry/hooker/HandleBindAppHooker.java | 12 ++--- .../hooker/LoadedApkConstructorHooker.java | 9 ++-- .../entry/hooker/OnePlusWorkAroundHooker.java | 7 +-- .../hooker/StartBootstrapServicesHooker.java | 8 +-- .../entry/hooker/SystemMainHooker.java | 8 +-- 10 files changed, 71 insertions(+), 45 deletions(-) diff --git a/edxp-sandhook/build.gradle b/edxp-sandhook/build.gradle index c409c4a65..b6053f56a 100644 --- a/edxp-sandhook/build.gradle +++ b/edxp-sandhook/build.gradle @@ -24,7 +24,7 @@ dependencies { compileOnly files("libs/framework-stub.jar") implementation project(':edxp-common') implementation project(':xposed-bridge') - implementation 'com.swift.sandhook:hooklib:3.2.2' + implementation 'com.swift.sandhook:hooklib:3.2.7' compileOnly project(':dexmaker') } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/Router.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/Router.java index d7c126ceb..b2a4af398 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/Router.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/Router.java @@ -4,7 +4,6 @@ import android.text.TextUtils; import com.elderdrivers.riru.edxp.config.EdXpConfigGlobal; -import com.elderdrivers.riru.edxp.util.Utils; import com.elderdrivers.riru.edxp.sandhook.config.SandHookEdxpConfig; import com.elderdrivers.riru.edxp.sandhook.config.SandHookProvider; import com.elderdrivers.riru.edxp.sandhook.core.HookMain; @@ -14,9 +13,9 @@ import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.SysInnerHookInfo; import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.WorkAroundHookInfo; import com.elderdrivers.riru.edxp.sandhook.entry.hooker.SystemMainHooker; +import com.elderdrivers.riru.edxp.util.Utils; import com.swift.sandhook.SandHookConfig; import com.swift.sandhook.xposedcompat.XposedCompat; -import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge; import java.util.concurrent.atomic.AtomicBoolean; @@ -31,6 +30,12 @@ public class Router { private static volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false); + static boolean useSandHook; + + static { + useSandHook = EdXpConfigGlobal.getHookProvider() instanceof SandHookProvider; + } + public static void prepare(boolean isSystem) { // this flag is needed when loadModules @@ -81,33 +86,46 @@ public static void startBootstrapHook(boolean isSystem) { Utils.logD("startBootstrapHook starts: isSystem = " + isSystem); ClassLoader classLoader = XposedBridge.BOOTCLASSLOADER; if (isSystem) { - HookMain.doHookDefault( + if (useSandHook) { + XposedCompat.addHookers(classLoader, SysBootstrapHookInfo.hookItems); + } else { + HookMain.doHookDefault( Router.class.getClassLoader(), classLoader, SysBootstrapHookInfo.class.getName()); - XposedCompat.addHookers(classLoader, SysBootstrapHookInfo.hookItems); + } } else { - HookMain.doHookDefault( - Router.class.getClassLoader(), - classLoader, - AppBootstrapHookInfo.class.getName()); - XposedCompat.addHookers(classLoader, AppBootstrapHookInfo.hookItems); + if (useSandHook) { + XposedCompat.addHookers(classLoader, AppBootstrapHookInfo.hookItems); + } else { + HookMain.doHookDefault( + Router.class.getClassLoader(), + classLoader, + AppBootstrapHookInfo.class.getName()); + } } } public static void startSystemServerHook() { -// HookMain.doHookDefault( -// Router.class.getClassLoader(), -// SystemMainHooker.systemServerCL, -// SysInnerHookInfo.class.getName()); - XposedCompat.addHookers(SystemMainHooker.systemServerCL, SysInnerHookInfo.hookItems); + if (useSandHook) { + XposedCompat.addHookers(SystemMainHooker.systemServerCL, SysInnerHookInfo.hookItems); + } else { + HookMain.doHookDefault( + Router.class.getClassLoader(), + SystemMainHooker.systemServerCL, + SysInnerHookInfo.class.getName()); + } } public static void startWorkAroundHook() { - HookMain.doHookDefault( - Router.class.getClassLoader(), - XposedBridge.BOOTCLASSLOADER, - WorkAroundHookInfo.class.getName()); + if (useSandHook) { + XposedCompat.addHookers(XposedBridge.BOOTCLASSLOADER, WorkAroundHookInfo.hookItems); + } else { + HookMain.doHookDefault( + Router.class.getClassLoader(), + XposedBridge.BOOTCLASSLOADER, + WorkAroundHookInfo.class.getName()); + } } public static void onEnterChildProcess() { diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/AppBootstrapHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/AppBootstrapHookInfo.java index 09a15f136..ee352801f 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/AppBootstrapHookInfo.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/AppBootstrapHookInfo.java @@ -7,11 +7,14 @@ public class AppBootstrapHookInfo implements KeepMembers { public static String[] hookItemNames = { - OnePlusWorkAroundHooker.class.getName() + OnePlusWorkAroundHooker.class.getName(), + HandleBindAppHooker.class.getName(), + LoadedApkConstructorHooker.class.getName(), }; public static Class[] hookItems = { HandleBindAppHooker.class, - LoadedApkConstructorHooker.class + LoadedApkConstructorHooker.class, + OnePlusWorkAroundHooker.class }; } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/SysBootstrapHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/SysBootstrapHookInfo.java index 7befb2eaa..c9b0fbc1a 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/SysBootstrapHookInfo.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/SysBootstrapHookInfo.java @@ -8,12 +8,16 @@ public class SysBootstrapHookInfo implements KeepMembers { public static String[] hookItemNames = { - OnePlusWorkAroundHooker.class.getName() + OnePlusWorkAroundHooker.class.getName(), + HandleBindAppHooker.class.getName(), + SystemMainHooker.class.getName(), + LoadedApkConstructorHooker.class.getName() }; public static Class[] hookItems = { HandleBindAppHooker.class, SystemMainHooker.class, - LoadedApkConstructorHooker.class + LoadedApkConstructorHooker.class, + OnePlusWorkAroundHooker.class }; } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/WorkAroundHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/WorkAroundHookInfo.java index 4602349eb..7d255730d 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/WorkAroundHookInfo.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/bootstrap/WorkAroundHookInfo.java @@ -9,5 +9,6 @@ public class WorkAroundHookInfo implements KeepMembers { }; public static Class[] hookItems = { + OnePlusWorkAroundHooker.class }; } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/HandleBindAppHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/HandleBindAppHooker.java index ce987cc76..72c3099c9 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/HandleBindAppHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/HandleBindAppHooker.java @@ -7,14 +7,13 @@ import android.content.res.CompatibilityInfo; import com.elderdrivers.riru.common.KeepMembers; -import com.elderdrivers.riru.edxp.util.Utils; import com.elderdrivers.riru.edxp.Main; import com.elderdrivers.riru.edxp.sandhook.entry.Router; +import com.elderdrivers.riru.edxp.util.Utils; import com.swift.sandhook.SandHook; import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethodBackup; -import com.swift.sandhook.annotation.HookMode; import com.swift.sandhook.annotation.Param; import com.swift.sandhook.annotation.SkipParamCheck; import com.swift.sandhook.annotation.ThisObject; @@ -27,8 +26,8 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage; import static com.elderdrivers.riru.edxp.config.InstallerChooser.INSTALLER_PACKAGE_NAME; -import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader; import static com.elderdrivers.riru.edxp.sandhook.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME; +import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClassLoader; // normal process initialization (for new Activity, Service, BroadcastReceiver etc.) @HookClass(ActivityThread.class) @@ -45,7 +44,7 @@ public class HandleBindAppHooker implements KeepMembers { @HookMethod("handleBindApplication") public static void hook(@ThisObject ActivityThread thiz, @Param("android.app.ActivityThread$AppBindData") Object bindData) throws Throwable { if (XposedBlackListHooker.shouldDisableHooks("")) { - SandHook.callOriginByBackup(backup, thiz, bindData); + backup(thiz, bindData); return; } try { @@ -96,10 +95,11 @@ public static void hook(@ThisObject ActivityThread thiz, @Param("android.app.Act } catch (Throwable t) { Router.logE("error when hooking bindApp", t); } finally { - SandHook.callOriginByBackup(backup, thiz, bindData); + backup(thiz, bindData); } } - public static void backup(Object thiz, Object bindData) { + public static void backup(Object thiz, Object bindData) throws Throwable { + SandHook.callOriginByBackup(backup, thiz, bindData); } } \ No newline at end of file diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/LoadedApkConstructorHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/LoadedApkConstructorHooker.java index 8121d63d3..46daac80f 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/LoadedApkConstructorHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/LoadedApkConstructorHooker.java @@ -47,13 +47,12 @@ public static void hook(@ThisObject Object thiz, ActivityThread activityThread, boolean includeCode, boolean registerPackage) throws Throwable { if (XposedBlackListHooker.shouldDisableHooks("")) { - SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); - + backup(thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); return; } Router.logD("LoadedApk# starts"); - SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); + backup(thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); try { LoadedApk loadedApk = (LoadedApk) thiz; @@ -105,7 +104,7 @@ public static void hook(@ThisObject Object thiz, ActivityThread activityThread, public static void backup(Object thiz, ActivityThread activityThread, ApplicationInfo aInfo, CompatibilityInfo compatInfo, ClassLoader baseLoader, boolean securityViolation, - boolean includeCode, boolean registerPackage) { - + boolean includeCode, boolean registerPackage) throws Throwable { + SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage); } } \ No newline at end of file diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/OnePlusWorkAroundHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/OnePlusWorkAroundHooker.java index d0995649b..9066a1126 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/OnePlusWorkAroundHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/OnePlusWorkAroundHooker.java @@ -3,6 +3,7 @@ import com.elderdrivers.riru.common.KeepMembers; import com.elderdrivers.riru.edxp.Main; import com.elderdrivers.riru.edxp.sandhook.entry.Router; +import com.swift.sandhook.SandHook; import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethodBackup; @@ -40,7 +41,7 @@ public class OnePlusWorkAroundHooker implements KeepMembers { static Method backup; @HookMethod("inCompatConfigList") - public static boolean hook(int type, String packageName) { + public static boolean hook(int type, String packageName) throws Throwable { if (XposedBridge.disableHooks || Router.forkCompleted) { return backup(type, packageName); } @@ -48,7 +49,7 @@ public static boolean hook(int type, String packageName) { return false; } - public static boolean backup(int type, String packageName) { - return false; + public static boolean backup(int type, String packageName) throws Throwable { + return (boolean) SandHook.callOriginByBackup(backup, null, type, packageName); } } \ No newline at end of file diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/StartBootstrapServicesHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/StartBootstrapServicesHooker.java index 39a69266e..082d0d36c 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/StartBootstrapServicesHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/StartBootstrapServicesHooker.java @@ -38,7 +38,7 @@ public class StartBootstrapServicesHooker implements KeepMembers { public static void hook(@ThisObject Object systemServer) throws Throwable { if (XposedBridge.disableHooks) { - SandHook.callOriginByBackup(backup, systemServer); + backup(systemServer); return; } @@ -71,11 +71,11 @@ public static void hook(@ThisObject Object systemServer) throws Throwable { } catch (Throwable t) { Router.logE("error when hooking startBootstrapServices", t); } finally { - SandHook.callOriginByBackup(backup, systemServer); + backup(systemServer); } } - public static void backup(Object systemServer) { - + public static void backup(Object systemServer) throws Throwable { + SandHook.callOriginByBackup(backup, systemServer); } } diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/SystemMainHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/SystemMainHooker.java index 5b9ae61b3..c5d6d1fd5 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/SystemMainHooker.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/hooker/SystemMainHooker.java @@ -33,10 +33,10 @@ public class SystemMainHooker implements KeepMembers { @HookMethod("systemMain") public static ActivityThread hook() throws Throwable { if (XposedBridge.disableHooks) { - return (ActivityThread) SandHook.callOriginByBackup(backup, null); + return backup(); } Router.logD("ActivityThread#systemMain() starts"); - ActivityThread activityThread = (ActivityThread) SandHook.callOriginByBackup(backup, null); + ActivityThread activityThread = backup(); try { // get system_server classLoader systemServerCL = Thread.currentThread().getContextClassLoader(); @@ -49,7 +49,7 @@ public static ActivityThread hook() throws Throwable { return activityThread; } - public static ActivityThread backup() { - return null; + public static ActivityThread backup() throws Throwable { + return (ActivityThread) SandHook.callOriginByBackup(backup, null); } } \ No newline at end of file From bd90c8234df63f63d8f8814305835c881da7862a Mon Sep 17 00:00:00 2001 From: swift_gan Date: Fri, 22 Mar 2019 13:32:53 +0800 Subject: [PATCH 4/5] SandHook: tweak DexMaker --- .../external/com/android/dx/DexMaker.java | 71 ++++++++++++++++--- .../methodgen/HookerDexMaker.java | 4 +- .../methodgen/HookerDexMakerNew.java | 4 +- .../sandhook/xposedcompat/utils/DexLog.java | 36 +++------- 4 files changed, 76 insertions(+), 39 deletions(-) diff --git a/dexmaker/src/main/java/external/com/android/dx/DexMaker.java b/dexmaker/src/main/java/external/com/android/dx/DexMaker.java index 037cb428a..62efd8458 100644 --- a/dexmaker/src/main/java/external/com/android/dx/DexMaker.java +++ b/dexmaker/src/main/java/external/com/android/dx/DexMaker.java @@ -230,7 +230,7 @@ TypeDeclaration getTypeDeclaration(TypeId type) { * Modifier#FINAL} and {@link Modifier#ABSTRACT}. */ public void declare(TypeId type, String sourceFile, int flags, - TypeId supertype, TypeId... interfaces) { + TypeId supertype, TypeId... interfaces) { TypeDeclaration declaration = getTypeDeclaration(type); int supportedFlags = Modifier.PUBLIC | Modifier.FINAL | Modifier.ABSTRACT | AccessFlags.ACC_SYNTHETIC; @@ -471,8 +471,23 @@ private ClassLoader generateClassLoader(File result, File dexCache, ClassLoader } } + public ClassLoader loadClassDirect(ClassLoader parent, File dexCache, String dexFileName) { + File result = new File(dexCache, dexFileName); + // Check that the file exists. If it does, return a DexClassLoader and skip all + // the dex bytecode generation. + if (result.exists()) { + return generateClassLoader(result, dexCache, parent); + } else { + return null; + } + } + public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOException { - return generateAndLoad(parent, dexCache, null); + return generateAndLoad(parent, dexCache, generateFileName(), false); + } + + public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String dexFileName) throws IOException { + return generateAndLoad(parent, dexCache, dexFileName, false); } /** @@ -500,9 +515,8 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOE * @param dexCache the destination directory where generated and optimized * dex files will be written. If null, this class will try to guess the * application's private data dir. - * @param fileName the name of dex file */ - public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fileName) throws IOException { + public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String dexFileName, boolean deleteOld) throws IOException { if (dexCache == null) { String property = System.getProperty("dexmaker.dexcache"); if (property != null) { @@ -516,13 +530,17 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil } } - if (fileName == null || fileName.isEmpty()) - fileName = generateFileName(); - File result = new File(dexCache, fileName); - // Check that the file exists. If it does, return a DexClassLoader and skip all - // the dex bytecode generation. + File result = new File(dexCache, dexFileName); + if (result.exists()) { - return generateClassLoader(result, dexCache, parent); + if (deleteOld) { + try { + deleteOldDex(result); + } catch (Throwable throwable) { + } + } else { + return generateClassLoader(result, dexCache, parent); + } } /* @@ -532,7 +550,14 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil * * TODO: load the dex from memory where supported. */ + + File parentDir = result.getParentFile(); + if (!parentDir.exists()) { + parentDir.mkdirs(); + } + result.createNewFile(); + JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(result)); JarEntry entry = new JarEntry(DexFormat.DEX_IN_JAR_NAME); byte[] dex = generate(); @@ -544,6 +569,32 @@ public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fil return generateClassLoader(result, dexCache, parent); } + public void deleteOldDex(File dexFile) { + dexFile.delete(); + String dexDir = dexFile.getParent(); + File oatDir = new File(dexDir, "/oat/"); + File oatDirArm = new File(oatDir, "/arm/"); + File oatDirArm64 = new File(oatDir, "/arm64/"); + if (!oatDir.exists()) + return; + String nameStart = dexFile.getName().replaceAll(".jar", ""); + doDeleteOatFiles(oatDir, nameStart); + doDeleteOatFiles(oatDirArm, nameStart); + doDeleteOatFiles(oatDirArm64, nameStart); + } + + private void doDeleteOatFiles(File dir, String nameStart) { + if (!dir.exists()) + return; + File[] oats = dir.listFiles(); + if (oats == null) + return; + for (File oatFile:oats) { + if (oatFile.isFile() && oatFile.getName().startsWith(nameStart)) + oatFile.delete(); + } + } + DexFile getDexFile() { if (outputDex == null) { DexOptions options = new DexOptions(); diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java index f5d410afe..465b25330 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMaker.java @@ -190,7 +190,7 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo, HookWrapper.HookEntity hookEntity = null; //try load cache first try { - ClassLoader loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName); + ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(mDexDirPath), dexName); if (loader != null) { hookEntity = loadHookerClass(loader, className); } @@ -222,7 +222,7 @@ private HookWrapper.HookEntity doMake(String className, String dexName) throws E } // Create the dex file and load it. try { - loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName); + loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName, true); } catch (IOException e) { //can not write file byte[] dexBytes = mDexMaker.generate(); diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java index 38fad272d..a6aa08a46 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/HookerDexMakerNew.java @@ -150,7 +150,7 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo, HookWrapper.HookEntity hookEntity = null; //try load cache first try { - ClassLoader loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName); + ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(mDexDirPath), dexName); if (loader != null) { hookEntity = loadHookerClass(loader, className); } @@ -176,7 +176,7 @@ private HookWrapper.HookEntity doMake(String className, String dexName) throws E } // Create the dex file and load it. try { - loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName); + loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName, true); } catch (IOException e) { //can not write file byte[] dexBytes = mDexMaker.generate(); diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/utils/DexLog.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/utils/DexLog.java index 9aefa8883..be45ace5f 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/utils/DexLog.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/utils/DexLog.java @@ -9,14 +9,10 @@ public class DexLog { public static final String TAG = "SandXposed"; - public static volatile boolean DEBUG = true; + public static volatile boolean DEBUG = false; public static int v(String s) { - if (DEBUG) { - return Log.v(TAG, s); - } else { - return 0; - } + return Log.v(TAG, s); } public static int i(String s) { @@ -24,7 +20,11 @@ public static int i(String s) { } public static int d(String s) { - return Log.d(TAG, s); + if (DEBUG) { + return Log.d(TAG, s); + } else { + return 0; + } } public static void printMethodHookIn(Member member) { @@ -34,33 +34,19 @@ public static void printMethodHookIn(Member member) { } public static void printCallOriginError(Member member) { - if (DEBUG && member != null) { - Log.d("SandHook", "method <" + member.toString() + "> call origin error!"); - } + Log.e("SandHook", "method <" + member.toString() + "> call origin error!"); } public static int w(String s) { - if (DEBUG) { - return Log.w(TAG, s); - } else { - return 0; - } + return Log.w(TAG, s); } public static int e(String s) { - if (DEBUG) { - return Log.e(TAG, s); - } else { - return 0; - } + return Log.e(TAG, s); } public static int e(String s, Throwable t) { - if (DEBUG) { - return Log.e(TAG, s, t); - } else { - return 0; - } + return Log.e(TAG, s, t); } From 1dfcec51f75a471070f390129c07afdcc467b614 Mon Sep 17 00:00:00 2001 From: swift_gan Date: Fri, 22 Mar 2019 15:01:46 +0800 Subject: [PATCH 5/5] SandHook: update sandhook to fix OS 8.0 - 8.1 --- edxp-sandhook/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edxp-sandhook/build.gradle b/edxp-sandhook/build.gradle index b6053f56a..642aeba3e 100644 --- a/edxp-sandhook/build.gradle +++ b/edxp-sandhook/build.gradle @@ -24,7 +24,7 @@ dependencies { compileOnly files("libs/framework-stub.jar") implementation project(':edxp-common') implementation project(':xposed-bridge') - implementation 'com.swift.sandhook:hooklib:3.2.7' + implementation 'com.swift.sandhook:hooklib:3.2.8' compileOnly project(':dexmaker') }