This commit is contained in:
solohsu 2019-04-03 11:05:32 +08:00
parent 7c7928760a
commit b8228e1da9
7 changed files with 45 additions and 17 deletions

View File

@ -7,6 +7,11 @@ import java.lang.reflect.Member;
public abstract class BaseHookProvider implements HookProvider { public abstract class BaseHookProvider implements HookProvider {
@Override
public void unhookMethod(Member method) {
}
public Member findMethodNative(Member hookMethod) { public Member findMethodNative(Member hookMethod) {
return hookMethod; return hookMethod;
} }

View File

@ -36,12 +36,12 @@ bool my_runtimeInit(void *runtime, void *mapAddr) {
return false; return false;
} }
LOGI("runtimeInit starts"); LOGI("runtimeInit starts");
bool result = (*runtimeInitBackup)(runtime, mapAddr); bool result = runtimeInitBackup(runtime, mapAddr);
if (!deoptBootImage) { if (!deoptBootImage) {
LOGE("deoptBootImageSym is null, skip deoptBootImage"); LOGE("deoptBootImageSym is null, skip deoptBootImage");
} else { } else {
LOGI("deoptBootImage starts"); LOGI("deoptBootImage starts");
(*deoptBootImage)(runtime); deoptBootImage(runtime);
LOGI("deoptBootImage finishes"); LOGI("deoptBootImage finishes");
} }
LOGI("runtimeInit finishes"); LOGI("runtimeInit finishes");
@ -50,8 +50,8 @@ bool my_runtimeInit(void *runtime, void *mapAddr) {
static bool onIsInSamePackageCalled(void *thiz, void *that) { static bool onIsInSamePackageCalled(void *thiz, void *that) {
std::string storage1, storage2; std::string storage1, storage2;
const char *thisDesc = (*getDesc)(thiz, &storage1); const char *thisDesc = getDesc(thiz, &storage1);
const char *thatDesc = (*getDesc)(that, &storage2); const char *thatDesc = getDesc(that, &storage2);
// Note: these identifiers should be consistent with those in Java layer // Note: these identifiers should be consistent with those in Java layer
if (strstr(thisDesc, "EdHooker_") != nullptr if (strstr(thisDesc, "EdHooker_") != nullptr
|| strstr(thatDesc, "EdHooker_") != nullptr || strstr(thatDesc, "EdHooker_") != nullptr
@ -128,13 +128,13 @@ static void hookIsInSamePackage(int api_level, void *artHandle,
return; return;
} }
getDesc = reinterpret_cast<const char *(*)(void *, std::string *)>(getDescSym); getDesc = reinterpret_cast<const char *(*)(void *, std::string *)>(getDescSym);
(*hookFun)(original, reinterpret_cast<void *>(onIsInSamePackageCalled), hookFun(original, reinterpret_cast<void *>(onIsInSamePackageCalled),
reinterpret_cast<void **>(&isInSamePackageBackup)); reinterpret_cast<void **>(&isInSamePackageBackup));
} }
void *my_classLinkerCst(void *classLinker, void *internTable) { void *my_classLinkerCst(void *classLinker, void *internTable) {
LOGI("classLinkerCst starts"); LOGI("classLinkerCst starts");
void *result = (*classLinkerCstBackup)(classLinker, internTable); void *result = classLinkerCstBackup(classLinker, internTable);
if (class_linker_ != classLinker) { if (class_linker_ != classLinker) {
LOGI("class_linker_ changed from %p to %p", class_linker_, classLinker); LOGI("class_linker_ changed from %p to %p", class_linker_, classLinker);
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()); LOGE("can't get deoptMethodSym: %s", dlerror());
return; return;
} }
(*hookFun)(classLinkerCstSym, reinterpret_cast<void *>(my_classLinkerCst), hookFun(classLinkerCstSym, reinterpret_cast<void *>(my_classLinkerCst),
reinterpret_cast<void **>(&classLinkerCstBackup)); reinterpret_cast<void **>(&classLinkerCstBackup));
LOGI("classLinkerCst hooked"); LOGI("classLinkerCst hooked");
} }
@ -184,7 +184,7 @@ void deoptimize_method(JNIEnv *env, jclass clazz, jobject method) {
return; return;
} }
LOGD("deoptimizing method: %p", reflected_method); LOGD("deoptimizing method: %p", reflected_method);
(*deoptMethod)(class_linker_, reflected_method); deoptMethod(class_linker_, reflected_method);
deoptedMethods.push_back(reflected_method); deoptedMethods.push_back(reflected_method);
LOGD("method deoptimized: %p", reflected_method); LOGD("method deoptimized: %p", reflected_method);
} }
@ -210,7 +210,7 @@ void hookRuntime(int api_level, void *artHandle, void (*hookFun)(void *, void *,
return; return;
} }
LOGI("start to hook runtimeInitSym"); LOGI("start to hook runtimeInitSym");
(*hookFun)(runtimeInitSym, reinterpret_cast<void *>(my_runtimeInit), hookFun(runtimeInitSym, reinterpret_cast<void *>(my_runtimeInit),
reinterpret_cast<void **>(&runtimeInitBackup)); reinterpret_cast<void **>(&runtimeInitBackup));
LOGI("runtimeInitSym hooked"); LOGI("runtimeInitSym hooked");
} else { } else {
@ -232,12 +232,12 @@ int waitGc(int gcCause, void *thread) {
LOGE("heap_ is null"); LOGE("heap_ is null");
return -1; return -1;
} }
return (*waitGcInternal)(heap_, gcCause, thread); return waitGcInternal(heap_, gcCause, thread);
} }
static void myHeapPreFork(void *heap) { static void myHeapPreFork(void *heap) {
heap_ = heap; heap_ = heap;
(*heapPreForkBackup)(heap); heapPreForkBackup(heap);
} }
void getSuspendSyms(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) { 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()); LOGE("can't find heapPreFork: %s", dlerror());
} else { } else {
// a chance to get pointer of the heap // a chance to get pointer of the heap
(*hookFun)(heapPreFork, reinterpret_cast<void *>(myHeapPreFork), hookFun(heapPreFork, reinterpret_cast<void *>(myHeapPreFork),
reinterpret_cast<void **>(&heapPreForkBackup)); reinterpret_cast<void **>(&heapPreForkBackup));
LOGI("heapPreFork hooked."); LOGI("heapPreFork hooked.");
} }

View File

@ -2,9 +2,9 @@ package com.elderdrivers.riru.edxp.sandhook.config;
import android.util.Log; 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.dexmaker.DynamicBridge;
import com.elderdrivers.riru.edxp.sandhook.util.PrebuiltMethodsDeopter;
import com.swift.sandhook.xposedcompat.XposedCompat; import com.swift.sandhook.xposedcompat.XposedCompat;
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge; import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
@ -13,7 +13,7 @@ import java.lang.reflect.Member;
import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedBridge;
public class SandHookProvider implements HookProvider { public class SandHookProvider extends BaseHookProvider {
@Override @Override
public void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo) { public void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo) {
if (SandHookXposedBridge.hooked(method) || DynamicBridge.hooked(method)) { if (SandHookXposedBridge.hooked(method) || DynamicBridge.hooked(method)) {

View File

@ -4,19 +4,34 @@ import com.elderdrivers.riru.edxp.config.BaseHookProvider;
import com.lody.whale.WhaleRuntime; import com.lody.whale.WhaleRuntime;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.util.HashMap;
import java.util.Map;
import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedBridge;
public class WhaleHookProvider extends BaseHookProvider { public class WhaleHookProvider extends BaseHookProvider {
private static final Map<Member, Long> sHookedMethodSlotMap = new HashMap<>();
@Override
public void unhookMethod(Member method) {
synchronized (sHookedMethodSlotMap) {
sHookedMethodSlotMap.remove(method);
}
}
@Override @Override
public void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo) { 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 @Override
public Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws Throwable { 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 @Override

View File

@ -53,6 +53,11 @@ public class EdXpConfigGlobal {
} }
@Override
public void unhookMethod(Member method) {
}
@Override @Override
public Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) public Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

View File

@ -8,6 +8,8 @@ public interface HookProvider {
void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo); void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo);
void unhookMethod(Member method);
Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws Throwable; Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws Throwable;
Member findMethodNative(Member hookMethod); Member findMethodNative(Member hookMethod);

View File

@ -214,6 +214,7 @@ public final class XposedBridge {
*/ */
@Deprecated @Deprecated
public static void unhookMethod(Member hookMethod, XC_MethodHook callback) { public static void unhookMethod(Member hookMethod, XC_MethodHook callback) {
EdXpConfigGlobal.getHookProvider().unhookMethod(hookMethod);
CopyOnWriteSortedSet<XC_MethodHook> callbacks; CopyOnWriteSortedSet<XC_MethodHook> callbacks;
synchronized (sHookedMethodCallbacks) { synchronized (sHookedMethodCallbacks) {
callbacks = sHookedMethodCallbacks.get(hookMethod); callbacks = sHookedMethodCallbacks.get(hookMethod);