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<>();