Commit 13f17d10 authored by swift_gan's avatar swift_gan

sync code

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