Commit 4d896ad7 authored by swift_gan's avatar swift_gan Committed by ganyao114

Fix: fix ArtMethod Offset on Android 5.1

parent 564a3fd3
...@@ -47,9 +47,11 @@ namespace SandHook { ...@@ -47,9 +47,11 @@ namespace SandHook {
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) {
return RoundUpToPtrSize(4 * 7 + 4 * 2);
} else if (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) {
Size addr = getAddressFromJava(jniEnv, "com/swift/sandhook/SandHookMethodResolver", Size addr = getAddressFromJava(jniEnv, "com/swift/sandhook/SandHookMethodResolver",
"entryPointFromInterpreter"); "entryPointFromInterpreter");
int offset = 0; int offset = 0;
...@@ -83,7 +85,7 @@ namespace SandHook { ...@@ -83,7 +85,7 @@ namespace SandHook {
} }
return getParentSize() - 4 - 2 * BYTE_POINT; return getParentSize() - 4 - 2 * BYTE_POINT;
} else { } else {
return getParentSize() - 4 - 2 * BYTE_POINT; return CastArtMethod::entryPointFromInterpreter->getOffset() + 2 * BYTE_POINT;
} }
} }
}; };
...@@ -189,8 +191,6 @@ namespace SandHook { ...@@ -189,8 +191,6 @@ namespace SandHook {
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->init(env, m1, size);
accessFlag = new CastAccessFlag(); accessFlag = new CastAccessFlag();
accessFlag->init(env, m1, size); accessFlag->init(env, m1, size);
...@@ -198,12 +198,15 @@ namespace SandHook { ...@@ -198,12 +198,15 @@ namespace SandHook {
entryPointFromInterpreter = new CastEntryPointFormInterpreter(); entryPointFromInterpreter = new CastEntryPointFormInterpreter();
entryPointFromInterpreter->init(env, m1, size); entryPointFromInterpreter->init(env, m1, size);
dexCacheResolvedMethods = new CastDexCacheResolvedMethods(); entryPointQuickCompiled = new CastEntryPointQuickCompiled();
dexCacheResolvedMethods->init(env, m1, size); entryPointQuickCompiled->init(env, m1, size);
dexMethodIndex = new CastDexMethodIndex(); dexMethodIndex = new CastDexMethodIndex();
dexMethodIndex->init(env, m1, size); dexMethodIndex->init(env, m1, size);
dexCacheResolvedMethods = new CastDexCacheResolvedMethods();
dexCacheResolvedMethods->init(env, m1, size);
declaringClass = new CastShadowClass(); declaringClass = new CastShadowClass();
declaringClass->init(env, m1, size); declaringClass->init(env, m1, size);
......
...@@ -11,20 +11,23 @@ ...@@ -11,20 +11,23 @@
#include "../includes/arch.h" #include "../includes/arch.h"
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <type_traits>
#define RoundUpToPtrSize(x) (x + BYTE_POINT - 1 - ((x + BYTE_POINT - 1) & (BYTE_POINT - 1)))
extern "C" { extern "C" {
Size getAddressFromJava(JNIEnv *env, const char *className, const char *fieldName); Size getAddressFromJava(JNIEnv *env, const char *className, const char *fieldName);
Size getAddressFromJavaByCallMethod(JNIEnv *env, const char *className, const char *methodName); Size getAddressFromJavaByCallMethod(JNIEnv *env, const char *className, const char *methodName);
jint getIntFromJava(JNIEnv *env, const char *className, const char *fieldName); jint getIntFromJava(JNIEnv *env, const char *className, const char *fieldName);
bool getBooleanFromJava(JNIEnv *env, const char *className, const char *fieldName); bool getBooleanFromJava(JNIEnv *env, const char *className, const char *fieldName);
bool munprotect(size_t addr, size_t len); bool munprotect(size_t addr, size_t len);
bool flushCacheExt(Size addr, Size len); bool flushCacheExt(Size addr, Size len);
} }
......
...@@ -6,86 +6,86 @@ ...@@ -6,86 +6,86 @@
extern "C" { extern "C" {
Size getAddressFromJava(JNIEnv *env, const char *className, const char *fieldName) { Size getAddressFromJava(JNIEnv *env, const char *className, const char *fieldName) {
jclass clazz = env->FindClass(className); jclass clazz = env->FindClass(className);
if (clazz == NULL) { if (clazz == NULL) {
printf("find class error !"); printf("find class error !");
return 0; return 0;
}
jfieldID id = env->GetStaticFieldID(clazz, fieldName, "J");
if (id == NULL) {
printf("find field error !");
return 0;
}
return env->GetStaticLongField(clazz, id);
} }
jfieldID id = env->GetStaticFieldID(clazz, fieldName, "J");
if (id == NULL) {
printf("find field error !");
return 0;
}
return env->GetStaticLongField(clazz, id);
}
Size getAddressFromJavaByCallMethod(JNIEnv *env, const char *className, const char *methodName) { Size getAddressFromJavaByCallMethod(JNIEnv *env, const char *className, const char *methodName) {
jclass clazz = env->FindClass(className); jclass clazz = env->FindClass(className);
if (clazz == NULL) { if (clazz == NULL) {
printf("find class error !"); printf("find class error !");
return 0; return 0;
} }
jmethodID id = env->GetStaticMethodID(clazz, methodName, "()J"); jmethodID id = env->GetStaticMethodID(clazz, methodName, "()J");
if (id == NULL) { if (id == NULL) {
printf("find field error !"); printf("find field error !");
return 0; return 0;
}
return env->CallStaticLongMethodA(clazz, id, nullptr);
} }
return env->CallStaticLongMethodA(clazz, id, nullptr);
}
jint getIntFromJava(JNIEnv *env, const char *className, const char *fieldName) { jint getIntFromJava(JNIEnv *env, const char *className, const char *fieldName) {
jclass clazz = env->FindClass(className); jclass clazz = env->FindClass(className);
if (clazz == NULL) { if (clazz == NULL) {
printf("find class error !"); printf("find class error !");
return 0; return 0;
} }
jfieldID id = env->GetStaticFieldID(clazz, fieldName, "I"); jfieldID id = env->GetStaticFieldID(clazz, fieldName, "I");
if (id == NULL) { if (id == NULL) {
printf("find field error !"); printf("find field error !");
return 0; return 0;
}
return env->GetStaticIntField(clazz, id);
} }
return env->GetStaticIntField(clazz, id);
}
bool getBooleanFromJava(JNIEnv *env, const char *className, const char *fieldName) { bool getBooleanFromJava(JNIEnv *env, const char *className, const char *fieldName) {
jclass clazz = env->FindClass(className); jclass clazz = env->FindClass(className);
if (clazz == NULL) { if (clazz == NULL) {
printf("find class error !"); printf("find class error !");
return false; return false;
} }
jfieldID id = env->GetStaticFieldID(clazz, fieldName, "Z"); jfieldID id = env->GetStaticFieldID(clazz, fieldName, "Z");
if (id == NULL) { if (id == NULL) {
printf("find field error !"); printf("find field error !");
return false; return false;
}
return env->GetStaticBooleanField(clazz, id);
} }
return env->GetStaticBooleanField(clazz, id);
}
bool munprotect(size_t addr, size_t len) { bool munprotect(size_t addr, size_t len) {
long pagesize = sysconf(_SC_PAGESIZE); long pagesize = sysconf(_SC_PAGESIZE);
unsigned alignment = (unsigned) ((unsigned long long) addr % pagesize); unsigned alignment = (unsigned) ((unsigned long long) addr % pagesize);
int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len), int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len),
PROT_READ | PROT_WRITE | PROT_EXEC); PROT_READ | PROT_WRITE | PROT_EXEC);
if (i == -1) { if (i == -1) {
return false; return false;
}
return true;
} }
return true;
}
bool flushCacheExt(Size addr, Size len) { bool flushCacheExt(Size addr, Size len) {
#if defined(__arm__) #if defined(__arm__)
int i = cacheflush(addr, addr + len, 0); int i = cacheflush(addr, addr + len, 0);
if (i == -1) { if (i == -1) {
return false; return false;
}
return true;
#elif defined(__aarch64__)
char *begin = reinterpret_cast<char *>(addr);
__builtin___clear_cache(begin, begin + len);
#endif
return true;
} }
return true;
#elif defined(__aarch64__)
char *begin = reinterpret_cast<char *>(addr);
__builtin___clear_cache(begin, begin + len);
#endif
return true;
}
} }
...@@ -68,9 +68,13 @@ public class SandHookMethodResolver { ...@@ -68,9 +68,13 @@ public class SandHookMethodResolver {
canResolvedInJava = true; canResolvedInJava = true;
} }
try { try {
try {
dexMethodIndex = (int) dexMethodIndexField.get(testArtMethod);
} catch (Throwable e) {
}
try { try {
fieldEntryPointFromCompiledCode = getField(artMethodClass, "entryPointFromQuickCompiledCode"); fieldEntryPointFromCompiledCode = getField(artMethodClass, "entryPointFromQuickCompiledCode");
} catch (Exception e) { } catch (Throwable e) {
fieldEntryPointFromCompiledCode = getField(artMethodClass, "entryPointFromCompiledCode"); fieldEntryPointFromCompiledCode = getField(artMethodClass, "entryPointFromCompiledCode");
} }
if (fieldEntryPointFromCompiledCode.getType() == int.class) { if (fieldEntryPointFromCompiledCode.getType() == int.class) {
......
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