Commit 8ffd5536 authored by swift_gan's avatar swift_gan

done call origin method

parent beabc0fb
......@@ -27,7 +27,7 @@ namespace SandHook {
}
Size calElementSize(JNIEnv *jniEnv, art::mirror::ArtMethod p) override {
return getParentSize();
return BYTE_POINT;
}
};
......@@ -144,12 +144,6 @@ namespace SandHook {
art::mirror::ArtMethod* neverCall = reinterpret_cast<art::mirror::ArtMethod *>(env->GetMethodID(neverCallTestClass, "neverCall", "()V"));
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) {
......
......@@ -32,6 +32,30 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) {
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,
art::mirror::ArtMethod *hookMethod,
art::mirror::ArtMethod *backupMethod) {
......@@ -42,10 +66,13 @@ bool doHookWithReplacement(art::mirror::ArtMethod *originMethod,
if (SDK_INT >= ANDROID_O) {
disableInterpreterForO(originMethod);
}
if (backupMethod != nullptr) {
memcpy(backupMethod, originMethod, SandHook::CastArtMethod::size);
}
SandHook::HookTrampoline* hookTrampoline = trampolineManager.installReplacementTrampoline(originMethod, hookMethod, backupMethod);
if (hookTrampoline != nullptr) {
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,
art::mirror::ArtMethod *originMethod,
art::mirror::ArtMethod *hookMethod,
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;
if (isInterpreter) {
......@@ -64,8 +87,27 @@ bool doHookWithInline(JNIEnv* env,
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);
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"
......@@ -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* 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;
if (isInterpreter) {
......@@ -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:
.long 0
FUNCTION_END(REPLACEMENT_HOOK_TRAMPOLINE)
#define SIZE_JUMP #0x10
FUNCTION_START(DIRECT_JUMP_TRAMPOLINE)
ldr Reg0, addr_target
br Reg0
......@@ -32,27 +33,26 @@ FUNCTION_END(DIRECT_JUMP_TRAMPOLINE)
FUNCTION_START(INLINE_HOOK_TRAMPOLINE)
ldr Reg1, addr_origin_art_method
cmp RegMethod, Reg1
bne go_to_origin_code
bne origin_code
ldr RegMethod, addr_hook_art_method
ldr Reg1, offset_entry_code2
add Reg1, RegMethod, Reg1
ldr Reg1, [Reg1]
br Reg1
go_to_origin_code:
mov RegMethod, Reg1
b origin_code
addr_origin_art_method:
.long 0
.long 0
origin_code:
.long 0
.long 0
.long 0
.long 0
ldr Reg0, addr_origin_art_method
ldr Reg1, offset_entry_code2
add Reg1, RegMethod, Reg1
add Reg1, Reg0, Reg1
ldr Reg1, [Reg1]
add Reg1, Reg1, SIZE_JUMP
br Reg1
addr_origin_art_method:
.long 0
.long 0
offset_entry_code2:
.long 0
.long 0
......
......@@ -68,6 +68,10 @@ namespace SandHook {
codeCopy(originCode, OFFSET_INLINE_ORIGIN_CODE, SIZE_DIRECT_JUMP_TRAMPOLINE);
}
Code getCallOriginCode() {
return reinterpret_cast<Code>((Size)getCode() + OFFSET_INLINE_ORIGIN_CODE);
}
protected:
Size codeLength() override {
return SIZE_INLINE_HOOK_TRAMPOLINE;
......
......@@ -62,8 +62,8 @@
#define OFFSET_JUMP_ADDR_TARGET 4 * 2
#define SIZE_INLINE_HOOK_TRAMPOLINE 4 * 24
#define OFFSET_INLINE_ADDR_ORIGIN_METHOD 4 * 10
#define OFFSET_INLINE_ORIGIN_CODE 4 * 12
#define OFFSET_INLINE_ORIGIN_CODE 4 * 8
#define OFFSET_INLINE_ADDR_ORIGIN_METHOD 4 * 18
#define OFFSET_INLINE_OFFSET_ENTRY_CODE 4 * 20
#define OFFSET_INLINE_ADDR_HOOK_METHOD 4 * 22
#else
......
......@@ -74,7 +74,7 @@ namespace SandHook {
HookTrampoline* hookTrampoline = new HookTrampoline();
InlineHookTrampoline* inlineHookTrampoline = nullptr;
DirectJumpTrampoline* directJumpTrampoline = nullptr;
ReplacementHookTrampoline* callOriginTrampoline = nullptr;
DirectJumpTrampoline* callOriginTrampoline = nullptr;
Code inlineHookTrampolineSpace;
Code callOriginTrampolineSpace;
Code originEntry;
......@@ -105,14 +105,13 @@ namespace SandHook {
//备份原始方法
if (backupMethod != nullptr) {
callOriginTrampoline = new ReplacementHookTrampoline();
callOriginTrampoline = new DirectJumpTrampoline();
callOriginTrampoline->init();
callOriginTrampolineSpace = allocExecuteSpace(callOriginTrampoline->getCodeLen());
if (callOriginTrampolineSpace == 0)
goto label_error;
callOriginTrampoline->setExecuteSpace(callOriginTrampolineSpace);
callOriginTrampoline->setHookMethod(reinterpret_cast<Code>(originMethod));
callOriginTrampoline->setEntryCodeOffset(quickCompileOffset);
callOriginTrampoline->setJumpTarget(inlineHookTrampoline->getCallOriginCode());
hookTrampoline->callOrigin = callOriginTrampoline;
}
......
......@@ -16,6 +16,7 @@ public class ActivityHooker {
@MethodParams(Bundle.class)
public static void onCreate(Activity thiz, Bundle bundle) {
Log.e("ActivityHooker", "hooked success " + thiz);
onCreateBackup(thiz, bundle);
}
@HookMethodBackup("onCreate")
......
......@@ -2,4 +2,5 @@ package com.swift.sandhook;
public class ClassNeverCall {
private void neverCall() {}
private static void neverCallStatic() {}
}
......@@ -9,6 +9,7 @@ public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
ActivityHooker.onCreate(null, null);
try {
HookWrapper.addHookClass(ActivityHooker.class);
} catch (HookErrorException e) {
......
......@@ -49,6 +49,9 @@ public class SandHook {
public static void hook(@NonNull Member target, @NonNull Method hook, @Nullable Method backup) {
hook.setAccessible(true);
if (backup != null) {
SandHookMethodResolver.resolveMethod(hook, backup);
}
hookMethod(target, hook, backup);
}
......@@ -135,4 +138,6 @@ public class SandHook {
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 {
}
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