Commit 8ffd5536 authored by swift_gan's avatar swift_gan

done call origin method

parent beabc0fb
...@@ -27,7 +27,7 @@ namespace SandHook { ...@@ -27,7 +27,7 @@ namespace SandHook {
} }
Size calElementSize(JNIEnv *jniEnv, art::mirror::ArtMethod p) override { Size calElementSize(JNIEnv *jniEnv, art::mirror::ArtMethod p) override {
return getParentSize(); return BYTE_POINT;
} }
}; };
...@@ -144,12 +144,6 @@ namespace SandHook { ...@@ -144,12 +144,6 @@ namespace SandHook {
art::mirror::ArtMethod* neverCall = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID(neverCallTestClass, "neverCall", "()V")); art::mirror::ArtMethod* neverCall = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID(neverCallTestClass, "neverCall", "()V"));
quickToInterpreterBridge = entryPointQuickCompiled->get(*neverCall); quickToInterpreterBridge = entryPointQuickCompiled->get(*neverCall);
// //test
// art::mirror::ArtMethod** mArray = reinterpret_cast<art::mirror::ArtMethod**>(m1.dex_cache_resolved_methods_);
//
// art::mirror::ArtMethod m1B = *mArray[m1.dex_method_index_];
// art::mirror::ArtMethod m1C = *mArray[m2.dex_method_index_];
} }
static void copy(art::mirror::ArtMethod* from, art::mirror::ArtMethod* to) { static void copy(art::mirror::ArtMethod* from, art::mirror::ArtMethod* to) {
......
...@@ -32,6 +32,30 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) { ...@@ -32,6 +32,30 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) {
SandHook::CastArtMethod::accessFlag->set(method, accessFlag); SandHook::CastArtMethod::accessFlag->set(method, accessFlag);
} }
void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *backupMethod) {
if (SDK_INT >= ANDROID_P)
return;
uint32_t index = SandHook::CastArtMethod::dexMethodIndex->get(*backupMethod);
if (SDK_INT < ANDROID_O2) {
SandHook::CastArtMethod::dexCacheResolvedMethods->setElement(*hookMethod, index, backupMethod);
} else {
int cacheSize = 1024;
Size slotIndex = index % cacheSize;
void *newCachedMethodsArray = calloc(cacheSize, BYTE_POINT * 2);
unsigned int one = 1;
memcpy(newCachedMethodsArray + BYTE_POINT, &one, 4);
memcpy(newCachedMethodsArray + BYTE_POINT * 2 * slotIndex,
(&backupMethod),
BYTE_POINT
);
memcpy(newCachedMethodsArray + BYTE_POINT * 2 * slotIndex + BYTE_POINT,
&index,
4
);
SandHook::CastArtMethod::dexCacheResolvedMethods->set(hookMethod, &newCachedMethodsArray);
}
}
bool doHookWithReplacement(art::mirror::ArtMethod *originMethod, bool doHookWithReplacement(art::mirror::ArtMethod *originMethod,
art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *hookMethod,
art::mirror::ArtMethod *backupMethod) { art::mirror::ArtMethod *backupMethod) {
...@@ -42,10 +66,13 @@ bool doHookWithReplacement(art::mirror::ArtMethod *originMethod, ...@@ -42,10 +66,13 @@ bool doHookWithReplacement(art::mirror::ArtMethod *originMethod,
if (SDK_INT >= ANDROID_O) { if (SDK_INT >= ANDROID_O) {
disableInterpreterForO(originMethod); disableInterpreterForO(originMethod);
} }
if (backupMethod != nullptr) {
memcpy(backupMethod, originMethod, SandHook::CastArtMethod::size);
}
SandHook::HookTrampoline* hookTrampoline = trampolineManager.installReplacementTrampoline(originMethod, hookMethod, backupMethod); SandHook::HookTrampoline* hookTrampoline = trampolineManager.installReplacementTrampoline(originMethod, hookMethod, backupMethod);
if (hookTrampoline != nullptr) { if (hookTrampoline != nullptr) {
SandHook::CastArtMethod::entryPointQuickCompiled->set(originMethod, hookTrampoline->replacement->getCode()); SandHook::CastArtMethod::entryPointQuickCompiled->set(originMethod, hookTrampoline->replacement->getCode());
hookTrampoline->replacement->flushCache(reinterpret_cast<Size>(originMethod), 100); hookTrampoline->replacement->flushCache(reinterpret_cast<Size>(originMethod), SandHook::CastArtMethod::size);
} }
} }
...@@ -53,10 +80,6 @@ bool doHookWithInline(JNIEnv* env, ...@@ -53,10 +80,6 @@ bool doHookWithInline(JNIEnv* env,
art::mirror::ArtMethod *originMethod, art::mirror::ArtMethod *originMethod,
art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *hookMethod,
art::mirror::ArtMethod *backupMethod) { art::mirror::ArtMethod *backupMethod) {
// uint32_t accessFlag = SandHook::CastArtMethod::accessFlag->get(*originMethod);
// SandHook::CastArtMethod::accessFlag->set(hookMethod, accessFlag);
bool isInterpreter = SandHook::CastArtMethod::entryPointQuickCompiled->get(*hookMethod) == SandHook::CastArtMethod::quickToInterpreterBridge; bool isInterpreter = SandHook::CastArtMethod::entryPointQuickCompiled->get(*hookMethod) == SandHook::CastArtMethod::quickToInterpreterBridge;
if (isInterpreter) { if (isInterpreter) {
...@@ -64,8 +87,27 @@ bool doHookWithInline(JNIEnv* env, ...@@ -64,8 +87,27 @@ bool doHookWithInline(JNIEnv* env,
compileMethod(hookMethod, reinterpret_cast<void*>(threadId)); compileMethod(hookMethod, reinterpret_cast<void*>(threadId));
} }
isInterpreter = SandHook::CastArtMethod::entryPointQuickCompiled->get(*backupMethod) == SandHook::CastArtMethod::quickToInterpreterBridge;
if (isInterpreter) {
Size threadId = getAddressFromJavaByCallMethod(env, "com/swift/sandhook/SandHook", "getThreadId");
compileMethod(backupMethod, reinterpret_cast<void*>(threadId));
}
SandHook::HookTrampoline* hookTrampoline = trampolineManager.installInlineTrampoline(originMethod, hookMethod, backupMethod); SandHook::HookTrampoline* hookTrampoline = trampolineManager.installInlineTrampoline(originMethod, hookMethod, backupMethod);
hookTrampoline->inlineSecondory->flushCache(reinterpret_cast<Size>(hookMethod), 100); hookTrampoline->inlineSecondory->flushCache(reinterpret_cast<Size>(hookMethod), SandHook::CastArtMethod::size);
if (hookTrampoline->callOrigin != nullptr) {
//backup
memcpy(backupMethod, originMethod, SandHook::CastArtMethod::size);
SandHook::CastArtMethod::entryPointQuickCompiled->set(backupMethod, hookTrampoline->callOrigin->getCode());
if (SDK_INT >= ANDROID_N) {
disableCompilable(backupMethod);
}
if (SDK_INT >= ANDROID_O) {
disableInterpreterForO(backupMethod);
}
hookTrampoline->callOrigin->flushCache(reinterpret_cast<Size>(backupMethod), SandHook::CastArtMethod::size);
}
} }
extern "C" extern "C"
...@@ -78,6 +120,10 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or ...@@ -78,6 +120,10 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or
art::mirror::ArtMethod* hook = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(hookMethod)); art::mirror::ArtMethod* hook = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(hookMethod));
art::mirror::ArtMethod* backup = backupMethod == NULL ? nullptr : reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(backupMethod)); art::mirror::ArtMethod* backup = backupMethod == NULL ? nullptr : reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(backupMethod));
// if (backup != nullptr) {
// memcpy(backup, origin, SandHook::CastArtMethod::size);
// }
bool isInterpreter = SandHook::CastArtMethod::entryPointQuickCompiled->get(*origin) == SandHook::CastArtMethod::quickToInterpreterBridge; bool isInterpreter = SandHook::CastArtMethod::entryPointQuickCompiled->get(*origin) == SandHook::CastArtMethod::quickToInterpreterBridge;
if (isInterpreter) { if (isInterpreter) {
...@@ -99,3 +145,11 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or ...@@ -99,3 +145,11 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or
} }
extern "C"
JNIEXPORT void JNICALL
Java_com_swift_sandhook_SandHook_ensureMethodCached(JNIEnv *env, jclass type, jobject hook,
jobject backup) {
art::mirror::ArtMethod* hookeMethod = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(hook));
art::mirror::ArtMethod* backupMethod = backup == NULL ? nullptr : reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(backup));
// ensureMethodCached(hookeMethod, backupMethod);
}
\ No newline at end of file
...@@ -21,6 +21,7 @@ offset_entry_code: ...@@ -21,6 +21,7 @@ offset_entry_code:
.long 0 .long 0
FUNCTION_END(REPLACEMENT_HOOK_TRAMPOLINE) FUNCTION_END(REPLACEMENT_HOOK_TRAMPOLINE)
#define SIZE_JUMP #0x10
FUNCTION_START(DIRECT_JUMP_TRAMPOLINE) FUNCTION_START(DIRECT_JUMP_TRAMPOLINE)
ldr Reg0, addr_target ldr Reg0, addr_target
br Reg0 br Reg0
...@@ -32,27 +33,26 @@ FUNCTION_END(DIRECT_JUMP_TRAMPOLINE) ...@@ -32,27 +33,26 @@ FUNCTION_END(DIRECT_JUMP_TRAMPOLINE)
FUNCTION_START(INLINE_HOOK_TRAMPOLINE) FUNCTION_START(INLINE_HOOK_TRAMPOLINE)
ldr Reg1, addr_origin_art_method ldr Reg1, addr_origin_art_method
cmp RegMethod, Reg1 cmp RegMethod, Reg1
bne go_to_origin_code bne origin_code
ldr RegMethod, addr_hook_art_method ldr RegMethod, addr_hook_art_method
ldr Reg1, offset_entry_code2 ldr Reg1, offset_entry_code2
add Reg1, RegMethod, Reg1 add Reg1, RegMethod, Reg1
ldr Reg1, [Reg1] ldr Reg1, [Reg1]
br Reg1 br Reg1
go_to_origin_code:
mov RegMethod, Reg1
b origin_code
addr_origin_art_method:
.long 0
.long 0
origin_code: origin_code:
.long 0 .long 0
.long 0 .long 0
.long 0 .long 0
.long 0 .long 0
ldr Reg0, addr_origin_art_method
ldr Reg1, offset_entry_code2 ldr Reg1, offset_entry_code2
add Reg1, RegMethod, Reg1 add Reg1, Reg0, Reg1
ldr Reg1, [Reg1] ldr Reg1, [Reg1]
add Reg1, Reg1, SIZE_JUMP
br Reg1 br Reg1
addr_origin_art_method:
.long 0
.long 0
offset_entry_code2: offset_entry_code2:
.long 0 .long 0
.long 0 .long 0
......
...@@ -68,6 +68,10 @@ namespace SandHook { ...@@ -68,6 +68,10 @@ namespace SandHook {
codeCopy(originCode, OFFSET_INLINE_ORIGIN_CODE, SIZE_DIRECT_JUMP_TRAMPOLINE); codeCopy(originCode, OFFSET_INLINE_ORIGIN_CODE, SIZE_DIRECT_JUMP_TRAMPOLINE);
} }
Code getCallOriginCode() {
return reinterpret_cast<Code>((Size)getCode() + OFFSET_INLINE_ORIGIN_CODE);
}
protected: protected:
Size codeLength() override { Size codeLength() override {
return SIZE_INLINE_HOOK_TRAMPOLINE; return SIZE_INLINE_HOOK_TRAMPOLINE;
......
...@@ -62,8 +62,8 @@ ...@@ -62,8 +62,8 @@
#define OFFSET_JUMP_ADDR_TARGET 4 * 2 #define OFFSET_JUMP_ADDR_TARGET 4 * 2
#define SIZE_INLINE_HOOK_TRAMPOLINE 4 * 24 #define SIZE_INLINE_HOOK_TRAMPOLINE 4 * 24
#define OFFSET_INLINE_ADDR_ORIGIN_METHOD 4 * 10 #define OFFSET_INLINE_ORIGIN_CODE 4 * 8
#define OFFSET_INLINE_ORIGIN_CODE 4 * 12 #define OFFSET_INLINE_ADDR_ORIGIN_METHOD 4 * 18
#define OFFSET_INLINE_OFFSET_ENTRY_CODE 4 * 20 #define OFFSET_INLINE_OFFSET_ENTRY_CODE 4 * 20
#define OFFSET_INLINE_ADDR_HOOK_METHOD 4 * 22 #define OFFSET_INLINE_ADDR_HOOK_METHOD 4 * 22
#else #else
......
...@@ -74,7 +74,7 @@ namespace SandHook { ...@@ -74,7 +74,7 @@ namespace SandHook {
HookTrampoline* hookTrampoline = new HookTrampoline(); HookTrampoline* hookTrampoline = new HookTrampoline();
InlineHookTrampoline* inlineHookTrampoline = nullptr; InlineHookTrampoline* inlineHookTrampoline = nullptr;
DirectJumpTrampoline* directJumpTrampoline = nullptr; DirectJumpTrampoline* directJumpTrampoline = nullptr;
ReplacementHookTrampoline* callOriginTrampoline = nullptr; DirectJumpTrampoline* callOriginTrampoline = nullptr;
Code inlineHookTrampolineSpace; Code inlineHookTrampolineSpace;
Code callOriginTrampolineSpace; Code callOriginTrampolineSpace;
Code originEntry; Code originEntry;
...@@ -105,14 +105,13 @@ namespace SandHook { ...@@ -105,14 +105,13 @@ namespace SandHook {
//备份原始方法 //备份原始方法
if (backupMethod != nullptr) { if (backupMethod != nullptr) {
callOriginTrampoline = new ReplacementHookTrampoline(); callOriginTrampoline = new DirectJumpTrampoline();
callOriginTrampoline->init(); callOriginTrampoline->init();
callOriginTrampolineSpace = allocExecuteSpace(callOriginTrampoline->getCodeLen()); callOriginTrampolineSpace = allocExecuteSpace(callOriginTrampoline->getCodeLen());
if (callOriginTrampolineSpace == 0) if (callOriginTrampolineSpace == 0)
goto label_error; goto label_error;
callOriginTrampoline->setExecuteSpace(callOriginTrampolineSpace); callOriginTrampoline->setExecuteSpace(callOriginTrampolineSpace);
callOriginTrampoline->setHookMethod(reinterpret_cast<Code>(originMethod)); callOriginTrampoline->setJumpTarget(inlineHookTrampoline->getCallOriginCode());
callOriginTrampoline->setEntryCodeOffset(quickCompileOffset);
hookTrampoline->callOrigin = callOriginTrampoline; hookTrampoline->callOrigin = callOriginTrampoline;
} }
......
...@@ -16,6 +16,7 @@ public class ActivityHooker { ...@@ -16,6 +16,7 @@ public class ActivityHooker {
@MethodParams(Bundle.class) @MethodParams(Bundle.class)
public static void onCreate(Activity thiz, Bundle bundle) { public static void onCreate(Activity thiz, Bundle bundle) {
Log.e("ActivityHooker", "hooked success " + thiz); Log.e("ActivityHooker", "hooked success " + thiz);
onCreateBackup(thiz, bundle);
} }
@HookMethodBackup("onCreate") @HookMethodBackup("onCreate")
......
...@@ -2,4 +2,5 @@ package com.swift.sandhook; ...@@ -2,4 +2,5 @@ package com.swift.sandhook;
public class ClassNeverCall { public class ClassNeverCall {
private void neverCall() {} private void neverCall() {}
private static void neverCallStatic() {}
} }
...@@ -9,6 +9,7 @@ public class MyApp extends Application { ...@@ -9,6 +9,7 @@ public class MyApp extends Application {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
ActivityHooker.onCreate(null, null);
try { try {
HookWrapper.addHookClass(ActivityHooker.class); HookWrapper.addHookClass(ActivityHooker.class);
} catch (HookErrorException e) { } catch (HookErrorException e) {
......
...@@ -49,6 +49,9 @@ public class SandHook { ...@@ -49,6 +49,9 @@ public class SandHook {
public static void hook(@NonNull Member target, @NonNull Method hook, @Nullable Method backup) { public static void hook(@NonNull Member target, @NonNull Method hook, @Nullable Method backup) {
hook.setAccessible(true); hook.setAccessible(true);
if (backup != null) {
SandHookMethodResolver.resolveMethod(hook, backup);
}
hookMethod(target, hook, backup); hookMethod(target, hook, backup);
} }
...@@ -135,4 +138,6 @@ public class SandHook { ...@@ -135,4 +138,6 @@ public class SandHook {
private static native boolean hookMethod(Member originMethod, Method hookMethod, Method backupMethod); private static native boolean hookMethod(Member originMethod, Method hookMethod, Method backupMethod);
public static native void ensureMethodCached(Method hook, Method backup);
} }
...@@ -107,7 +107,7 @@ public class SandHookMethodResolver { ...@@ -107,7 +107,7 @@ public class SandHookMethodResolver {
} }
private static void resolveInNative(Method hook, Method backup) { private static void resolveInNative(Method hook, Method backup) {
// HookMain.ensureMethodCached(hook, backup); SandHook.ensureMethodCached(hook, backup);
} }
} }
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