diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseHookProvider.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseHookProvider.java index 28d4d5fa..5f7fd05e 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseHookProvider.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseHookProvider.java @@ -7,6 +7,11 @@ import java.lang.reflect.Member; public abstract class BaseHookProvider implements HookProvider { + @Override + public void unhookMethod(Member method) { + + } + public Member findMethodNative(Member hookMethod) { return hookMethod; } diff --git a/edxp-core/jni/main/native_hook/native_hook.cpp b/edxp-core/jni/main/native_hook/native_hook.cpp index efa989a7..1cfc3e6b 100644 --- a/edxp-core/jni/main/native_hook/native_hook.cpp +++ b/edxp-core/jni/main/native_hook/native_hook.cpp @@ -36,12 +36,12 @@ bool my_runtimeInit(void *runtime, void *mapAddr) { return false; } LOGI("runtimeInit starts"); - bool result = (*runtimeInitBackup)(runtime, mapAddr); + bool result = runtimeInitBackup(runtime, mapAddr); if (!deoptBootImage) { LOGE("deoptBootImageSym is null, skip deoptBootImage"); } else { LOGI("deoptBootImage starts"); - (*deoptBootImage)(runtime); + deoptBootImage(runtime); LOGI("deoptBootImage finishes"); } LOGI("runtimeInit finishes"); @@ -50,8 +50,8 @@ bool my_runtimeInit(void *runtime, void *mapAddr) { static bool onIsInSamePackageCalled(void *thiz, void *that) { std::string storage1, storage2; - const char *thisDesc = (*getDesc)(thiz, &storage1); - const char *thatDesc = (*getDesc)(that, &storage2); + const char *thisDesc = getDesc(thiz, &storage1); + const char *thatDesc = getDesc(that, &storage2); // Note: these identifiers should be consistent with those in Java layer if (strstr(thisDesc, "EdHooker_") != nullptr || strstr(thatDesc, "EdHooker_") != nullptr @@ -128,13 +128,13 @@ static void hookIsInSamePackage(int api_level, void *artHandle, return; } getDesc = reinterpret_cast(getDescSym); - (*hookFun)(original, reinterpret_cast(onIsInSamePackageCalled), + hookFun(original, reinterpret_cast(onIsInSamePackageCalled), reinterpret_cast(&isInSamePackageBackup)); } void *my_classLinkerCst(void *classLinker, void *internTable) { LOGI("classLinkerCst starts"); - void *result = (*classLinkerCstBackup)(classLinker, internTable); + void *result = classLinkerCstBackup(classLinker, internTable); if (class_linker_ != classLinker) { LOGI("class_linker_ changed from %p to %p", class_linker_, classLinker); class_linker_ = classLinker; @@ -161,7 +161,7 @@ void hookInstrumentation(int api_level, void *artHandle, void (*hookFun)(void *, LOGE("can't get deoptMethodSym: %s", dlerror()); return; } - (*hookFun)(classLinkerCstSym, reinterpret_cast(my_classLinkerCst), + hookFun(classLinkerCstSym, reinterpret_cast(my_classLinkerCst), reinterpret_cast(&classLinkerCstBackup)); LOGI("classLinkerCst hooked"); } @@ -184,7 +184,7 @@ void deoptimize_method(JNIEnv *env, jclass clazz, jobject method) { return; } LOGD("deoptimizing method: %p", reflected_method); - (*deoptMethod)(class_linker_, reflected_method); + deoptMethod(class_linker_, reflected_method); deoptedMethods.push_back(reflected_method); LOGD("method deoptimized: %p", reflected_method); } @@ -210,7 +210,7 @@ void hookRuntime(int api_level, void *artHandle, void (*hookFun)(void *, void *, return; } LOGI("start to hook runtimeInitSym"); - (*hookFun)(runtimeInitSym, reinterpret_cast(my_runtimeInit), + hookFun(runtimeInitSym, reinterpret_cast(my_runtimeInit), reinterpret_cast(&runtimeInitBackup)); LOGI("runtimeInitSym hooked"); } else { @@ -232,12 +232,12 @@ int waitGc(int gcCause, void *thread) { LOGE("heap_ is null"); return -1; } - return (*waitGcInternal)(heap_, gcCause, thread); + return waitGcInternal(heap_, gcCause, thread); } static void myHeapPreFork(void *heap) { heap_ = heap; - (*heapPreForkBackup)(heap); + heapPreForkBackup(heap); } void getSuspendSyms(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) { @@ -249,7 +249,7 @@ void getSuspendSyms(int api_level, void *artHandle, void (*hookFun)(void *, void LOGE("can't find heapPreFork: %s", dlerror()); } else { // a chance to get pointer of the heap - (*hookFun)(heapPreFork, reinterpret_cast(myHeapPreFork), + hookFun(heapPreFork, reinterpret_cast(myHeapPreFork), reinterpret_cast(&heapPreForkBackup)); LOGI("heapPreFork hooked."); } 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 06d37075..df543516 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 @@ -2,9 +2,9 @@ package com.elderdrivers.riru.edxp.sandhook.config; import android.util.Log; -import com.elderdrivers.riru.edxp.hook.HookProvider; +import com.elderdrivers.riru.edxp.config.BaseHookProvider; +import com.elderdrivers.riru.edxp.deopt.PrebuiltMethodsDeopter; import com.elderdrivers.riru.edxp.sandhook.dexmaker.DynamicBridge; -import com.elderdrivers.riru.edxp.sandhook.util.PrebuiltMethodsDeopter; import com.swift.sandhook.xposedcompat.XposedCompat; import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge; @@ -13,7 +13,7 @@ import java.lang.reflect.Member; import de.robv.android.xposed.XposedBridge; -public class SandHookProvider implements HookProvider { +public class SandHookProvider extends BaseHookProvider { @Override public void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo) { if (SandHookXposedBridge.hooked(method) || DynamicBridge.hooked(method)) { diff --git a/edxp-whale/src/main/java/com/elderdrivers/riru/edxp/whale/config/WhaleHookProvider.java b/edxp-whale/src/main/java/com/elderdrivers/riru/edxp/whale/config/WhaleHookProvider.java index 57b6c6ce..571b5cb8 100644 --- a/edxp-whale/src/main/java/com/elderdrivers/riru/edxp/whale/config/WhaleHookProvider.java +++ b/edxp-whale/src/main/java/com/elderdrivers/riru/edxp/whale/config/WhaleHookProvider.java @@ -4,19 +4,34 @@ import com.elderdrivers.riru.edxp.config.BaseHookProvider; import com.lody.whale.WhaleRuntime; import java.lang.reflect.Member; +import java.util.HashMap; +import java.util.Map; import de.robv.android.xposed.XposedBridge; public class WhaleHookProvider extends BaseHookProvider { + private static final Map sHookedMethodSlotMap = new HashMap<>(); + + @Override + public void unhookMethod(Member method) { + synchronized (sHookedMethodSlotMap) { + sHookedMethodSlotMap.remove(method); + } + } + @Override public void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo) { - WhaleRuntime.hookMethodNative(method.getDeclaringClass(), method, additionalInfo); + long slot = WhaleRuntime.hookMethodNative(method.getDeclaringClass(), method, additionalInfo); + synchronized (sHookedMethodSlotMap) { + sHookedMethodSlotMap.put(method, slot); + } } @Override public Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws Throwable { - return WhaleRuntime.invokeOriginalMethodNative(methodId, thisObject, args); + long slot = sHookedMethodSlotMap.get(method); + return WhaleRuntime.invokeOriginalMethodNative(slot, thisObject, args); } @Override diff --git a/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdXpConfigGlobal.java b/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdXpConfigGlobal.java index dd06ef24..95c404a0 100644 --- a/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdXpConfigGlobal.java +++ b/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdXpConfigGlobal.java @@ -53,6 +53,11 @@ public class EdXpConfigGlobal { } + @Override + public void unhookMethod(Member method) { + + } + @Override public Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { diff --git a/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/hook/HookProvider.java b/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/hook/HookProvider.java index 50901c0f..119594db 100644 --- a/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/hook/HookProvider.java +++ b/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/hook/HookProvider.java @@ -8,6 +8,8 @@ public interface HookProvider { void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo); + void unhookMethod(Member method); + Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws Throwable; Member findMethodNative(Member hookMethod); 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..92e69d02 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 @@ -214,6 +214,7 @@ public final class XposedBridge { */ @Deprecated public static void unhookMethod(Member hookMethod, XC_MethodHook callback) { + EdXpConfigGlobal.getHookProvider().unhookMethod(hookMethod); CopyOnWriteSortedSet callbacks; synchronized (sHookedMethodCallbacks) { callbacks = sHookedMethodCallbacks.get(hookMethod);