Commit 13f17d10 authored by swift_gan's avatar swift_gan

sync code

parent 3d7db2a9
......@@ -8,26 +8,27 @@ namespace SandHook {
class CastDexCacheResolvedMethods : public IMember<art::mirror::ArtMethod, void*> {
protected:
Size calOffset(art::mirror::ArtMethod p) override {
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override {
if (SDK_INT >= ANDROID_P)
return getParentSize() + 1;
auto filter = [](int offset, void *ptr) -> bool {
// if (isBadReadPtr(ptr, BYTE_POINT))
// return false;
// Size addr = ADDR(ptr);
// if (isBadReadPtr(reinterpret_cast<void *>(addr + offset), BYTE_POINT))
// return false;
// Size subAddr = ADDR(addr + offset);
// return addr == subAddr;
};
int offset = findOffsetWithCB1(&p, getParentSize(), 4, *filter);
return offset;
int offset = 0;
Size addr = getAddressFromJava(jniEnv, "com/swift/sandhook/SandHookMethodResolver", "resolvedMethodsAddress");
if (addr != 0) {
offset = findOffset(&p, getParentSize(), 2, reinterpret_cast<void *>(addr));
if (offset >= 0) {
return static_cast<Size>(offset);
}
}
switch (SDK_INT) {
}
return getParentSize() + 1;
}
};
class CastEntryPointFormInterpreter : public IMember<art::mirror::ArtMethod, void*> {
protected:
Size calOffset(art::mirror::ArtMethod p) override {
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override {
if (SDK_INT <= ANDROID_M)
return getParentSize() - 3 * BYTE_POINT;
else
......@@ -37,7 +38,7 @@ namespace SandHook {
class CastEntryPointQuickCompiled : public IMember<art::mirror::ArtMethod, void*> {
protected:
Size calOffset(art::mirror::ArtMethod p) override {
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override {
return getParentSize() - BYTE_POINT;
}
};
......@@ -45,7 +46,7 @@ namespace SandHook {
class CastAccessFlag : public IMember<art::mirror::ArtMethod, uint32_t> {
protected:
Size calOffset(art::mirror::ArtMethod p) override {
Size calOffset(JNIEnv *jniEnv, art::mirror::ArtMethod p) override {
int offset = findOffset(&p, getParentSize(), sizeof(uint32_t), 524313);
if (offset < 0)
throw getParentSize() + 1;
......@@ -77,22 +78,22 @@ namespace SandHook {
//init Members
entryPointQuickCompiled = new CastEntryPointQuickCompiled();
entryPointQuickCompiled->init(m1, size);
entryPointQuickCompiled->init(env, m1, size);
accessFlag = new CastAccessFlag();
accessFlag->init(m1, size);
accessFlag->init(env, m1, size);
entryPointFormInterpreter = new CastEntryPointFormInterpreter();
entryPointFormInterpreter->init(m1, size);
entryPointFormInterpreter->init(env, m1, size);
dexCacheResolvedMethods = new CastDexCacheResolvedMethods();
// dexCacheResolvedMethods->init(m1, size);
dexCacheResolvedMethods->init(env, m1, size);
//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_];
// //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_];
}
......@@ -108,6 +109,8 @@ namespace SandHook {
IMember<art::mirror::ArtMethod, void*>* CastArtMethod::dexCacheResolvedMethods = nullptr;
IMember<art::mirror::ArtMethod, uint32_t>* CastArtMethod::accessFlag = nullptr;
}
......@@ -40,9 +40,9 @@ namespace SandHook {
class IMember {
public:
virtual void init(PType p, Size size) {
virtual void init(JNIEnv *jniEnv, PType p, Size size) {
this->parentSize = size;
offset = calOffset(p);
offset = calOffset(jniEnv, p);
}
virtual Size getOffset() {
......@@ -69,7 +69,7 @@ namespace SandHook {
Size offset = 0;
protected:
Size parentSize = 0;
virtual Size calOffset(PType p) = 0;
virtual Size calOffset(JNIEnv *jniEnv, PType p) = 0;
};
......
......@@ -122,5 +122,20 @@ bool isBadReadPtr(void *ptr, int length)
}
Size getAddressFromJava(JNIEnv* env, char* className, char* fieldName) {
jclass clazz = env -> FindClass(className);
if (clazz == NULL){
printf("find class error !");
return 0;
}
jfieldID id = env -> GetStaticFieldID(clazz, fieldName, "Ljava/lang/Long;");
if (id == NULL){
printf("find field error !");
return 0;
}
return env -> GetStaticLongField(clazz, id);
}
#endif //SANDHOOK_UTILS_H
......@@ -13,11 +13,11 @@ public class SandHook {
public static Object testOffsetArtMethod2;
public static int testAccessFlag;
public static int methodOffset;
public static boolean init() {
initTestOffset();
SandHookMethodResolver.init();
return true;
}
......@@ -33,7 +33,6 @@ public class SandHook {
} catch (NoSuchMethodException e) {
throw new RuntimeException("SandHook init error", e);
}
//
initTestAccessFlag();
}
......@@ -42,14 +41,12 @@ public class SandHook {
try {
loadArtMethod();
Field fieldAccessFlags = getField(artMethodClass, "accessFlags");
fieldAccessFlags.setAccessible(true);
testAccessFlag = (int) fieldAccessFlags.get(testOffsetArtMethod1);
} catch (Exception e) {
}
} else {
try {
Field fieldAccessFlags = getField(Method.class, "accessFlags");
fieldAccessFlags.setAccessible(true);
testAccessFlag = (int) fieldAccessFlags.get(testOffsetMethod1);
} catch (Exception e) {
}
......@@ -59,7 +56,6 @@ public class SandHook {
private static void loadArtMethod() {
try {
Field fieldArtMethod = getField(Method.class, "artMethod");
fieldArtMethod.setAccessible(true);
testOffsetArtMethod1 = fieldArtMethod.get(testOffsetMethod1);
testOffsetArtMethod2 = fieldArtMethod.get(testOffsetMethod2);
} catch (IllegalAccessException e) {
......
......@@ -3,6 +3,10 @@ package com.swift.sandhook;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static com.swift.sandhook.SandHook.artMethodClass;
import static com.swift.sandhook.SandHook.getField;
import static com.swift.sandhook.SandHook.hasJavaArtMethod;
public class SandHookMethodResolver {
public static Field resolvedMethodsField;
......@@ -11,41 +15,67 @@ public class SandHookMethodResolver {
public static Field artMethodField;
public static boolean canResolvedInJava = false;
public static boolean isArtMethod = false;
public static long resolvedMethodsAddress = 0;
public static int dexMethodIndex = 0;
public static Method testMethod;
public static Object testArtMethod;
public static void init() {
testMethod = SandHook.testOffsetMethod1;
checkSupport();
}
private static void checkSupport() {
try {
dexMethodIndexField = SandHook.getField(Method.class, "dexMethodIndex");
dexMethodIndex = (int) dexMethodIndexField.get(SandHook.testOffsetMethod1);
dexCacheField = SandHook.getField(Class.class, "dexCache");
dexCacheField.setAccessible(true);
Object dexCache = dexCacheField.get(ArtMethodSizeTest.class);
resolvedMethodsField = SandHook.getField(dexCache.getClass(), "resolvedMethods");
Object resolvedMethods = resolvedMethodsField.get(dexCache);
if (resolvedMethods instanceof Long) {
canResolvedInJava = false;
resolvedMethodsAddress = (long) resolvedMethods;
} else if (resolvedMethods instanceof long[]) {
canResolvedInJava = true;
} else if (SandHook.hasJavaArtMethod() && resolvedMethods instanceof Object[]) {
canResolvedInJava = true;
artMethodField = getField(Method.class, "artMethod");
testArtMethod = artMethodField.get(testMethod);
if (hasJavaArtMethod() && testArtMethod.getClass() == artMethodClass) {
checkSupportForArtMethod();
isArtMethod = true;
} else if (testArtMethod instanceof Long) {
checkSupportForArtMethodId();
isArtMethod = false;
} else {
canResolvedInJava = false;
}
if (canResolvedInJava) {
artMethodField = SandHook.getField(Method.class, "artMethod");
}
} catch (Exception e) {
e.printStackTrace();
}
}
// may 5.0
private static void checkSupportForArtMethod() throws Exception {
dexMethodIndexField = getField(artMethodClass, "dexMethodIndex");
dexCacheField = getField(Class.class, "dexCache");
Object dexCache = dexCacheField.get(testMethod.getDeclaringClass());
resolvedMethodsField = getField(dexCache.getClass(), "resolvedMethods");
if (resolvedMethodsField.get(dexCache) instanceof Object[]) {
canResolvedInJava = true;
}
}
// may 6.0
private static void checkSupportForArtMethodId() throws Exception {
dexMethodIndexField = getField(Method.class, "dexMethodIndex");
dexMethodIndex = (int) dexMethodIndexField.get(testMethod);
dexCacheField = getField(Class.class, "dexCache");
Object dexCache = dexCacheField.get(testMethod.getDeclaringClass());
resolvedMethodsField = getField(dexCache.getClass(), "resolvedMethods");
Object resolvedMethods = resolvedMethodsField.get(dexCache);
if (resolvedMethods instanceof Long) {
canResolvedInJava = false;
resolvedMethodsAddress = (long) resolvedMethods;
} else if (resolvedMethods instanceof long[]) {
canResolvedInJava = true;
}
}
public static void resolveMethod(Method hook, Method backup) {
if (canResolvedInJava && artMethodField != null) {
// in java
......@@ -53,26 +83,31 @@ public class SandHookMethodResolver {
resolveInJava(hook, backup);
} catch (Exception e) {
// in native
resolveInNative(hook, backup);
}
} else {
// in native
resolveInNative(hook, backup);
}
}
private static void resolveInJava(Method hook, Method backup) throws Exception {
Object dexCache = dexCacheField.get(hook.getDeclaringClass());
int dexMethodIndex = (int) dexMethodIndexField.get(backup);
Object resolvedMethods = resolvedMethodsField.get(dexCache);
if (resolvedMethods instanceof long[]) {
long artMethod = (long) artMethodField.get(backup);
((long[])resolvedMethods)[dexMethodIndex] = artMethod;
} else if (resolvedMethods instanceof Object[]) {
if (isArtMethod) {
Object artMethod = artMethodField.get(backup);
int dexMethodIndex = (int) dexMethodIndexField.get(artMethod);
Object resolvedMethods = resolvedMethodsField.get(dexCache);
((Object[])resolvedMethods)[dexMethodIndex] = artMethod;
} else {
throw new UnsupportedOperationException("unsupport");
int dexMethodIndex = (int) dexMethodIndexField.get(backup);
Object resolvedMethods = resolvedMethodsField.get(dexCache);
long artMethod = (long) artMethodField.get(backup);
((long[])resolvedMethods)[dexMethodIndex] = artMethod;
}
}
private static void resolveInNative(Method hook, Method backup) {
// HookMain.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