Commit cfa2690d authored by swift_gan's avatar swift_gan

invoke backup to resolve static method

parent 8ffd5536
...@@ -10,15 +10,15 @@ ...@@ -10,15 +10,15 @@
namespace SandHook { namespace SandHook {
class CastDexCacheResolvedMethods : public ArrayMember<art::mirror::ArtMethod> { class CastDexCacheResolvedMethods : public ArrayMember<art::mirror::ArtMethod, void*> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override { Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod* p) override {
if (SDK_INT >= ANDROID_P) if (SDK_INT >= ANDROID_P)
return getParentSize() + 1; return getParentSize() + 1;
int offset = 0; int offset = 0;
Size addr = getAddressFromJava(jniEnv, "com/swift/sandhook/SandHookMethodResolver", "resolvedMethodsAddress"); Size addr = getAddressFromJava(jniEnv, "com/swift/sandhook/SandHookMethodResolver", "resolvedMethodsAddress");
if (addr != 0) { if (addr != 0) {
offset = findOffset(&p, getParentSize(), 2, addr); offset = findOffset(p, getParentSize(), 2, addr);
if (offset >= 0) { if (offset >= 0) {
return static_cast<Size>(offset); return static_cast<Size>(offset);
} }
...@@ -26,14 +26,11 @@ namespace SandHook { ...@@ -26,14 +26,11 @@ namespace SandHook {
return getParentSize() + 1; return getParentSize() + 1;
} }
Size calElementSize(JNIEnv *jniEnv, art::mirror::ArtMethod p) override {
return BYTE_POINT;
}
}; };
class CastEntryPointFormInterpreter : public IMember<art::mirror::ArtMethod, void*> { class CastEntryPointFormInterpreter : public IMember<art::mirror::ArtMethod, void*> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override { Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod* p) override {
if (SDK_INT >= ANDROID_L2 && SDK_INT <= ANDROID_M) if (SDK_INT >= ANDROID_L2 && SDK_INT <= ANDROID_M)
return getParentSize() - 3 * BYTE_POINT; return getParentSize() - 3 * BYTE_POINT;
else if (SDK_INT <= ANDROID_L) else if (SDK_INT <= ANDROID_L)
...@@ -45,7 +42,7 @@ namespace SandHook { ...@@ -45,7 +42,7 @@ namespace SandHook {
class CastEntryPointQuickCompiled : public IMember<art::mirror::ArtMethod, void*> { class CastEntryPointQuickCompiled : public IMember<art::mirror::ArtMethod, void*> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override { Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod* p) override {
if (SDK_INT >= ANDROID_L2) { if (SDK_INT >= ANDROID_L2) {
return getParentSize() - BYTE_POINT; return getParentSize() - BYTE_POINT;
} else { } else {
...@@ -56,7 +53,7 @@ namespace SandHook { ...@@ -56,7 +53,7 @@ namespace SandHook {
class CastEntryPointFromJni : public IMember<art::mirror::ArtMethod, void*> { class CastEntryPointFromJni : public IMember<art::mirror::ArtMethod, void*> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override { Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod* p) override {
if (SDK_INT >= ANDROID_L2 && SDK_INT <= ANDROID_N) { if (SDK_INT >= ANDROID_L2 && SDK_INT <= ANDROID_N) {
return getParentSize() - 2 * BYTE_POINT; return getParentSize() - 2 * BYTE_POINT;
} else { } else {
...@@ -68,12 +65,12 @@ namespace SandHook { ...@@ -68,12 +65,12 @@ namespace SandHook {
class CastAccessFlag : public IMember<art::mirror::ArtMethod, uint32_t> { class CastAccessFlag : public IMember<art::mirror::ArtMethod, uint32_t> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override { Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod* p) override {
uint32_t accessFlag = getIntFromJava(jniEnv, "com/swift/sandhook/SandHook", "testAccessFlag"); uint32_t accessFlag = getIntFromJava(jniEnv, "com/swift/sandhook/SandHook", "testAccessFlag");
if (accessFlag == 0) { if (accessFlag == 0) {
accessFlag = 524313; accessFlag = 524313;
} }
int offset = findOffset(&p, getParentSize(), 2, accessFlag); int offset = findOffset(p, getParentSize(), 2, accessFlag);
if (offset < 0) if (offset < 0)
return getParentSize() + 1; return getParentSize() + 1;
else else
...@@ -84,13 +81,13 @@ namespace SandHook { ...@@ -84,13 +81,13 @@ namespace SandHook {
class CastDexMethodIndex : public IMember<art::mirror::ArtMethod, uint32_t> { class CastDexMethodIndex : public IMember<art::mirror::ArtMethod, uint32_t> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override { Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod* p) override {
if (SDK_INT >= ANDROID_P) if (SDK_INT >= ANDROID_P)
return getParentSize() + 1; return getParentSize() + 1;
int offset = 0; int offset = 0;
jint index = getIntFromJava(jniEnv, "com/swift/sandhook/SandHookMethodResolver", "dexMethodIndex"); jint index = getIntFromJava(jniEnv, "com/swift/sandhook/SandHookMethodResolver", "dexMethodIndex");
if (index != 0) { if (index != 0) {
offset = findOffset(&p, getParentSize(), 2, static_cast<uint32_t>(index)); offset = findOffset(p, getParentSize(), 2, static_cast<uint32_t>(index));
if (offset >= 0) { if (offset >= 0) {
return static_cast<Size>(offset); return static_cast<Size>(offset);
} }
...@@ -107,7 +104,7 @@ namespace SandHook { ...@@ -107,7 +104,7 @@ namespace SandHook {
static Size size; static Size size;
static IMember<art::mirror::ArtMethod, void*>* entryPointQuickCompiled; static IMember<art::mirror::ArtMethod, void*>* entryPointQuickCompiled;
static IMember<art::mirror::ArtMethod, void*>* entryPointFormInterpreter; static IMember<art::mirror::ArtMethod, void*>* entryPointFormInterpreter;
static ArrayMember<art::mirror::ArtMethod>* dexCacheResolvedMethods; static ArrayMember<art::mirror::ArtMethod,void*>* dexCacheResolvedMethods;
static IMember<art::mirror::ArtMethod, uint32_t>* dexMethodIndex; static IMember<art::mirror::ArtMethod, uint32_t>* dexMethodIndex;
static IMember<art::mirror::ArtMethod, uint32_t>* accessFlag; static IMember<art::mirror::ArtMethod, uint32_t>* accessFlag;
static void* quickToInterpreterBridge; static void* quickToInterpreterBridge;
...@@ -121,8 +118,8 @@ namespace SandHook { ...@@ -121,8 +118,8 @@ namespace SandHook {
Size artMethod2 = (Size) env->GetStaticMethodID(sizeTestClass, "method2", "()V"); Size artMethod2 = (Size) env->GetStaticMethodID(sizeTestClass, "method2", "()V");
size = artMethod2 - artMethod1; size = artMethod2 - artMethod1;
art::mirror::ArtMethod m1 = *reinterpret_cast<art::mirror::ArtMethod *>(artMethod1); art::mirror::ArtMethod* m1 = reinterpret_cast<art::mirror::ArtMethod *>(artMethod1);
art::mirror::ArtMethod m2 = *reinterpret_cast<art::mirror::ArtMethod *>(artMethod2); art::mirror::ArtMethod* m2 = reinterpret_cast<art::mirror::ArtMethod *>(artMethod2);
//init Members //init Members
entryPointQuickCompiled = new CastEntryPointQuickCompiled(); entryPointQuickCompiled = new CastEntryPointQuickCompiled();
...@@ -142,7 +139,7 @@ namespace SandHook { ...@@ -142,7 +139,7 @@ namespace SandHook {
jclass neverCallTestClass = env->FindClass("com/swift/sandhook/ClassNeverCall"); jclass neverCallTestClass = env->FindClass("com/swift/sandhook/ClassNeverCall");
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);
} }
...@@ -155,7 +152,7 @@ namespace SandHook { ...@@ -155,7 +152,7 @@ namespace SandHook {
Size CastArtMethod::size = 0; Size CastArtMethod::size = 0;
IMember<art::mirror::ArtMethod, void*>* CastArtMethod::entryPointQuickCompiled = nullptr; IMember<art::mirror::ArtMethod, void*>* CastArtMethod::entryPointQuickCompiled = nullptr;
IMember<art::mirror::ArtMethod, void*>* CastArtMethod::entryPointFormInterpreter = nullptr; IMember<art::mirror::ArtMethod, void*>* CastArtMethod::entryPointFormInterpreter = nullptr;
ArrayMember<art::mirror::ArtMethod>* CastArtMethod::dexCacheResolvedMethods = nullptr; ArrayMember<art::mirror::ArtMethod, void*>* CastArtMethod::dexCacheResolvedMethods = nullptr;
IMember<art::mirror::ArtMethod, uint32_t>* CastArtMethod::dexMethodIndex = nullptr; IMember<art::mirror::ArtMethod, uint32_t>* CastArtMethod::dexMethodIndex = nullptr;
IMember<art::mirror::ArtMethod, uint32_t>* CastArtMethod::accessFlag = nullptr; IMember<art::mirror::ArtMethod, uint32_t>* CastArtMethod::accessFlag = nullptr;
void* CastArtMethod::quickToInterpreterBridge = nullptr; void* CastArtMethod::quickToInterpreterBridge = nullptr;
......
...@@ -43,7 +43,7 @@ namespace SandHook { ...@@ -43,7 +43,7 @@ namespace SandHook {
class IMember { class IMember {
public: public:
virtual void init(JNIEnv *jniEnv, PType p, Size size) { virtual void init(JNIEnv *jniEnv, PType* p, Size size) {
this->parentSize = size; this->parentSize = size;
offset = calOffset(jniEnv, p); offset = calOffset(jniEnv, p);
} }
...@@ -56,10 +56,10 @@ namespace SandHook { ...@@ -56,10 +56,10 @@ namespace SandHook {
return parentSize; return parentSize;
} }
virtual MType get(PType p) { virtual MType get(PType* p) {
if (offset > parentSize) if (offset > parentSize)
return NULL; return NULL;
return *reinterpret_cast<MType*>((Size)&p + getOffset()); return *reinterpret_cast<MType*>((Size)p + getOffset());
}; };
virtual void set(PType* p, MType t) { virtual void set(PType* p, MType t) {
...@@ -72,15 +72,15 @@ namespace SandHook { ...@@ -72,15 +72,15 @@ namespace SandHook {
Size offset = 0; Size offset = 0;
protected: protected:
Size parentSize = 0; Size parentSize = 0;
virtual Size calOffset(JNIEnv *jniEnv, PType p) = 0; virtual Size calOffset(JNIEnv *jniEnv, PType* p) = 0;
}; };
template<typename PType> template<typename PType, typename ElementType>
class ArrayMember : public IMember<PType, void*> { class ArrayMember : public IMember<PType, void*> {
public: public:
virtual void init(JNIEnv *jniEnv, PType p, Size parentSize) override { virtual void init(JNIEnv *jniEnv, PType* p, Size parentSize) override {
IMember<PType,void*>::init(jniEnv, p, parentSize); IMember<PType,void*>::init(jniEnv, p, parentSize);
elementSize = calElementSize(jniEnv, p); elementSize = calElementSize(jniEnv, p);
} }
...@@ -89,21 +89,24 @@ namespace SandHook { ...@@ -89,21 +89,24 @@ namespace SandHook {
return elementSize; return elementSize;
} }
virtual Size arrayStart(PType parent) { virtual Size arrayStart(PType* parent) {
return reinterpret_cast<Size>(IMember<PType,void*>::get(parent)); void* p = IMember<PType,void*>::get(parent);
return reinterpret_cast<Size>(p);
} }
using IMember<PType,void*>::getParentSize; using IMember<PType,void*>::getParentSize;
virtual void setElement(PType parent, int position, void* elementPoint) { virtual void setElement(PType* parent, int position, ElementType elementPoint) {
Size array = arrayStart(parent); Size array = arrayStart(parent);
memcpy(reinterpret_cast<void*>(array + position * getElementSize()), elementPoint, getElementSize()); memcpy(reinterpret_cast<void*>(array + position * getElementSize()), &elementPoint, getElementSize());
} }
private: private:
Size elementSize = 0; Size elementSize = 0;
protected: protected:
virtual Size calElementSize(JNIEnv *jniEnv, PType p) = 0; virtual Size calElementSize(JNIEnv *jniEnv, PType* p) {
return sizeof(ElementType);
};
}; };
} }
......
...@@ -21,13 +21,13 @@ Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk) ...@@ -21,13 +21,13 @@ Java_com_swift_sandhook_SandHook_initNative(JNIEnv *env, jclass type, jint sdk)
} }
void disableCompilable(art::mirror::ArtMethod* method) { void disableCompilable(art::mirror::ArtMethod* method) {
uint32_t accessFlag = SandHook::CastArtMethod::accessFlag->get(*method); uint32_t accessFlag = SandHook::CastArtMethod::accessFlag->get(method);
accessFlag |= 0x01000000; accessFlag |= 0x01000000;
SandHook::CastArtMethod::accessFlag->set(method, accessFlag); SandHook::CastArtMethod::accessFlag->set(method, accessFlag);
} }
void disableInterpreterForO(art::mirror::ArtMethod* method) { void disableInterpreterForO(art::mirror::ArtMethod* method) {
uint32_t accessFlag = SandHook::CastArtMethod::accessFlag->get(*method); uint32_t accessFlag = SandHook::CastArtMethod::accessFlag->get(method);
accessFlag |= 0x0100; accessFlag |= 0x0100;
SandHook::CastArtMethod::accessFlag->set(method, accessFlag); SandHook::CastArtMethod::accessFlag->set(method, accessFlag);
} }
...@@ -35,9 +35,9 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) { ...@@ -35,9 +35,9 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) {
void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *backupMethod) { void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *backupMethod) {
if (SDK_INT >= ANDROID_P) if (SDK_INT >= ANDROID_P)
return; return;
uint32_t index = SandHook::CastArtMethod::dexMethodIndex->get(*backupMethod); uint32_t index = SandHook::CastArtMethod::dexMethodIndex->get(backupMethod);
if (SDK_INT < ANDROID_O2) { if (SDK_INT < ANDROID_O2) {
SandHook::CastArtMethod::dexCacheResolvedMethods->setElement(*hookMethod, index, backupMethod); SandHook::CastArtMethod::dexCacheResolvedMethods->setElement(hookMethod, index, backupMethod);
} else { } else {
int cacheSize = 1024; int cacheSize = 1024;
Size slotIndex = index % cacheSize; Size slotIndex = index % cacheSize;
...@@ -72,6 +72,10 @@ bool doHookWithReplacement(art::mirror::ArtMethod *originMethod, ...@@ -72,6 +72,10 @@ bool doHookWithReplacement(art::mirror::ArtMethod *originMethod,
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());
void* entryPointFormInterpreter = SandHook::CastArtMethod::entryPointFormInterpreter->get(hookMethod);
if (entryPointFormInterpreter != NULL) {
SandHook::CastArtMethod::entryPointFormInterpreter->set(originMethod, entryPointFormInterpreter);
}
hookTrampoline->replacement->flushCache(reinterpret_cast<Size>(originMethod), SandHook::CastArtMethod::size); hookTrampoline->replacement->flushCache(reinterpret_cast<Size>(originMethod), SandHook::CastArtMethod::size);
} }
} }
...@@ -80,18 +84,13 @@ bool doHookWithInline(JNIEnv* env, ...@@ -80,18 +84,13 @@ 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) {
bool isInterpreter = SandHook::CastArtMethod::entryPointQuickCompiled->get(*hookMethod) == SandHook::CastArtMethod::quickToInterpreterBridge;
if (isInterpreter) { bool isInterpreter = SandHook::CastArtMethod::entryPointQuickCompiled->get(hookMethod) == SandHook::CastArtMethod::quickToInterpreterBridge;
Size threadId = getAddressFromJavaByCallMethod(env, "com/swift/sandhook/SandHook", "getThreadId");
compileMethod(hookMethod, reinterpret_cast<void*>(threadId));
}
isInterpreter = SandHook::CastArtMethod::entryPointQuickCompiled->get(*backupMethod) == SandHook::CastArtMethod::quickToInterpreterBridge;
//fix >= 8.1
if (isInterpreter) { if (isInterpreter) {
Size threadId = getAddressFromJavaByCallMethod(env, "com/swift/sandhook/SandHook", "getThreadId"); Size threadId = getAddressFromJavaByCallMethod(env, "com/swift/sandhook/SandHook", "getThreadId");
compileMethod(backupMethod, reinterpret_cast<void*>(threadId)); compileMethod(hookMethod, reinterpret_cast<void*>(threadId));
} }
SandHook::HookTrampoline* hookTrampoline = trampolineManager.installInlineTrampoline(originMethod, hookMethod, backupMethod); SandHook::HookTrampoline* hookTrampoline = trampolineManager.installInlineTrampoline(originMethod, hookMethod, backupMethod);
...@@ -124,12 +123,12 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or ...@@ -124,12 +123,12 @@ Java_com_swift_sandhook_SandHook_hookMethod(JNIEnv *env, jclass type, jobject or
// memcpy(backup, origin, SandHook::CastArtMethod::size); // 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) {
if (SDK_INT >= ANDROID_N) { if (SDK_INT >= ANDROID_N) {
Size threadId = getAddressFromJavaByCallMethod(env, "com/swift/sandhook/SandHook", "getThreadId"); Size threadId = getAddressFromJavaByCallMethod(env, "com/swift/sandhook/SandHook", "getThreadId");
if (compileMethod(origin, reinterpret_cast<void *>(threadId)) && SandHook::CastArtMethod::entryPointQuickCompiled->get(*origin) != SandHook::CastArtMethod::quickToInterpreterBridge) { if (compileMethod(origin, reinterpret_cast<void *>(threadId)) && SandHook::CastArtMethod::entryPointQuickCompiled->get(origin) != SandHook::CastArtMethod::quickToInterpreterBridge) {
doHookWithInline(env, origin, hook, backup); doHookWithInline(env, origin, hook, backup);
} else { } else {
doHookWithReplacement(origin, hook, backup); doHookWithReplacement(origin, hook, backup);
...@@ -151,5 +150,5 @@ Java_com_swift_sandhook_SandHook_ensureMethodCached(JNIEnv *env, jclass type, jo ...@@ -151,5 +150,5 @@ Java_com_swift_sandhook_SandHook_ensureMethodCached(JNIEnv *env, jclass type, jo
jobject backup) { jobject backup) {
art::mirror::ArtMethod* hookeMethod = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(hook)); 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)); art::mirror::ArtMethod* backupMethod = backup == NULL ? nullptr : reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(backup));
// ensureMethodCached(hookeMethod, backupMethod); ensureMethodCached(hookeMethod, backupMethod);
} }
\ No newline at end of file
...@@ -61,4 +61,16 @@ addr_hook_art_method: ...@@ -61,4 +61,16 @@ addr_hook_art_method:
.long 0 .long 0
FUNCTION_END(INLINE_HOOK_TRAMPOLINE) FUNCTION_END(INLINE_HOOK_TRAMPOLINE)
FUNCTION_START(CALL_ORIGIN_TRAMPOLINE)
ldr RegMethod, origin_art_method
ldr Reg0, addr_target
br Reg0
origin_art_method:
.long 0
.long 0
addr_origin:
.long 0
.long 0
FUNCTION_END(CALL_ORIGIN_TRAMPOLINE)
#endif #endif
...@@ -16,5 +16,6 @@ x: \ ...@@ -16,5 +16,6 @@ x: \
#define REPLACEMENT_HOOK_TRAMPOLINE replacement_hook_trampoline #define REPLACEMENT_HOOK_TRAMPOLINE replacement_hook_trampoline
#define INLINE_HOOK_TRAMPOLINE inline_hook_trampoline #define INLINE_HOOK_TRAMPOLINE inline_hook_trampoline
#define DIRECT_JUMP_TRAMPOLINE direct_jump_trampoline #define DIRECT_JUMP_TRAMPOLINE direct_jump_trampoline
#define CALL_ORIGIN_TRAMPOLINE call_origin_trampoline
#endif //SANDHOOK_BASE_H #endif //SANDHOOK_BASE_H
...@@ -45,6 +45,7 @@ public class MainActivity extends AppCompatActivity { ...@@ -45,6 +45,7 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
public void run() { public void run() {
methodBeHooked(savedInstanceState); methodBeHooked(savedInstanceState);
Log.w("gy", "dadadad");
} }
}, 3000); }, 3000);
......
...@@ -3,15 +3,14 @@ package com.swift.sandhook; ...@@ -3,15 +3,14 @@ package com.swift.sandhook;
import android.app.Application; import android.app.Application;
import com.swift.sandhook.wrapper.HookErrorException; import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.wrapper.HookWrapper; import com.swift.sandhook.wrapper.LogHooker;
public class MyApp extends Application { 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); SandHook.addHookClass(LogHooker.class, ActivityHooker.class);
} catch (HookErrorException e) { } catch (HookErrorException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -48,13 +48,20 @@ public class SandHook { ...@@ -48,13 +48,20 @@ 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);
if (backup != null) { if (backup != null) {
resolveBackupMethod(backup);
SandHookMethodResolver.resolveMethod(hook, backup); SandHookMethodResolver.resolveMethod(hook, backup);
} }
hookMethod(target, hook, backup); hookMethod(target, hook, backup);
} }
private static void resolveBackupMethod(Method method) {
try {
method.invoke(null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void initTestOffset() { private static void initTestOffset() {
// make test methods sure resolved! // make test methods sure resolved!
......
...@@ -12,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -12,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class HookWrapper { public class HookWrapper {
Map<Member,HookEntity> hookEntityMap = new ConcurrentHashMap<>(); static Map<Member,HookEntity> globalHookEntityMap = new ConcurrentHashMap<>();
public static void addHookClass(Class<?>... classes) throws HookErrorException { public static void addHookClass(Class<?>... classes) throws HookErrorException {
for (Class clazz:classes) { for (Class clazz:classes) {
...@@ -28,7 +28,7 @@ public class HookWrapper { ...@@ -28,7 +28,7 @@ public class HookWrapper {
for (HookEntity entity:hookEntityMap.values()) { for (HookEntity entity:hookEntityMap.values()) {
if (entity.target != null && entity.hook != null) { if (entity.target != null && entity.hook != null) {
SandHook.hook(entity.target, entity.hook, entity.backup); SandHook.hook(entity.target, entity.hook, entity.backup);
hookEntityMap.put(entity.target, entity); globalHookEntityMap.put(entity.target, entity);
} }
} }
} }
......
package com.swift.sandhook.wrapper;
import android.util.Log;
@HookClass(Log.class)
public class LogHooker {
@HookMethod("w")
@MethodParams({String.class, String.class})
public static int onCreate(String tag, String msg) {
Log.e("LogHooker", "hooked success " + tag);
return onCreateBackup(tag, msg);
}
@HookMethodBackup("w")
@MethodParams({String.class, String.class})
public static int onCreateBackup(String tag, String msg) {
return 0;
}
}
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