From 2bd0e305760e6540bb649d15658c863a960742bc Mon Sep 17 00:00:00 2001 From: swift_gan Date: Sat, 30 Mar 2019 10:35:19 +0800 Subject: [PATCH 1/4] SandHook: temporarily fix thread synchronization --- .../src/main/java/de/robv/android/xposed/XposedBridge.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java index 204a0b04..d0a2e2d3 100644 --- a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java +++ b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java @@ -14,10 +14,10 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import de.robv.android.xposed.XC_MethodHook.MethodHookParam; import de.robv.android.xposed.callbacks.XC_InitPackageResources; @@ -60,7 +60,7 @@ public final class XposedBridge { private static final Object[] EMPTY_ARRAY = new Object[0]; // built-in handlers - public static final Map> sHookedMethodCallbacks = new HashMap<>(); + public static final Map> sHookedMethodCallbacks = new ConcurrentHashMap<>(); public static final CopyOnWriteSortedSet sLoadedPackageCallbacks = new CopyOnWriteSortedSet<>(); /*package*/ static final CopyOnWriteSortedSet sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>(); From 184734b4b6ddaa24ee975fc0284715eb3e824399 Mon Sep 17 00:00:00 2001 From: swift_gan Date: Sat, 30 Mar 2019 14:42:12 +0800 Subject: [PATCH 2/4] SandHook: fix thread synchronization --- edxp-sandhook/build.gradle | 2 +- .../hookstub/HookStubManager.java | 35 ++++++++++--------- .../methodgen/HookerDexMakerNew.java | 19 +++++----- .../methodgen/SandHookXposedBridge.java | 2 +- .../de/robv/android/xposed/XposedBridge.java | 4 +-- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/edxp-sandhook/build.gradle b/edxp-sandhook/build.gradle index 67448739..21b5e374 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.3.4' + implementation 'com.swift.sandhook:hooklib:3.3.8' compileOnly project(':dexmaker') } diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java index 571b8ba5..dd7b918b 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java @@ -13,15 +13,12 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedHelpers; -import static de.robv.android.xposed.XposedBridge.sHookedMethodCallbacks; - public class HookStubManager { public static volatile boolean is64Bit; @@ -40,9 +37,7 @@ public class HookStubManager { public static Member[] originMethods; public static HookMethodEntity[] hookMethodEntities; - - private static final Map> hookCallbacks - = sHookedMethodCallbacks; + public static XposedBridge.AdditionalHookInfo[] additionalHookInfos; static { is64Bit = SandHook.is64Bit(); @@ -59,11 +54,12 @@ public class HookStubManager { } originMethods = new Member[ALL_STUB]; hookMethodEntities = new HookMethodEntity[ALL_STUB]; + additionalHookInfos = new XposedBridge.AdditionalHookInfo[ALL_STUB]; } } - public static HookMethodEntity getHookMethodEntity(Member origin) { + public static HookMethodEntity getHookMethodEntity(Member origin, XposedBridge.AdditionalHookInfo additionalHookInfo) { if (!support()) { return null; @@ -111,13 +107,14 @@ public class HookStubManager { HookMethodEntity entity = new HookMethodEntity(origin, stubMethodInfo.hook, stubMethodInfo.backup); entity.retType = retType; entity.parType = parType; - int id = getMethodId(stubMethodInfo.args, stubMethodInfo.index); - originMethods[id] = origin; - hookMethodEntities[id] = entity; if (hasStubBackup && !tryCompileAndResolveCallOriginMethod(entity.backup, stubMethodInfo.args, stubMethodInfo.index)) { DexLog.w("internal stub <" + entity.hook.getName() + "> call origin compile failure, skip use internal stub"); return null; } else { + int id = getMethodId(stubMethodInfo.args, stubMethodInfo.index); + originMethods[id] = origin; + hookMethodEntities[id] = entity; + additionalHookInfos[id] = additionalHookInfo; return entity; } } @@ -257,7 +254,8 @@ public class HookStubManager { DexLog.printMethodHookIn(originMethod); - Object[] snapshot = hookCallbacks.get(originMethod).getSnapshot(); + Object[] snapshot = additionalHookInfos[id].callbacks.getSnapshot(); + if (snapshot == null || snapshot.length == 0) { if (hasStubBackup) { return callOrigin.call(stubArgs); @@ -314,6 +312,7 @@ public class HookStubManager { try { ((XC_MethodHook) snapshot[afterIdx]).callAfterHookedMethod(param); } catch (Throwable t) { + XposedBridge.log(t); if (lastThrowable == null) param.setResult(lastResult); else @@ -327,16 +326,17 @@ public class HookStubManager { } } - public static Object hookBridge(Member origin, Object thiz, Object... args) throws Throwable { + public static Object hookBridge(Member origin, Method backup, XposedBridge.AdditionalHookInfo additionalHookInfo, Object thiz, Object... args) throws Throwable { if (XposedBridge.disableHooks) { - return SandHook.callOriginMethod(origin, thiz, args); + return SandHook.callOriginMethod(true, origin, backup, thiz, args); } DexLog.printMethodHookIn(origin); - Object[] snapshot = hookCallbacks.get(origin).getSnapshot(); + Object[] snapshot = additionalHookInfo.callbacks.getSnapshot(); + if (snapshot == null || snapshot.length == 0) { return SandHook.callOriginMethod(origin, thiz, args); } @@ -368,7 +368,7 @@ public class HookStubManager { // call original method if not requested otherwise if (!param.returnEarly) { try { - param.setResult(SandHook.callOriginMethod(origin, thiz, param.args)); + param.setResult(SandHook.callOriginMethod(true, origin, backup, thiz, param.args)); } catch (Throwable e) { param.setThrowable(e); } @@ -383,6 +383,7 @@ public class HookStubManager { try { ((XC_MethodHook) snapshot[afterIdx]).callAfterHookedMethod(param); } catch (Throwable t) { + XposedBridge.log(t); if (lastThrowable == null) param.setResult(lastResult); else @@ -396,8 +397,8 @@ public class HookStubManager { } } - public static long callOrigin(HookMethodEntity entity, Member origin, Object thiz, Object[] args) throws Throwable { - Object res = SandHook.callOriginMethod(origin, thiz, args); + public final static long callOrigin(HookMethodEntity entity, Member origin, Object thiz, Object[] args) throws Throwable { + Object res = SandHook.callOriginMethod(true, origin, entity.backup, thiz, args); return entity.getResultAddress(res); } 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 a6aa08a4..276f9caa 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 @@ -37,7 +37,7 @@ public class HookerDexMakerNew implements HookMaker { public static final String METHOD_NAME_HOOK = "hook"; public static final TypeId objArrayTypeId = TypeId.get(Object[].class); private static final String CLASS_DESC_PREFIX = "L"; - private static final String CLASS_NAME_PREFIX = "SandHookerN"; + private static final String CLASS_NAME_PREFIX = "SandHookerNew"; private static final String FIELD_NAME_HOOK_INFO = "additionalHookInfo"; private static final String FIELD_NAME_METHOD = "method"; private static final String FIELD_NAME_BACKUP_METHOD = "backupMethod"; @@ -237,12 +237,13 @@ public class HookerDexMakerNew implements HookMaker { private void generateHookMethod() { mHookMethodId = mHookerTypeId.getMethod(mReturnTypeId, METHOD_NAME_HOOK, mParameterTypeIds); - mSandHookBridgeMethodId = TypeId.get(HookStubManager.class).getMethod(TypeId.get(Object.class), "hookBridge", memberTypeId, TypeId.get(Object.class), TypeId.get(Object[].class)); + mSandHookBridgeMethodId = TypeId.get(HookStubManager.class).getMethod(TypeId.get(Object.class), "hookBridge", memberTypeId, methodTypeId, hookInfoTypeId, TypeId.get(Object.class), TypeId.get(Object[].class)); Code code = mDexMaker.declare(mHookMethodId, Modifier.PUBLIC | Modifier.STATIC); - Local method = code.newLocal(memberTypeId); - // Local backupMethod = code.newLocal(methodTypeId); + Local originMethod = code.newLocal(memberTypeId); + Local backupMethod = code.newLocal(methodTypeId); + Local hookInfo = code.newLocal(hookInfoTypeId); Local thisObject = code.newLocal(TypeId.OBJECT); Local args = code.newLocal(objArrayTypeId); Local actualParamSize = code.newLocal(TypeId.INT); @@ -253,10 +254,12 @@ public class HookerDexMakerNew implements HookMaker { Map resultLocals = createResultLocals(code); - code.sget(mMethodFieldId, method); code.loadConstant(args, null); code.loadConstant(argIndex, 0); -// code.sget(mBackupMethodFieldId, backupMethod); + code.sget(mMethodFieldId, originMethod); + code.sget(mBackupMethodFieldId, backupMethod); + code.sget(mHookInfoFieldId, hookInfo); + int paramsSize = mParameterTypeIds.length; int offset = 0; // thisObject @@ -282,10 +285,10 @@ public class HookerDexMakerNew implements HookMaker { } if (mReturnTypeId.equals(TypeId.VOID)) { - code.invokeStatic(mSandHookBridgeMethodId, null, method, thisObject, args); + code.invokeStatic(mSandHookBridgeMethodId, null, originMethod, backupMethod, hookInfo, thisObject, args); code.returnVoid(); } else { - code.invokeStatic(mSandHookBridgeMethodId, resultObj, method, thisObject, args); + code.invokeStatic(mSandHookBridgeMethodId, resultObj, originMethod, backupMethod, hookInfo, thisObject, args); TypeId objTypeId = getObjTypeIdIfPrimitive(mReturnTypeId); Local matchObjLocal = resultLocals.get(objTypeId); code.cast(matchObjLocal, resultObj); diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/SandHookXposedBridge.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/SandHookXposedBridge.java index c79c6311..8b369478 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/SandHookXposedBridge.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/methodgen/SandHookXposedBridge.java @@ -64,7 +64,7 @@ public final class SandHookXposedBridge { long timeStart = System.currentTimeMillis(); HookMethodEntity stub = null; if (XposedCompat.useInternalStub) { - stub = HookStubManager.getHookMethodEntity(hookMethod); + stub = HookStubManager.getHookMethodEntity(hookMethod, additionalHookInfo); } if (stub != null) { SandHook.hook(new HookWrapper.HookEntity(hookMethod, stub.hook, stub.backup, false)); diff --git a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java index d0a2e2d3..204a0b04 100644 --- a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java +++ b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java @@ -14,10 +14,10 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import de.robv.android.xposed.XC_MethodHook.MethodHookParam; import de.robv.android.xposed.callbacks.XC_InitPackageResources; @@ -60,7 +60,7 @@ public final class XposedBridge { private static final Object[] EMPTY_ARRAY = new Object[0]; // built-in handlers - public static final Map> sHookedMethodCallbacks = new ConcurrentHashMap<>(); + public static final Map> sHookedMethodCallbacks = new HashMap<>(); public static final CopyOnWriteSortedSet sLoadedPackageCallbacks = new CopyOnWriteSortedSet<>(); /*package*/ static final CopyOnWriteSortedSet sInitPackageResourcesCallbacks = new CopyOnWriteSortedSet<>(); From 07bb6952fa0030980cd00cc2c807b38444f91377 Mon Sep 17 00:00:00 2001 From: swift_gan Date: Sat, 30 Mar 2019 14:44:22 +0800 Subject: [PATCH 3/4] SandHook: remove log --- .../swift/sandhook/xposedcompat/hookstub/HookStubManager.java | 1 - 1 file changed, 1 deletion(-) diff --git a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java index dd7b918b..a6d6b2d9 100644 --- a/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java +++ b/edxp-sandhook/src/main/java/com/swift/sandhook/xposedcompat/hookstub/HookStubManager.java @@ -312,7 +312,6 @@ public class HookStubManager { try { ((XC_MethodHook) snapshot[afterIdx]).callAfterHookedMethod(param); } catch (Throwable t) { - XposedBridge.log(t); if (lastThrowable == null) param.setResult(lastResult); else From f025a73376fe392f584b8ce90717faa3419f413c Mon Sep 17 00:00:00 2001 From: swift_gan Date: Sat, 30 Mar 2019 16:49:15 +0800 Subject: [PATCH 4/4] SandHook: remove useless method finder --- .../riru/edxp/sandhook/config/SandHookProvider.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/config/SandHookProvider.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/config/SandHookProvider.java index f77dcfa6..06d37075 100644 --- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/config/SandHookProvider.java +++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/config/SandHookProvider.java @@ -3,7 +3,6 @@ package com.elderdrivers.riru.edxp.sandhook.config; import android.util.Log; import com.elderdrivers.riru.edxp.hook.HookProvider; -import com.elderdrivers.riru.edxp.sandhook.dexmaker.DexMakerUtils; import com.elderdrivers.riru.edxp.sandhook.dexmaker.DynamicBridge; import com.elderdrivers.riru.edxp.sandhook.util.PrebuiltMethodsDeopter; import com.swift.sandhook.xposedcompat.XposedCompat; @@ -42,7 +41,7 @@ public class SandHookProvider implements HookProvider { @Override public Member findMethodNative(Member hookMethod) { - return DexMakerUtils.findMethodNative(hookMethod); + return hookMethod; } @Override