Commit bc670453 authored by swift_gan's avatar swift_gan

add hook blacklist & reset declare method

parent d0f5ffd7
...@@ -109,7 +109,7 @@ void* ArtMethod::getInterpreterCodeEntry() { ...@@ -109,7 +109,7 @@ void* ArtMethod::getInterpreterCodeEntry() {
return CastArtMethod::entryPointFormInterpreter->get(this); return CastArtMethod::entryPointFormInterpreter->get(this);
} }
void* ArtMethod::getDeclaringClassPtr() { GCRoot ArtMethod::getDeclaringClass() {
return CastArtMethod::declaringClass->get(this); return CastArtMethod::declaringClass->get(this);
} }
...@@ -132,7 +132,7 @@ void ArtMethod::setDexCacheResolveItem(uint32_t index, void* item) { ...@@ -132,7 +132,7 @@ void ArtMethod::setDexCacheResolveItem(uint32_t index, void* item) {
CastArtMethod::dexCacheResolvedMethods->setElement(this, index, item); CastArtMethod::dexCacheResolvedMethods->setElement(this, index, item);
} }
void ArtMethod::setDeclaringClassPtr(void *classPtr) { void ArtMethod::setDeclaringClass(GCRoot classPtr) {
CastArtMethod::declaringClass->set(this, classPtr); CastArtMethod::declaringClass->set(this, classPtr);
} }
......
...@@ -128,9 +128,11 @@ namespace SandHook { ...@@ -128,9 +128,11 @@ namespace SandHook {
} }
}; };
class CastShadowClass : public IMember<art::mirror::ArtMethod, void*> { class CastShadowClass : public IMember<art::mirror::ArtMethod, GCRoot> {
protected: protected:
Size calOffset(JNIEnv *jniEnv, mirror::ArtMethod *p) override { Size calOffset(JNIEnv *jniEnv, mirror::ArtMethod *p) override {
if (SDK_INT < ANDROID_N)
return getParentSize() + 1;
return 0; return 0;
} }
}; };
...@@ -237,7 +239,7 @@ namespace SandHook { ...@@ -237,7 +239,7 @@ namespace SandHook {
ArrayMember<art::mirror::ArtMethod, void *> *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;
IMember<art::mirror::ArtMethod, void*> *CastArtMethod::declaringClass = nullptr; IMember<art::mirror::ArtMethod, GCRoot> *CastArtMethod::declaringClass = nullptr;
void *CastArtMethod::quickToInterpreterBridge = nullptr; void *CastArtMethod::quickToInterpreterBridge = nullptr;
void *CastArtMethod::genericJniStub = nullptr; void *CastArtMethod::genericJniStub = nullptr;
void *CastArtMethod::staticResolveStub = nullptr; void *CastArtMethod::staticResolveStub = nullptr;
......
...@@ -16,19 +16,15 @@ ...@@ -16,19 +16,15 @@
* limitations under the License. * limitations under the License.
*/ */
/**
* art_6_0.h
*
* @author : sanping.li@alipay.com
*
*/
#ifndef ART_H #ifndef ART_H
#define ART_H #define ART_H
#include <jni.h> #include <jni.h>
#include "arch.h" #include "arch.h"
//7.0 - 10.0
#define GCRoot uint32_t
namespace art { namespace art {
namespace mirror { namespace mirror {
class Object { class Object {
...@@ -64,13 +60,13 @@ public: ...@@ -64,13 +60,13 @@ public:
void setInterpreterCodeEntry(void* entry); void setInterpreterCodeEntry(void* entry);
void setDexCacheResolveList(void* list); void setDexCacheResolveList(void* list);
void setDexCacheResolveItem(uint32_t index, void* item); void setDexCacheResolveItem(uint32_t index, void* item);
void setDeclaringClassPtr(void* classPtr); void setDeclaringClass(GCRoot classPtr);
void* getQuickCodeEntry(); void* getQuickCodeEntry();
void* getInterpreterCodeEntry(); void* getInterpreterCodeEntry();
uint32_t getAccessFlags(); uint32_t getAccessFlags();
uint32_t getDexMethodIndex(); uint32_t getDexMethodIndex();
void* getDeclaringClassPtr(); GCRoot getDeclaringClass();
bool compile(JNIEnv* env); bool compile(JNIEnv* env);
bool deCompile(); bool deCompile();
......
...@@ -18,7 +18,7 @@ namespace SandHook { ...@@ -18,7 +18,7 @@ namespace SandHook {
static ArrayMember<art::mirror::ArtMethod,void*>* 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 IMember<art::mirror::ArtMethod, void*>* declaringClass; static IMember<art::mirror::ArtMethod, GCRoot>* declaringClass;
static void* quickToInterpreterBridge; static void* quickToInterpreterBridge;
static void* genericJniStub; static void* genericJniStub;
static void* staticResolveStub; static void* staticResolveStub;
......
...@@ -45,6 +45,18 @@ void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMeth ...@@ -45,6 +45,18 @@ void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMeth
} }
} }
void ensureDeclareClass(JNIEnv *env, jclass type, jobject originMethod,
jobject backupMethod) {
if (originMethod == NULL || backupMethod == NULL)
return;
art::mirror::ArtMethod* origin = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(originMethod));
art::mirror::ArtMethod* backup = reinterpret_cast<art::mirror::ArtMethod *>(env->FromReflectedMethod(backupMethod));
if (origin->getDeclaringClass() != backup->getDeclaringClass()) {
LOGW("declaring class has been moved!");
backup->setDeclaringClass(origin->getDeclaringClass());
}
}
bool doHookWithReplacement(JNIEnv* env, bool doHookWithReplacement(JNIEnv* env,
art::mirror::ArtMethod *originMethod, art::mirror::ArtMethod *originMethod,
art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *hookMethod,
...@@ -354,6 +366,11 @@ static JNINativeMethod jniSandHook[] = { ...@@ -354,6 +366,11 @@ static JNINativeMethod jniSandHook[] = {
"(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V", "(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V",
(void *) Java_com_swift_sandhook_SandHook_ensureMethodCached (void *) Java_com_swift_sandhook_SandHook_ensureMethodCached
}, },
{
"ensureDeclareClass",
"(Ljava/lang/reflect/Member;Ljava/lang/reflect/Method;)V",
(void *) ensureDeclareClass
},
{ {
"compileMethod", "compileMethod",
"(Ljava/lang/reflect/Member;)Z", "(Ljava/lang/reflect/Member;)Z",
......
...@@ -3,6 +3,7 @@ package com.swift.sandhook; ...@@ -3,6 +3,7 @@ package com.swift.sandhook;
import android.os.Build; import android.os.Build;
import com.swift.sandhook.annotation.HookMode; import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.blacklist.HookBlackList;
import com.swift.sandhook.utils.ReflectionUtils; import com.swift.sandhook.utils.ReflectionUtils;
import com.swift.sandhook.utils.Unsafe; import com.swift.sandhook.utils.Unsafe;
import com.swift.sandhook.wrapper.HookErrorException; import com.swift.sandhook.wrapper.HookErrorException;
...@@ -82,7 +83,10 @@ public class SandHook { ...@@ -82,7 +83,10 @@ public class SandHook {
throw new HookErrorException("null input"); throw new HookErrorException("null input");
if (globalHookEntityMap.containsKey(entity.target)) if (globalHookEntityMap.containsKey(entity.target))
throw new HookErrorException("method <" + entity.target.getName() + "> has been hooked!"); throw new HookErrorException("method <" + entity.target.toString() + "> has been hooked!");
if (HookBlackList.canNotHook(target))
throw new HookErrorException("method <" + entity.target.toString() + "> can not hook, because of in blacklist!");
resolveStaticMethod(target); resolveStaticMethod(target);
resolveStaticMethod(backup); resolveStaticMethod(backup);
...@@ -145,7 +149,12 @@ public class SandHook { ...@@ -145,7 +149,12 @@ 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); //holder in stack to avoid moving gc
Class originClassHolder = originMethod.getDeclaringClass();
//reset declaring class
if (SandHookConfig.SDK_INT >= Build.VERSION_CODES.N) {
ensureDeclareClass(originMethod, backupMethod);
}
if (Modifier.isStatic(originMethod.getModifiers())) { if (Modifier.isStatic(originMethod.getModifiers())) {
try { try {
return backupMethod.invoke(null, args); return backupMethod.invoke(null, args);
...@@ -170,6 +179,12 @@ public class SandHook { ...@@ -170,6 +179,12 @@ public class SandHook {
} }
public static void ensureBackupMethod(Method backupMethod) { public static void ensureBackupMethod(Method backupMethod) {
if (SandHookConfig.SDK_INT < Build.VERSION_CODES.N)
return;
HookWrapper.HookEntity entity = globalBackupMap.get(backupMethod);
if (entity != null) {
ensureDeclareClass(entity.target, backupMethod);
}
} }
public static void resolveStaticMethod(Member method) { public static void resolveStaticMethod(Member method) {
...@@ -312,6 +327,7 @@ public class SandHook { ...@@ -312,6 +327,7 @@ public class SandHook {
private static native int hookMethod(Member originMethod, Method hookMethod, Method backupMethod, int hookMode); private static native int hookMethod(Member originMethod, Method hookMethod, Method backupMethod, int hookMode);
public static native void ensureMethodCached(Method hook, Method backup); public static native void ensureMethodCached(Method hook, Method backup);
public static native void ensureDeclareClass(Member origin, Method backup);
public static native boolean compileMethod(Member member); public static native boolean compileMethod(Member member);
public static native boolean deCompileMethod(Member member, boolean disableJit); public static native boolean deCompileMethod(Member member, boolean disableJit);
......
package com.swift.sandhook.blacklist;
import java.lang.reflect.Member;
import java.util.HashSet;
import java.util.Set;
public class HookBlackList {
static Set<String> blackList = new HashSet<>();
static {
blackList.add("java.lang.reflect.Member.getDeclaringClass");
blackList.add("java.lang.reflect.Method.invoke");
blackList.add("java.util.Map.get");
blackList.add("java.lang.reflect.AccessibleObject.setAccessible");
blackList.add("java.lang.reflect.Member.getModifiers");
blackList.add("java.lang.reflect.InvocationTargetException.getCause");
}
public final static boolean canNotHook(Member origin) {
String name = origin.getDeclaringClass().getName() + "." + origin.getName();
return blackList.contains(name);
}
}
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