Merge pull request #197 from ElderDrivers/sandhook

Sandhook
This commit is contained in:
solohsu 2019-03-30 16:55:25 +08:00 committed by GitHub
commit 70962c0860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 29 deletions

View File

@ -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')
}

View File

@ -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

View File

@ -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<Member, XposedBridge.CopyOnWriteSortedSet<XC_MethodHook>> 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);
@ -327,16 +325,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 +367,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 +382,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 +396,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);
}

View File

@ -37,7 +37,7 @@ public class HookerDexMakerNew implements HookMaker {
public static final String METHOD_NAME_HOOK = "hook";
public static final TypeId<Object[]> 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<Member> method = code.newLocal(memberTypeId);
// Local<Method> backupMethod = code.newLocal(methodTypeId);
Local<Member> originMethod = code.newLocal(memberTypeId);
Local<Method> backupMethod = code.newLocal(methodTypeId);
Local<XposedBridge.AdditionalHookInfo> hookInfo = code.newLocal(hookInfoTypeId);
Local<Object> thisObject = code.newLocal(TypeId.OBJECT);
Local<Object[]> args = code.newLocal(objArrayTypeId);
Local<Integer> actualParamSize = code.newLocal(TypeId.INT);
@ -253,10 +254,12 @@ public class HookerDexMakerNew implements HookMaker {
Map<TypeId, Local> 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);

View File

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