Fix bootloop on R Public Beta 2 (#583)

* Fix bootloop on R Public Beta 2

* Fix crashes with some apps
This commit is contained in:
双草酸酯 2020-07-30 21:40:53 +08:00 committed by GitHub
parent 56fd1ecfd4
commit 27f44d3c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 5 deletions

View File

@ -22,6 +22,8 @@ static int kAccNative = 0x0100;
static int kAccCompileDontBother = 0x01000000; static int kAccCompileDontBother = 0x01000000;
static int kAccFastInterpreterToInterpreterInvoke = 0x40000000; static int kAccFastInterpreterToInterpreterInvoke = 0x40000000;
static jfieldID fieldArtMethod = NULL;
static inline uint16_t read16(void *addr) { static inline uint16_t read16(void *addr) {
return *((uint16_t *) addr); return *((uint16_t *) addr);
} }
@ -37,8 +39,12 @@ static inline void write32(void *addr, uint32_t value) {
void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVersion) { void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVersion) {
int i; int i;
SDKVersion = sdkVersion; SDKVersion = sdkVersion;
jclass classExecutable;
LOGI("init to SDK %d", sdkVersion); LOGI("init to SDK %d", sdkVersion);
switch (sdkVersion) { switch (sdkVersion) {
case ANDROID_R:
classExecutable = (*env)->FindClass(env, "java/lang/reflect/Executable");
fieldArtMethod = (*env)->GetFieldID(env, classExecutable, "artMethod", "J");
case ANDROID_Q: case ANDROID_Q:
case ANDROID_P: case ANDROID_P:
kAccCompileDontBother = 0x02000000; kAccCompileDontBother = 0x02000000;
@ -211,6 +217,10 @@ static int doBackupAndHook(JNIEnv *env, void *targetMethod, void *hookMethod, vo
static void ensureMethodCached(void *hookMethod, void *backupMethod, static void ensureMethodCached(void *hookMethod, void *backupMethod,
void *hookClassResolvedMethods) { void *hookClassResolvedMethods) {
if (!backupMethod || (long) backupMethod < 0x1000) {
LOGW("ensureMethodCached: backupMethod is null or illegal: %p", backupMethod);
return;
}
void *dexCacheResolvedMethods; void *dexCacheResolvedMethods;
// then we get the dex method index of the static backup method // then we get the dex method index of the static backup method
int methodIndex = read32( int methodIndex = read32(
@ -255,6 +265,25 @@ static void ensureMethodCached(void *hookMethod, void *backupMethod,
} }
} }
static void *getArtMethod(JNIEnv *env, jobject jmethod) {
void *artMethod = NULL;
if(jmethod == NULL) {
return artMethod;
}
if(SDKVersion == ANDROID_R) {
artMethod = (void *) (*env)->GetLongField(env, jmethod, fieldArtMethod);
}
else {
artMethod = (void *) (*env)->FromReflectedMethod(env, jmethod);
}
LOGI("ArtMethod: %p", artMethod);
return artMethod;
}
jobject Java_lab_galaxy_yahfa_HookMain_findMethodNative(JNIEnv *env, jclass clazz, jobject Java_lab_galaxy_yahfa_HookMain_findMethodNative(JNIEnv *env, jclass clazz,
jclass targetClass, jstring methodName, jclass targetClass, jstring methodName,
jstring methodSig) { jstring methodSig) {
@ -287,9 +316,9 @@ jboolean Java_lab_galaxy_yahfa_HookMain_backupAndHookNative(JNIEnv *env, jclass
jobject backup) { jobject backup) {
if (!doBackupAndHook(env, if (!doBackupAndHook(env,
(void *) (*env)->FromReflectedMethod(env, target), getArtMethod(env, target),
(void *) (*env)->FromReflectedMethod(env, hook), getArtMethod(env, hook),
backup == NULL ? NULL : (void *) (*env)->FromReflectedMethod(env, backup) getArtMethod(env, backup)
)) { )) {
(*env)->NewGlobalRef(env, (*env)->NewGlobalRef(env,
hook); // keep a global ref so that the hook method would not be GCed hook); // keep a global ref so that the hook method would not be GCed

View File

@ -14,6 +14,7 @@
#define ANDROID_O2 27 #define ANDROID_O2 27
#define ANDROID_P 28 #define ANDROID_P 28
#define ANDROID_Q 29 #define ANDROID_Q 29
#define ANDROID_R 30
#define roundUpTo4(v) ((v+4-1) - ((v+4-1)&3)) #define roundUpTo4(v) ((v+4-1) - ((v+4-1)&3))
#define roundUpTo8(v) ((v+8-1) - ((v+8-1)&7)) #define roundUpTo8(v) ((v+8-1) - ((v+8-1)&7))

View File

@ -32,8 +32,9 @@ namespace edxp {
return; return;
} }
void *art_method = env->FromReflectedMethod(member); void *art_method = env->FromReflectedMethod(member);
if (!art_method) {
LOGE("setNonCompilableNative: art_method is null"); if (!art_method || (long)art_method < 0x1000) {
LOGE("setNonCompilableNative: art_method is null or invalid: %p", art_method);
return; return;
} }
setNonCompilable(art_method); setNonCompilable(art_method);