Commit 5d50e0ba authored by swift_gan's avatar swift_gan Committed by swift_gan

tweak hook stubs

parent c17f756a
...@@ -17,6 +17,8 @@ import com.swift.sandhook.test.TestClass; ...@@ -17,6 +17,8 @@ import com.swift.sandhook.test.TestClass;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import de.robv.android.xposed.XposedHelpers;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
Inter inter; Inter inter;
...@@ -51,7 +53,7 @@ public class MainActivity extends AppCompatActivity { ...@@ -51,7 +53,7 @@ public class MainActivity extends AppCompatActivity {
// Example of a call to a native method // Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text); TextView tv = (TextView) findViewById(R.id.sample_text);
TestClass str = new TestClass(1); final TestClass str = new TestClass(1);
str.add1(); str.add1();
str.add2(); str.add2();
...@@ -73,6 +75,7 @@ public class MainActivity extends AppCompatActivity { ...@@ -73,6 +75,7 @@ public class MainActivity extends AppCompatActivity {
Log.e("dosth", hashCode() + ""); Log.e("dosth", hashCode() + "");
} }
}; };
Log.e("testStub", "res = " + testStub(str, 1, "origin b", false, 'x', "origin e"));
} }
}).start(); }).start();
...@@ -122,6 +125,11 @@ public class MainActivity extends AppCompatActivity { ...@@ -122,6 +125,11 @@ public class MainActivity extends AppCompatActivity {
return testClass.a; return testClass.a;
} }
public Integer testStub(TestClass testClass, int a, String b, boolean c, char d, String e) {
Log.e("MainActivity", "call testStub origin" + a + ("" + c) + d + e);
return a;
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will // Handle action bar item clicks here. The action bar will
......
...@@ -4,6 +4,7 @@ import android.app.Activity; ...@@ -4,6 +4,7 @@ import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.util.Log; import android.util.Log;
import com.swift.sandhook.test.TestClass;
import com.swift.sandhook.testHookers.ActivityHooker; import com.swift.sandhook.testHookers.ActivityHooker;
import com.swift.sandhook.testHookers.CtrHook; import com.swift.sandhook.testHookers.CtrHook;
import com.swift.sandhook.testHookers.CustmizeHooker; import com.swift.sandhook.testHookers.CustmizeHooker;
...@@ -57,6 +58,22 @@ public class MyApp extends Application { ...@@ -57,6 +58,22 @@ public class MyApp extends Application {
} }
}); });
XposedHelpers.findAndHookMethod(MainActivity.class, "testStub", TestClass.class, int.class, String.class, boolean.class, char.class, String.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
param.args[1] = 2;
Log.e("XposedCompat", "beforeHookedMethod: " + param.method.getName());
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.e("XposedCompat", "afterHookedMethod: " + param.method.getName());
}
});
try { try {
ClassLoader classLoader = getClassLoader(); ClassLoader classLoader = getClassLoader();
DexClassLoader dexClassLoader = new DexClassLoader("/sdcard/hookers-debug.apk", DexClassLoader dexClassLoader = new DexClassLoader("/sdcard/hookers-debug.apk",
......
...@@ -3,6 +3,7 @@ package com.swift.sandhook.testHookers; ...@@ -3,6 +3,7 @@ package com.swift.sandhook.testHookers;
import android.util.Log; import android.util.Log;
import com.swift.sandhook.annotation.HookMode; import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.annotation.ThisObject;
import com.swift.sandhook.test.TestClass; import com.swift.sandhook.test.TestClass;
import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethod;
...@@ -13,13 +14,13 @@ public class JniHooker { ...@@ -13,13 +14,13 @@ public class JniHooker {
@HookMethod("jni_test") @HookMethod("jni_test")
@HookMode(HookMode.INLINE) @HookMode(HookMode.INLINE)
public static int onJni(TestClass thiz) { public static int onJni(@ThisObject TestClass thiz) {
Log.e("JniHooker", "hooked success "); Log.e("JniHooker", "hooked success ");
return onJniBackup(thiz); return onJniBackup(thiz);
} }
@HookMethodBackup("jni_test") @HookMethodBackup("jni_test")
public static int onJniBackup(TestClass thiz) { public static int onJniBackup(@ThisObject TestClass thiz) {
return onJniBackup(thiz); return onJniBackup(thiz);
} }
......
...@@ -58,9 +58,9 @@ void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMeth ...@@ -58,9 +58,9 @@ void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMeth
} }
} }
void ensureMethodDeclaringClass(art::mirror::ArtMethod *origin, art::mirror::ArtMethod *backup) { void ensureBackupMethod(art::mirror::ArtMethod *origin, art::mirror::ArtMethod *backup) {
if (origin->getDeclaringClassPtr() != backup->getDeclaringClassPtr()) { if (origin->getDeclaringClassPtr() != backup->getDeclaringClassPtr()) {
LOGW("backup method declaringClass is out to date due to Moving GC!"); LOGW("backup method is out to date due to Moving GC!");
SandHook::HookTrampoline* trampoline = trampolineManager.getHookTrampoline(origin); SandHook::HookTrampoline* trampoline = trampolineManager.getHookTrampoline(origin);
if (trampoline == nullptr) if (trampoline == nullptr)
...@@ -271,7 +271,7 @@ Java_com_swift_sandhook_SandHook_ensureMethodCached(JNIEnv *env, jclass type, jo ...@@ -271,7 +271,7 @@ Java_com_swift_sandhook_SandHook_ensureMethodCached(JNIEnv *env, jclass type, jo
extern "C" extern "C"
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_com_swift_sandhook_SandHook_ensureMethodDeclaringClass(JNIEnv *env, jclass type, Java_com_swift_sandhook_SandHook_ensureBackupMethod(JNIEnv *env, jclass type,
jobject originMethod, jobject originMethod,
jobject backupMethod) { jobject backupMethod) {
if (backupMethod == NULL || originMethod == NULL) if (backupMethod == NULL || originMethod == NULL)
...@@ -279,7 +279,7 @@ Java_com_swift_sandhook_SandHook_ensureMethodDeclaringClass(JNIEnv *env, jclass ...@@ -279,7 +279,7 @@ Java_com_swift_sandhook_SandHook_ensureMethodDeclaringClass(JNIEnv *env, jclass
art::mirror::ArtMethod* origin = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(originMethod)); art::mirror::ArtMethod* origin = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(originMethod));
art::mirror::ArtMethod* backup = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(backupMethod)); art::mirror::ArtMethod* backup = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(backupMethod));
ensureMethodDeclaringClass(origin, backup); ensureBackupMethod(origin, backup);
} }
extern "C" extern "C"
......
...@@ -149,30 +149,39 @@ public class SandHook { ...@@ -149,30 +149,39 @@ public class SandHook {
public static Object callOriginMethod(Member originMethod, Method backupMethod, Object thiz, Object[] args) throws Throwable { public static Object callOriginMethod(Member originMethod, Method backupMethod, Object thiz, Object[] args) throws Throwable {
backupMethod.setAccessible(true); backupMethod.setAccessible(true);
if (Modifier.isStatic(originMethod.getModifiers())) { if (Modifier.isStatic(originMethod.getModifiers())) {
ensureMethodDeclaringClass(originMethod, backupMethod);
return backupMethod.invoke(null, args); return backupMethod.invoke(null, args);
} else { } else {
ensureMethodDeclaringClass(originMethod, backupMethod);
return backupMethod.invoke(thiz, args); return backupMethod.invoke(thiz, args);
} }
} }
public static void ensureBackupDeclaringClass(Method backupMethod) { public static Object ensureBackupAndCallOriginMethod(Member originMethod, Method backupMethod, Object thiz, Object[] args) throws Throwable {
backupMethod.setAccessible(true);
if (Modifier.isStatic(originMethod.getModifiers())) {
ensureBackupMethod(originMethod, backupMethod);
return backupMethod.invoke(null, args);
} else {
ensureBackupMethod(originMethod, backupMethod);
return backupMethod.invoke(thiz, args);
}
}
public static void ensureBackupMethod(Method backupMethod) {
if (backupMethod == null) if (backupMethod == null)
return; return;
HookWrapper.HookEntity hookEntity = globalBackupMap.get(backupMethod); HookWrapper.HookEntity hookEntity = globalBackupMap.get(backupMethod);
if (hookEntity == null) if (hookEntity == null)
return; return;
ensureMethodDeclaringClass(hookEntity.target, backupMethod); ensureBackupMethod(hookEntity.target, backupMethod);
} }
public static void ensureBackupDelaringClassByOrigin(Member originMethod) { public static void ensureBackupMethodByOrigin(Member originMethod) {
if (originMethod == null) if (originMethod == null)
return; return;
HookWrapper.HookEntity hookEntity = globalHookEntityMap.get(originMethod); HookWrapper.HookEntity hookEntity = globalHookEntityMap.get(originMethod);
if (hookEntity == null || hookEntity.backup == null) if (hookEntity == null || hookEntity.backup == null)
return; return;
ensureMethodDeclaringClass(originMethod, hookEntity.backup); ensureBackupMethod(originMethod, hookEntity.backup);
} }
...@@ -304,7 +313,7 @@ public class SandHook { ...@@ -304,7 +313,7 @@ public class SandHook {
public static native void ensureMethodCached(Method hook, Method backup); public static native void ensureMethodCached(Method hook, Method backup);
public static native void ensureMethodDeclaringClass(Member originMethod, Method backupMethod); public static native void ensureBackupMethod(Member originMethod, Method backupMethod);
public static native boolean compileMethod(Member member); public static native boolean compileMethod(Member member);
......
...@@ -4,7 +4,7 @@ import java.lang.reflect.Method; ...@@ -4,7 +4,7 @@ import java.lang.reflect.Method;
public class BackupMethodStubs { public class BackupMethodStubs {
final static int maxStub = 100; final static int maxStub = 300;
private static volatile int curStub = 0; private static volatile int curStub = 0;
public static synchronized Method getStubMethod() { public static synchronized Method getStubMethod() {
...@@ -118,5 +118,204 @@ public class BackupMethodStubs { ...@@ -118,5 +118,204 @@ public class BackupMethodStubs {
public void stub98() {} public void stub98() {}
public void stub99() {} public void stub99() {}
public void stub100() {} public void stub100() {}
public void stub101() {}
public void stub102() {}
public void stub103() {}
public void stub104() {}
public void stub105() {}
public void stub106() {}
public void stub107() {}
public void stub108() {}
public void stub109() {}
public void stub110() {}
public void stub111() {}
public void stub112() {}
public void stub113() {}
public void stub114() {}
public void stub115() {}
public void stub116() {}
public void stub117() {}
public void stub118() {}
public void stub119() {}
public void stub120() {}
public void stub121() {}
public void stub122() {}
public void stub123() {}
public void stub124() {}
public void stub125() {}
public void stub126() {}
public void stub127() {}
public void stub128() {}
public void stub129() {}
public void stub130() {}
public void stub131() {}
public void stub132() {}
public void stub133() {}
public void stub134() {}
public void stub135() {}
public void stub136() {}
public void stub137() {}
public void stub138() {}
public void stub139() {}
public void stub140() {}
public void stub141() {}
public void stub142() {}
public void stub143() {}
public void stub144() {}
public void stub145() {}
public void stub146() {}
public void stub147() {}
public void stub148() {}
public void stub149() {}
public void stub150() {}
public void stub151() {}
public void stub152() {}
public void stub153() {}
public void stub154() {}
public void stub155() {}
public void stub156() {}
public void stub157() {}
public void stub158() {}
public void stub159() {}
public void stub160() {}
public void stub161() {}
public void stub162() {}
public void stub163() {}
public void stub164() {}
public void stub165() {}
public void stub166() {}
public void stub167() {}
public void stub168() {}
public void stub169() {}
public void stub170() {}
public void stub171() {}
public void stub172() {}
public void stub173() {}
public void stub174() {}
public void stub175() {}
public void stub176() {}
public void stub177() {}
public void stub178() {}
public void stub179() {}
public void stub180() {}
public void stub181() {}
public void stub182() {}
public void stub183() {}
public void stub184() {}
public void stub185() {}
public void stub186() {}
public void stub187() {}
public void stub188() {}
public void stub189() {}
public void stub190() {}
public void stub191() {}
public void stub192() {}
public void stub193() {}
public void stub194() {}
public void stub195() {}
public void stub196() {}
public void stub197() {}
public void stub198() {}
public void stub199() {}
public void stub200() {}
public void stub201() {}
public void stub202() {}
public void stub203() {}
public void stub204() {}
public void stub205() {}
public void stub206() {}
public void stub207() {}
public void stub208() {}
public void stub209() {}
public void stub210() {}
public void stub211() {}
public void stub212() {}
public void stub213() {}
public void stub214() {}
public void stub215() {}
public void stub216() {}
public void stub217() {}
public void stub218() {}
public void stub219() {}
public void stub220() {}
public void stub221() {}
public void stub222() {}
public void stub223() {}
public void stub224() {}
public void stub225() {}
public void stub226() {}
public void stub227() {}
public void stub228() {}
public void stub229() {}
public void stub230() {}
public void stub231() {}
public void stub232() {}
public void stub233() {}
public void stub234() {}
public void stub235() {}
public void stub236() {}
public void stub237() {}
public void stub238() {}
public void stub239() {}
public void stub240() {}
public void stub241() {}
public void stub242() {}
public void stub243() {}
public void stub244() {}
public void stub245() {}
public void stub246() {}
public void stub247() {}
public void stub248() {}
public void stub249() {}
public void stub250() {}
public void stub251() {}
public void stub252() {}
public void stub253() {}
public void stub254() {}
public void stub255() {}
public void stub256() {}
public void stub257() {}
public void stub258() {}
public void stub259() {}
public void stub260() {}
public void stub261() {}
public void stub262() {}
public void stub263() {}
public void stub264() {}
public void stub265() {}
public void stub266() {}
public void stub267() {}
public void stub268() {}
public void stub269() {}
public void stub270() {}
public void stub271() {}
public void stub272() {}
public void stub273() {}
public void stub274() {}
public void stub275() {}
public void stub276() {}
public void stub277() {}
public void stub278() {}
public void stub279() {}
public void stub280() {}
public void stub281() {}
public void stub282() {}
public void stub283() {}
public void stub284() {}
public void stub285() {}
public void stub286() {}
public void stub287() {}
public void stub288() {}
public void stub289() {}
public void stub290() {}
public void stub291() {}
public void stub292() {}
public void stub293() {}
public void stub294() {}
public void stub295() {}
public void stub296() {}
public void stub297() {}
public void stub298() {}
public void stub299() {}
public void stub300() {}
} }
...@@ -32,7 +32,7 @@ JAVA_TYPE_LONG = "long" ...@@ -32,7 +32,7 @@ JAVA_TYPE_LONG = "long"
TEMP_STUB_HOOK_METHOD = """ TEMP_STUB_HOOK_METHOD = """
public static %s %s(%s) throws Throwable { public static %s %s(%s) throws Throwable {
return %s hookBridge(%s, new %s() %s); return %s hookBridge(%s, %s %s);
} }
""" """
...@@ -54,8 +54,14 @@ TEMP_STUB_CALL_ORIGIN_CLASS = """ ...@@ -54,8 +54,14 @@ TEMP_STUB_CALL_ORIGIN_CLASS = """
} }
""" """
TEMP_STUB_INFO = """
public static boolean hasStubBackup = %s;
public static int[] stubSizes = {%s};
"""
STUB_SIZES = [10,20,30,20,10,20,20,5,5] STUB_SIZES = [10,20,30,30,30,30,30,20,10,10,5,5,3]
HAS_BACKUP = False;
def getMethodId(args, index): def getMethodId(args, index):
...@@ -105,7 +111,8 @@ def genHookMethod(is64Bit, args, index): ...@@ -105,7 +111,8 @@ def genHookMethod(is64Bit, args, index):
args_list_pre = ", " if args > 0 else "" args_list_pre = ", " if args > 0 else ""
args_list = genArgsList(is64Bit, False, args) args_list = genArgsList(is64Bit, False, args)
args_list_def = genArgsList(is64Bit, True, args) args_list_def = genArgsList(is64Bit, True, args)
method = TEMP_STUB_HOOK_METHOD % (java_type, getMethodHookName(index), args_list_def, cast, getMethodId(args, index), getCallOriginClassName(args, index), args_list_pre + args_list) call_origin_obj = ("new " + getCallOriginClassName(args, index) + "()") if HAS_BACKUP else "null"
method = TEMP_STUB_HOOK_METHOD % (java_type, getMethodHookName(index), args_list_def, cast, getMethodId(args, index), call_origin_obj, args_list_pre + args_list)
return method return method
...@@ -119,19 +126,28 @@ def genCallOriginClass(is64Bit, args, index): ...@@ -119,19 +126,28 @@ def genCallOriginClass(is64Bit, args, index):
method = TEMP_STUB_CALL_ORIGIN_CLASS % (getCallOriginClassName(args, index), getMethodBackupName(index), genArgsListForCallOriginMethod(is64Bit, args)) method = TEMP_STUB_CALL_ORIGIN_CLASS % (getCallOriginClassName(args, index), getMethodBackupName(index), genArgsListForCallOriginMethod(is64Bit, args))
return method return method
def genStubInfo():
hasStub = "true" if HAS_BACKUP else "false"
stubSizes = ""
for args in range(len(STUB_SIZES)):
if (args != 0):
stubSizes += ", "
stubSizes += str(STUB_SIZES[args])
return TEMP_STUB_INFO % (hasStub, stubSizes)
def gen32Stub(packageDir): def gen32Stub(packageDir):
class_content = "" class_content = genStubInfo()
class_name = STUB_FILE_NAME + "32" class_name = STUB_FILE_NAME + "32"
for args in range(len(STUB_SIZES)): for args in range(len(STUB_SIZES)):
for index in range(STUB_SIZES[args]): for index in range(STUB_SIZES[args]):
class_content += """\n\n\n\t//stub of arg size %d, index %d""" % (args, index) class_content += """\n\n\t//stub of arg size %d, index %d""" % (args, index)
class_content += genCallOriginClass(False, args, index)
class_content += "\n"
class_content += genHookMethod(False, args, index) class_content += genHookMethod(False, args, index)
class_content += "\n" if HAS_BACKUP:
class_content += genBackupMethod(False, args, index) class_content += "\n"
class_content += "\n" class_content += genCallOriginClass(False, args, index)
class_content += "\n"
class_content += genBackupMethod(False, args, index)
class_content += "\n"
class_str = TEMP_STUB_CLASS_WRAPPER % (32, class_content) class_str = TEMP_STUB_CLASS_WRAPPER % (32, class_content)
javaFile = open(os.path.join(packageDir, class_name + ".java"), "w") javaFile = open(os.path.join(packageDir, class_name + ".java"), "w")
javaFile.write(class_str) javaFile.write(class_str)
...@@ -139,17 +155,18 @@ def gen32Stub(packageDir): ...@@ -139,17 +155,18 @@ def gen32Stub(packageDir):
def gen64Stub(packageDir): def gen64Stub(packageDir):
class_content = "" class_content = genStubInfo()
class_name = STUB_FILE_NAME + "64" class_name = STUB_FILE_NAME + "64"
for args in range(len(STUB_SIZES)): for args in range(len(STUB_SIZES)):
for index in range(STUB_SIZES[args]): for index in range(STUB_SIZES[args]):
class_content += """\n\n\n\t//stub of arg size %d, index %d""" % (args, index) class_content += """\n\n\t//stub of arg size %d, index %d""" % (args, index)
class_content += genCallOriginClass(True, args, index)
class_content += "\n"
class_content += genHookMethod(True, args, index) class_content += genHookMethod(True, args, index)
class_content += "\n" if HAS_BACKUP:
class_content += genBackupMethod(True, args, index) class_content += "\n"
class_content += "\n" class_content += genCallOriginClass(True, args, index)
class_content += "\n"
class_content += genBackupMethod(True, args, index)
class_content += "\n"
class_str = TEMP_STUB_CLASS_WRAPPER % (64, class_content) class_str = TEMP_STUB_CLASS_WRAPPER % (64, class_content)
javaFile = open(os.path.join(packageDir, class_name + ".java"), "w") javaFile = open(os.path.join(packageDir, class_name + ".java"), "w")
javaFile.write(class_str) javaFile.write(class_str)
......
...@@ -5,6 +5,7 @@ import android.util.Log; ...@@ -5,6 +5,7 @@ import android.util.Log;
import com.swift.sandhook.SandHook; import com.swift.sandhook.SandHook;
import com.swift.sandhook.SandHookMethodResolver; import com.swift.sandhook.SandHookMethodResolver;
import com.swift.sandhook.utils.ParamWrapper; import com.swift.sandhook.utils.ParamWrapper;
import com.swift.sandhook.wrapper.BackupMethodStubs;
import com.swift.sandhook.xposedcompat.utils.DexLog; import com.swift.sandhook.xposedcompat.utils.DexLog;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
...@@ -16,19 +17,20 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -16,19 +17,20 @@ import java.util.concurrent.atomic.AtomicInteger;
import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import static de.robv.android.xposed.XposedBridge.sHookedMethodCallbacks; import static de.robv.android.xposed.XposedBridge.sHookedMethodCallbacks;
public class HookStubManager { public class HookStubManager {
public final static int MAX_STUB_ARGS = 8; public static int MAX_STUB_ARGS = 0;
public final static int[] stubSizes = new int[] { public static int[] stubSizes;
10,20,30,20,10,20,20,5,5
};
public final static AtomicInteger[] curUseStubIndexes = new AtomicInteger[MAX_STUB_ARGS + 1]; public static boolean hasStubBackup = false;
public static AtomicInteger[] curUseStubIndexes;
public static int ALL_STUB = 0; public static int ALL_STUB = 0;
...@@ -39,12 +41,20 @@ public class HookStubManager { ...@@ -39,12 +41,20 @@ public class HookStubManager {
= sHookedMethodCallbacks; = sHookedMethodCallbacks;
static { static {
for (int i = 0;i < MAX_STUB_ARGS + 1;i++) { Class stubClass = SandHook.is64Bit() ? MethodHookerStubs64.class : MethodHookerStubs32.class;
curUseStubIndexes[i] = new AtomicInteger(0); stubSizes = (int[]) XposedHelpers.getStaticObjectField(stubClass, "stubSizes");
ALL_STUB += stubSizes[i]; Boolean hasBackup = (Boolean) XposedHelpers.getStaticObjectField(stubClass, "hasStubBackup");
hasStubBackup = hasBackup == null ? false : hasBackup;
if (stubSizes != null && stubSizes.length > 0) {
MAX_STUB_ARGS = stubSizes.length - 1;
curUseStubIndexes = new AtomicInteger[MAX_STUB_ARGS + 1];
for (int i = 0; i < MAX_STUB_ARGS + 1; i++) {
curUseStubIndexes[i] = new AtomicInteger(0);
ALL_STUB += stubSizes[i];
}
originMethods = new Member[ALL_STUB];
hookMethodEntities = new HookMethodEntity[ALL_STUB];
} }
originMethods = new Member[ALL_STUB];
hookMethodEntities = new HookMethodEntity[ALL_STUB];
} }
...@@ -97,11 +107,11 @@ public class HookStubManager { ...@@ -97,11 +107,11 @@ public class HookStubManager {
int id = getMethodId(stubMethodInfo.args, stubMethodInfo.index); int id = getMethodId(stubMethodInfo.args, stubMethodInfo.index);
originMethods[id] = origin; originMethods[id] = origin;
hookMethodEntities[id] = entity; hookMethodEntities[id] = entity;
if (tryCompileAndResolveCallOriginMethod(entity.backup, stubMethodInfo.args, stubMethodInfo.index)) { if (hasStubBackup && !tryCompileAndResolveCallOriginMethod(entity.backup, stubMethodInfo.args, stubMethodInfo.index)) {
return entity;
} else {
DexLog.w("internal stub <" + entity.hook.getName() + "> call origin compile failure, skip use internal stub"); DexLog.w("internal stub <" + entity.hook.getName() + "> call origin compile failure, skip use internal stub");
return null; return null;
} else {
return entity;
} }
} }
} }
...@@ -153,13 +163,13 @@ public class HookStubManager { ...@@ -153,13 +163,13 @@ public class HookStubManager {
try { try {
if (is64Bit) { if (is64Bit) {
Method hook = MethodHookerStubs64.class.getDeclaredMethod(getHookMethodName(curUseStubIndex), pars); Method hook = MethodHookerStubs64.class.getDeclaredMethod(getHookMethodName(curUseStubIndex), pars);
Method backup = MethodHookerStubs64.class.getDeclaredMethod(getBackupMethodName(curUseStubIndex), pars); Method backup = hasStubBackup ? MethodHookerStubs64.class.getDeclaredMethod(getBackupMethodName(curUseStubIndex), pars) : BackupMethodStubs.getStubMethod();
if (hook == null || backup == null) if (hook == null || backup == null)
return null; return null;
return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup); return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup);
} else { } else {
Method hook = MethodHookerStubs32.class.getDeclaredMethod(getHookMethodName(curUseStubIndex), pars); Method hook = MethodHookerStubs32.class.getDeclaredMethod(getHookMethodName(curUseStubIndex), pars);
Method backup = MethodHookerStubs32.class.getDeclaredMethod(getBackupMethodName(curUseStubIndex), pars); Method backup = hasStubBackup ? MethodHookerStubs32.class.getDeclaredMethod(getBackupMethodName(curUseStubIndex), pars) : BackupMethodStubs.getStubMethod();
if (hook == null || backup == null) if (hook == null || backup == null)
return null; return null;
return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup); return new StubMethodsInfo(stubArgs, curUseStubIndex, hook, backup);
...@@ -219,26 +229,41 @@ public class HookStubManager { ...@@ -219,26 +229,41 @@ public class HookStubManager {
public static long hookBridge(int id, CallOriginCallBack callOrigin, long... stubArgs) throws Throwable { public static long hookBridge(int id, CallOriginCallBack callOrigin, long... stubArgs) throws Throwable {
if (XposedBridge.disableHooks)
return callOrigin.call(stubArgs);
Member originMethod = originMethods[id]; Member originMethod = originMethods[id];
HookMethodEntity entity = hookMethodEntities[id]; HookMethodEntity entity = hookMethodEntities[id];
Object thiz = null;
Object[] args = null;
if (hasArgs(stubArgs)) {
thiz = entity.getThis(stubArgs[0]);
args = entity.getArgs(stubArgs);
}
if (XposedBridge.disableHooks) {
if (hasStubBackup) {
return callOrigin.call(stubArgs);
} else {
return callOrigin(entity, originMethod, thiz, args);
}
}
DexLog.printMethodHookIn(originMethod); DexLog.printMethodHookIn(originMethod);
Object[] snapshot = hookCallbacks.get(originMethod).getSnapshot(); Object[] snapshot = hookCallbacks.get(originMethod).getSnapshot();
if (snapshot == null || snapshot.length == 0) if (snapshot == null || snapshot.length == 0) {
return callOrigin.call(stubArgs); if (hasStubBackup) {
return callOrigin.call(stubArgs);
} else {
return callOrigin(entity, originMethod, thiz, args);
}
}
XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam(); XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam();
param.method = originMethod; param.method = originMethod;
param.thisObject = thiz;
if (hasArgs(stubArgs)) { param.args = args;
param.thisObject = entity.getThis(stubArgs[0]);
param.args = entity.getArgs(stubArgs);
}
int beforeIdx = 0; int beforeIdx = 0;
do { do {
...@@ -261,9 +286,13 @@ public class HookStubManager { ...@@ -261,9 +286,13 @@ public class HookStubManager {
// call original method if not requested otherwise // call original method if not requested otherwise
if (!param.returnEarly) { if (!param.returnEarly) {
try { try {
//prepare new args if (hasStubBackup) {
long[] newArgs = entity.getArgsAddress(stubArgs, param.args); //prepare new args
param.setResult(entity.getResult(callOrigin.call(newArgs))); long[] newArgs = entity.getArgsAddress(stubArgs, param.args);
param.setResult(entity.getResult(callOrigin.call(newArgs)));
} else {
param.setResult(SandHook.callOriginMethod(originMethod, thiz, param.args));
}
} catch (Exception e) { } catch (Exception e) {
XposedBridge.log(e); XposedBridge.log(e);
param.setThrowable(e); param.setThrowable(e);
...@@ -293,12 +322,17 @@ public class HookStubManager { ...@@ -293,12 +322,17 @@ public class HookStubManager {
} }
} }
public static long callOrigin(HookMethodEntity entity, Member origin, Object thiz, Object[] args) throws Throwable {
Object res = SandHook.callOriginMethod(origin, thiz, args);
return entity.getResultAddress(res);
}
private static boolean hasArgs(long... args) { private static boolean hasArgs(long... args) {
return args != null && args.length > 0; return args != null && args.length > 0;
} }
public static boolean support() { public static boolean support() {
return SandHook.canGetObject() && SandHook.canGetObjectAddress(); return MAX_STUB_ARGS > 0 && SandHook.canGetObject() && SandHook.canGetObjectAddress();
} }
} }
...@@ -412,7 +412,7 @@ public class HookerDexMaker { ...@@ -412,7 +412,7 @@ public class HookerDexMaker {
code.sget(mMethodFieldId, localOrigin); code.sget(mMethodFieldId, localOrigin);
code.sget(mBackupMethodFieldId, localBackup); code.sget(mBackupMethodFieldId, localBackup);
MethodId methodId = TypeId.get(SandHook.class).getMethod(TypeId.get(Void.TYPE), "ensureMethodDeclaringClass", memberTypeId, methodTypeId); MethodId methodId = TypeId.get(SandHook.class).getMethod(TypeId.get(Void.TYPE), "ensureBackupMethod", memberTypeId, methodTypeId);
code.invokeStatic(methodId, null, localOrigin, localBackup); code.invokeStatic(methodId, null, localOrigin, localBackup);
......
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