Hook ShouldUseInterpreterEntrypoint for O-Q
This commit is contained in:
parent
2eb4467d7f
commit
14e38beec3
|
|
@ -30,8 +30,6 @@ void *getArtMethod(JNIEnv *env, jobject jmethod);
|
||||||
// TODO: move to common utils instead of in YAHFA's code
|
// TODO: move to common utils instead of in YAHFA's code
|
||||||
void *getEntryPoint(void* method);
|
void *getEntryPoint(void* method);
|
||||||
|
|
||||||
void setEntryPoint(void* method, void* entry);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -113,38 +113,10 @@ void setNonCompilable(void *method) {
|
||||||
LOGI("setNonCompilable: change access flags from 0x%x to 0x%x", old_flags, access_flags);
|
LOGI("setNonCompilable: change access flags from 0x%x to 0x%x", old_flags, access_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool setNativeFlag(void *method, bool isNative) {
|
|
||||||
uint32_t access_flags = getFlags(method);
|
|
||||||
uint32_t old_flags = access_flags;
|
|
||||||
LOGI("setNativeFlag: access flags is 0x%x", access_flags);
|
|
||||||
uint32_t old_access_flags = access_flags;
|
|
||||||
if (isNative) {
|
|
||||||
access_flags |= kAccNative;
|
|
||||||
if (SDKVersion >= __ANDROID_API_Q__) {
|
|
||||||
// On API 29 whether to use the fast path or not is cached in the ART method structure
|
|
||||||
access_flags &= ~kAccFastInterpreterToInterpreterInvoke;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
access_flags &= ~kAccNative;
|
|
||||||
}
|
|
||||||
if (access_flags != old_access_flags) {
|
|
||||||
setFlags(method, access_flags);
|
|
||||||
LOGI("change access flags from 0x%x to 0x%x", old_flags, access_flags);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *getEntryPoint(void* method) {
|
void *getEntryPoint(void* method) {
|
||||||
return readAddr((char *) method + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod);
|
return readAddr((char *) method + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEntryPoint(void* method, void* entry) {
|
|
||||||
memcpy((char *) method + OFFSET_entry_point_from_quick_compiled_code_in_ArtMethod,
|
|
||||||
&entry,
|
|
||||||
pointer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) {
|
static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) {
|
||||||
if (hookCount >= hookCap) {
|
if (hookCount >= hookCap) {
|
||||||
LOGI("not enough capacity. Allocating...");
|
LOGI("not enough capacity. Allocating...");
|
||||||
|
|
@ -188,12 +160,6 @@ static int replaceMethod(void *fromMethod, void *toMethod, int isBackup) {
|
||||||
pointer_size);
|
pointer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the target method to native so that Android O wouldn't invoke it with interpreter
|
|
||||||
// for Q or above, we use ShouldUseInterpreterEntrypoint
|
|
||||||
if (SDKVersion >= __ANDROID_API_O__ && SDKVersion < __ANDROID_API_Q__) {
|
|
||||||
setNativeFlag(fromMethod, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
hookCount += 1;
|
hookCount += 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,21 +58,12 @@ namespace art {
|
||||||
|
|
||||||
CREATE_HOOK_STUB_ENTRIES(bool, ShouldUseInterpreterEntrypoint, void *art_method,
|
CREATE_HOOK_STUB_ENTRIES(bool, ShouldUseInterpreterEntrypoint, void *art_method,
|
||||||
const void *quick_code) {
|
const void *quick_code) {
|
||||||
if (UNLIKELY(quick_code != nullptr && edxp::isEntryHooked(quick_code))) {
|
if (quick_code != nullptr && UNLIKELY(edxp::isHooked(art_method))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ShouldUseInterpreterEntrypointBackup(art_method, quick_code);
|
return ShouldUseInterpreterEntrypointBackup(art_method, quick_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_HOOK_STUB_ENTRIES(bool, IsQuickToInterpreterBridge, void *thiz,
|
|
||||||
const void *quick_code) {
|
|
||||||
if (quick_code != nullptr && UNLIKELY(edxp::isEntryHooked(quick_code))) {
|
|
||||||
LOGD("Pretend to be quick to interpreter bridge %p", quick_code);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return IsQuickToInterpreterBridgeBackup(thiz, quick_code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ClassLinker(void *thiz) : HookedObject(thiz) {}
|
ClassLinker(void *thiz) : HookedObject(thiz) {}
|
||||||
|
|
||||||
|
|
@ -138,8 +129,7 @@ namespace art {
|
||||||
|
|
||||||
// Sandhook will hook ShouldUseInterpreterEntrypoint, so we just skip
|
// Sandhook will hook ShouldUseInterpreterEntrypoint, so we just skip
|
||||||
// edxp::Context::GetInstance()->GetVariant() will not work here, so we use smh dirty hack
|
// edxp::Context::GetInstance()->GetVariant() will not work here, so we use smh dirty hack
|
||||||
if (api_level >= __ANDROID_API_Q__ &&
|
if (!edxp::path_exists(edxp::kLibSandHookNativePath)) {
|
||||||
edxp::path_exists(edxp::kLibSandHookNativePath)) {
|
|
||||||
LOGD("Not sandhook, installing _ZN3art11ClassLinker30ShouldUseInterpreterEntrypointEPNS_9ArtMethodEPKv");
|
LOGD("Not sandhook, installing _ZN3art11ClassLinker30ShouldUseInterpreterEntrypointEPNS_9ArtMethodEPKv");
|
||||||
HOOK_FUNC(ShouldUseInterpreterEntrypoint,
|
HOOK_FUNC(ShouldUseInterpreterEntrypoint,
|
||||||
"_ZN3art11ClassLinker30ShouldUseInterpreterEntrypointEPNS_9ArtMethodEPKv");
|
"_ZN3art11ClassLinker30ShouldUseInterpreterEntrypointEPNS_9ArtMethodEPKv");
|
||||||
|
|
@ -151,8 +141,6 @@ namespace art {
|
||||||
// if (api_level >= __ANDROID_API_R__) {
|
// if (api_level >= __ANDROID_API_R__) {
|
||||||
// RETRIEVE_FUNC_SYMBOL(MakeInitializedClassesVisiblyInitialized,
|
// RETRIEVE_FUNC_SYMBOL(MakeInitializedClassesVisiblyInitialized,
|
||||||
// "_ZN3art11ClassLinker40MakeInitializedClassesVisiblyInitializedEPNS_6ThreadEb");
|
// "_ZN3art11ClassLinker40MakeInitializedClassesVisiblyInitializedEPNS_6ThreadEb");
|
||||||
// HOOK_FUNC(IsQuickToInterpreterBridge,
|
|
||||||
// "_ZNK3art11ClassLinker26IsQuickToInterpreterBridgeEPKv");
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,16 +30,12 @@ namespace edxp {
|
||||||
REGISTER_EDXP_NATIVE_METHODS("de.robv.android.xposed.PendingHooks");
|
REGISTER_EDXP_NATIVE_METHODS("de.robv.android.xposed.PendingHooks");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEntryHooked(const void* entry) {
|
|
||||||
return hooked_methods_.count(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isHooked(void* art_method) {
|
bool isHooked(void* art_method) {
|
||||||
return isEntryHooked(getEntryPoint(art_method));
|
return hooked_methods_.count(art_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
void recordHooked(void * art_method) {
|
void recordHooked(void * art_method) {
|
||||||
hooked_methods_.insert(getEntryPoint(art_method));
|
hooked_methods_.insert(art_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -9,8 +9,6 @@ namespace edxp {
|
||||||
|
|
||||||
void RegisterPendingHooks(JNIEnv *);
|
void RegisterPendingHooks(JNIEnv *);
|
||||||
|
|
||||||
bool isEntryHooked(const void* entry);
|
|
||||||
|
|
||||||
bool isHooked(void* art_method);
|
bool isHooked(void* art_method);
|
||||||
|
|
||||||
void recordHooked(void* art_method);
|
void recordHooked(void* art_method);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue