Commit 4852ccf9 authored by swift_gan's avatar swift_gan

done new hooker maker

parent 0d617246
...@@ -102,6 +102,8 @@ public class SandHook { ...@@ -102,6 +102,8 @@ public class SandHook {
mode = hookModeCallBack.hookMode(target); mode = hookModeCallBack.hookMode(target);
} }
globalHookEntityMap.put(entity.target, entity);
int res; int res;
if (mode != HookMode.AUTO) { if (mode != HookMode.AUTO) {
res = hookMethod(target, hook, backup, mode); res = hookMethod(target, hook, backup, mode);
...@@ -121,11 +123,10 @@ public class SandHook { ...@@ -121,11 +123,10 @@ public class SandHook {
} }
if (res < 0) { if (res < 0) {
globalHookEntityMap.remove(entity.target);
throw new HookErrorException("hook method <" + entity.target.toString() + "> error in native!"); throw new HookErrorException("hook method <" + entity.target.toString() + "> error in native!");
} }
globalHookEntityMap.put(entity.target, entity);
if (entity.backup != null) { if (entity.backup != null) {
globalBackupMap.put(entity.backup, entity); globalBackupMap.put(entity.backup, entity);
} }
......
...@@ -27,6 +27,7 @@ public class XposedCompat { ...@@ -27,6 +27,7 @@ public class XposedCompat {
//try to use internal stub hooker & backup method to speed up hook //try to use internal stub hooker & backup method to speed up hook
public static volatile boolean useInternalStub = true; public static volatile boolean useInternalStub = true;
public static volatile boolean useNewDexMaker = true;
public static volatile boolean retryWhenCallOriginError = false; public static volatile boolean retryWhenCallOriginError = false;
private static ClassLoader sandHookXposedClassLoader; private static ClassLoader sandHookXposedClassLoader;
......
...@@ -322,6 +322,77 @@ public class HookStubManager { ...@@ -322,6 +322,77 @@ public class HookStubManager {
} }
} }
public static Object hookBridge(Member origin, Object thiz, Object... args) throws Throwable {
if (XposedBridge.disableHooks) {
return SandHook.callOriginMethod(origin, thiz, args);
}
DexLog.printMethodHookIn(origin);
Object[] snapshot = hookCallbacks.get(origin).getSnapshot();
if (snapshot == null || snapshot.length == 0) {
return SandHook.callOriginMethod(origin, thiz, args);
}
XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam();
param.method = origin;
param.thisObject = thiz;
param.args = args;
int beforeIdx = 0;
do {
try {
((XC_MethodHook) snapshot[beforeIdx]).callBeforeHookedMethod(param);
} catch (Throwable t) {
// reset result (ignoring what the unexpectedly exiting callback did)
param.setResult(null);
param.returnEarly = false;
continue;
}
if (param.returnEarly) {
// skip remaining "before" callbacks and corresponding "after" callbacks
beforeIdx++;
break;
}
} while (++beforeIdx < snapshot.length);
// call original method if not requested otherwise
if (!param.returnEarly) {
try {
param.setResult(SandHook.callOriginMethod(origin, thiz, param.args));
} catch (Throwable e) {
XposedBridge.log(e);
param.setThrowable(e);
}
}
// call "after method" callbacks
int afterIdx = beforeIdx - 1;
do {
Object lastResult = param.getResult();
Throwable lastThrowable = param.getThrowable();
try {
((XC_MethodHook) snapshot[afterIdx]).callAfterHookedMethod(param);
} catch (Throwable t) {
XposedBridge.log(t);
if (lastThrowable == null)
param.setResult(lastResult);
else
param.setThrowable(lastThrowable);
}
} while (--afterIdx >= 0);
if (!param.hasThrowable()) {
return param.getResult();
} else {
throw param.getThrowable();
}
}
public static long callOrigin(HookMethodEntity entity, Member origin, Object thiz, Object[] args) throws Throwable { public static long callOrigin(HookMethodEntity entity, Member origin, Object thiz, Object[] args) throws Throwable {
Object res = SandHook.callOriginMethod(origin, thiz, args); Object res = SandHook.callOriginMethod(origin, thiz, args);
return entity.getResultAddress(res); return entity.getResultAddress(res);
......
...@@ -24,7 +24,7 @@ import de.robv.android.xposed.XposedBridge; ...@@ -24,7 +24,7 @@ import de.robv.android.xposed.XposedBridge;
public final class DynamicBridge { public final class DynamicBridge {
private static final HashMap<Member, Method> hookedInfo = new HashMap<>(); private static final HashMap<Member, Method> hookedInfo = new HashMap<>();
private static final HookerDexMaker dexMaker = new HookerDexMaker(); private static HookMaker hookMaker = XposedCompat.useNewDexMaker ? new HookerDexMakerNew() : new HookerDexMaker();
private static final AtomicBoolean dexPathInited = new AtomicBoolean(false); private static final AtomicBoolean dexPathInited = new AtomicBoolean(false);
private static File dexDir; private static File dexDir;
...@@ -66,9 +66,9 @@ public final class DynamicBridge { ...@@ -66,9 +66,9 @@ public final class DynamicBridge {
SandHook.hook(new HookWrapper.HookEntity(hookMethod, stub.hook, stub.backup, false)); SandHook.hook(new HookWrapper.HookEntity(hookMethod, stub.hook, stub.backup, false));
entityMap.put(hookMethod, stub); entityMap.put(hookMethod, stub);
} else { } else {
dexMaker.start(hookMethod, additionalHookInfo, hookMaker.start(hookMethod, additionalHookInfo,
XposedCompat.classLoader, dexDir == null ? null : dexDir.getAbsolutePath()); XposedCompat.classLoader, dexDir == null ? null : dexDir.getAbsolutePath());
hookedInfo.put(hookMethod, dexMaker.getCallBackupMethod()); hookedInfo.put(hookMethod, hookMaker.getCallBackupMethod());
} }
DexLog.d("hook method <" + hookMethod.toString() + "> cost " + (System.currentTimeMillis() - timeStart) + " ms, by " + (stub != null ? "internal stub." : "dex maker")); DexLog.d("hook method <" + hookMethod.toString() + "> cost " + (System.currentTimeMillis() - timeStart) + " ms, by " + (stub != null ? "internal stub." : "dex maker"));
Trace.endSection(); Trace.endSection();
......
package com.swift.sandhook.xposedcompat.methodgen;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import de.robv.android.xposed.XposedBridge;
public interface HookMaker {
void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
ClassLoader appClassLoader, String dexDirPath) throws Exception;
Method getHookMethod();
Method getBackupMethod();
Method getCallBackupMethod();
}
...@@ -34,7 +34,7 @@ import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.autoUnboxIfNec ...@@ -34,7 +34,7 @@ import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.autoUnboxIfNec
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.createResultLocals; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.createResultLocals;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getObjTypeIdIfPrimitive; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getObjTypeIdIfPrimitive;
public class HookerDexMaker { public class HookerDexMaker implements HookMaker {
public static final String METHOD_NAME_BACKUP = "backup"; public static final String METHOD_NAME_BACKUP = "backup";
public static final String METHOD_NAME_HOOK = "hook"; public static final String METHOD_NAME_HOOK = "hook";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment