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() {
return CastArtMethod::entryPointFormInterpreter->get(this);
}
void* ArtMethod::getDeclaringClassPtr() {
GCRoot ArtMethod::getDeclaringClass() {
return CastArtMethod::declaringClass->get(this);
}
......@@ -132,7 +132,7 @@ void ArtMethod::setDexCacheResolveItem(uint32_t index, void* item) {
CastArtMethod::dexCacheResolvedMethods->setElement(this, index, item);
}
void ArtMethod::setDeclaringClassPtr(void *classPtr) {
void ArtMethod::setDeclaringClass(GCRoot classPtr) {
CastArtMethod::declaringClass->set(this, classPtr);
}
......
......@@ -128,9 +128,11 @@ namespace SandHook {
}
};
class CastShadowClass : public IMember<art::mirror::ArtMethod, void*> {
class CastShadowClass : public IMember<art::mirror::ArtMethod, GCRoot> {
protected:
Size calOffset(JNIEnv *jniEnv, mirror::ArtMethod *p) override {
if (SDK_INT < ANDROID_N)
return getParentSize() + 1;
return 0;
}
};
......@@ -237,7 +239,7 @@ namespace SandHook {
ArrayMember<art::mirror::ArtMethod, void *> *CastArtMethod::dexCacheResolvedMethods = nullptr;
IMember<art::mirror::ArtMethod, uint32_t> *CastArtMethod::dexMethodIndex = 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::genericJniStub = nullptr;
void *CastArtMethod::staticResolveStub = nullptr;
......
......@@ -16,19 +16,15 @@
* limitations under the License.
*/
/**
* art_6_0.h
*
* @author : sanping.li@alipay.com
*
*/
#ifndef ART_H
#define ART_H
#include <jni.h>
#include "arch.h"
//7.0 - 10.0
#define GCRoot uint32_t
namespace art {
namespace mirror {
class Object {
......@@ -64,13 +60,13 @@ public:
void setInterpreterCodeEntry(void* entry);
void setDexCacheResolveList(void* list);
void setDexCacheResolveItem(uint32_t index, void* item);
void setDeclaringClassPtr(void* classPtr);
void setDeclaringClass(GCRoot classPtr);
void* getQuickCodeEntry();
void* getInterpreterCodeEntry();
uint32_t getAccessFlags();
uint32_t getDexMethodIndex();
void* getDeclaringClassPtr();
GCRoot getDeclaringClass();
bool compile(JNIEnv* env);
bool deCompile();
......
......@@ -18,7 +18,7 @@ namespace SandHook {
static ArrayMember<art::mirror::ArtMethod,void*>* dexCacheResolvedMethods;
static IMember<art::mirror::ArtMethod, uint32_t>* dexMethodIndex;
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* genericJniStub;
static void* staticResolveStub;
......
......@@ -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,
art::mirror::ArtMethod *originMethod,
art::mirror::ArtMethod *hookMethod,
......@@ -354,6 +366,11 @@ static JNINativeMethod jniSandHook[] = {
"(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V",
(void *) Java_com_swift_sandhook_SandHook_ensureMethodCached
},
{
"ensureDeclareClass",
"(Ljava/lang/reflect/Member;Ljava/lang/reflect/Method;)V",
(void *) ensureDeclareClass
},
{
"compileMethod",
"(Ljava/lang/reflect/Member;)Z",
......
......@@ -3,6 +3,7 @@ package com.swift.sandhook;
import android.os.Build;
import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.blacklist.HookBlackList;
import com.swift.sandhook.utils.ReflectionUtils;
import com.swift.sandhook.utils.Unsafe;
import com.swift.sandhook.wrapper.HookErrorException;
......@@ -82,7 +83,10 @@ public class SandHook {
throw new HookErrorException("null input");
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(backup);
......@@ -145,7 +149,12 @@ public class SandHook {
}
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())) {
try {
return backupMethod.invoke(null, args);
......@@ -170,6 +179,12 @@ public class SandHook {
}
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) {
......@@ -312,6 +327,7 @@ public class SandHook {
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 ensureDeclareClass(Member origin, Method backup);
public static native boolean compileMethod(Member member);
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