Uniform the use of new ArtMethod resolution strategy

This commit is contained in:
solohsu 2020-08-02 01:00:42 +08:00
parent 6b7c8e4942
commit 0336a2aa29
6 changed files with 29 additions and 23 deletions

View File

@ -122,7 +122,9 @@ public class HookMain {
checkCompatibleMethods(target, backup, "Original", "Backup");
}
if (backup != null) {
HookMethodResolver.resolveMethod(hook, backup);
HookMethodResolver.resolveMethod(hook, backup, target);
} else {
Utils.logD("wanna resolve backup method, but it's null, target: " + target);
}
// make sure GC completed before hook
Thread currentThread = Thread.currentThread();

View File

@ -91,22 +91,23 @@ public class HookMethodResolver {
}
}
public static void resolveMethod(Method hook, Method backup) {
public static void resolveMethod(Method hook, Method backup, Object target) {
if (canResolvedInJava && artMethodField != null) {
// in java
try {
resolveInJava(hook, backup);
resolveInJava(hook, backup, target);
} catch (Exception e) {
// in native
resolveInNative(hook, backup);
resolveInNative(hook, backup, target);
}
} else {
// in native
resolveInNative(hook, backup);
resolveInNative(hook, backup, target);
}
}
private static void resolveInJava(Method hook, Method backup) throws Exception {
private static void resolveInJava(Method hook, Method backup, Object target) throws Exception {
Utils.logD("start to resolve in java. target: " + target);
Object dexCache = dexCacheField.get(hook.getDeclaringClass());
if (isArtMethod) {
Object artMethod = artMethodField.get(backup);
@ -121,7 +122,8 @@ public class HookMethodResolver {
}
}
private static void resolveInNative(Method hook, Method backup) {
private static void resolveInNative(Method hook, Method backup, Object target) {
Utils.logD("start to resolve in native. target: " + target);
Yahfa.ensureMethodCached(hook, backup);
}

View File

@ -25,6 +25,8 @@ void setNonCompilable(void *method);
bool setNativeFlag(void *method, bool isNative);
void *getArtMethod(JNIEnv *env, jobject jmethod);
static void *getResolvedMethodsAddr(JNIEnv *, jobject);
#ifdef __cplusplus

View File

@ -31,8 +31,8 @@ static inline void write32(void *addr, uint32_t value) {
*((uint32_t *) addr) = value;
}
static inline void* readAddr(void *addr) {
return *((void**) addr);
static inline void *readAddr(void *addr) {
return *((void **) addr);
}
void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVersion) {
@ -215,8 +215,8 @@ static int doBackupAndHook(JNIEnv *env, void *targetMethod, void *hookMethod, vo
static void ensureMethodCached(void *hookMethod, void *backupMethod,
void *hookClassResolvedMethods) {
if (!backupMethod || (long) backupMethod < 0x1000) {
LOGW("ensureMethodCached: backupMethod is null or illegal: %p", backupMethod);
if (!backupMethod) {
LOGE("ensureMethodCached: backupMethod is null");
return;
}
void *dexCacheResolvedMethods;
@ -263,17 +263,16 @@ static void ensureMethodCached(void *hookMethod, void *backupMethod,
}
}
static void *getArtMethod(JNIEnv *env, jobject jmethod) {
void *getArtMethod(JNIEnv *env, jobject jmethod) {
void *artMethod = NULL;
if(jmethod == NULL) {
if (jmethod == NULL) {
return artMethod;
}
if(SDKVersion == __ANDROID_API_R__) {
if (SDKVersion == __ANDROID_API_R__) {
artMethod = (void *) (*env)->GetLongField(env, jmethod, fieldArtMethod);
}
else {
} else {
artMethod = (void *) (*env)->FromReflectedMethod(env, jmethod);
}
@ -329,8 +328,8 @@ jboolean Java_lab_galaxy_yahfa_HookMain_backupAndHookNative(JNIEnv *env, jclass
void Java_lab_galaxy_yahfa_HookMain_ensureMethodCached(JNIEnv *env, jclass clazz,
jobject hook,
jobject backup) {
ensureMethodCached((void *) (*env)->FromReflectedMethod(env, hook),
backup == NULL ? NULL : (void *) (*env)->FromReflectedMethod(env, backup),
ensureMethodCached(getArtMethod(env, hook),
getArtMethod(env, backup),
getResolvedMethodsAddr(env, hook));
}

View File

@ -4,6 +4,7 @@
#include <art/runtime/class_linker.h>
#include <nativehelper/jni_macros.h>
#include <vector>
#include <HookMain.h>
#include "art_class_linker.h"
namespace edxp {
@ -11,7 +12,7 @@ namespace edxp {
static std::vector<void *> deopted_methods;
static void ClassLinker_setEntryPointsToInterpreter(JNI_START, jobject method) {
void *reflected_method = env->FromReflectedMethod(method);
void *reflected_method = getArtMethod(env, method);
if (std::find(deopted_methods.begin(), deopted_methods.end(), reflected_method) !=
deopted_methods.end()) {
LOGD("method %p has been deopted before, skip...", reflected_method);

View File

@ -31,10 +31,10 @@ namespace edxp {
LOGE("setNonCompilableNative: member is null");
return;
}
void *art_method = env->FromReflectedMethod(member);
void *art_method = getArtMethod(env, member);
if (!art_method || (long)art_method < 0x1000) {
LOGE("setNonCompilableNative: art_method is null or invalid: %p", art_method);
if (!art_method) {
LOGE("setNonCompilableNative: art_method is null");
return;
}
setNonCompilable(art_method);
@ -45,7 +45,7 @@ namespace edxp {
LOGE("setNativeFlagNative: member is null");
return JNI_FALSE;
}
void *art_method = env->FromReflectedMethod(member);
void *art_method = getArtMethod(env, member);
if (!art_method) {
LOGE("setNativeFlagNative: art_method is null");
return JNI_FALSE;