Use a more stable symbol to deoptimize method
Now deoptMethod API supports all Android versions >= 6.0
This commit is contained in:
parent
88e0d33c2a
commit
b5b3280c9f
|
|
@ -92,6 +92,7 @@ public final class XposedInit {
|
||||||
&& !ConfigManager.isDynamicModulesMode()) {
|
&& !ConfigManager.isDynamicModulesMode()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// FIXME module list is cleared but never could be reload again when using dynamic-module-list under multi-user environment
|
||||||
XposedBridge.clearLoadedPackages();
|
XposedBridge.clearLoadedPackages();
|
||||||
final String filename = INSTALLER_DATA_BASE_DIR + "conf/modules.list";
|
final String filename = INSTALLER_DATA_BASE_DIR + "conf/modules.list";
|
||||||
BaseService service = SELinuxHelper.getAppDataFileService();
|
BaseService service = SELinuxHelper.getAppDataFileService();
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,9 @@ void (*deoptBootImage)(void *runtime) = nullptr;
|
||||||
|
|
||||||
bool (*runtimeInitBackup)(void *runtime, void *mapAddr) = nullptr;
|
bool (*runtimeInitBackup)(void *runtime, void *mapAddr) = nullptr;
|
||||||
|
|
||||||
// instrumentation
|
void *class_linker_ = nullptr;
|
||||||
void *instru_ = nullptr;
|
|
||||||
|
|
||||||
static void *(*instrCstBackup)(void *instru) = nullptr;
|
static void *(*classLinkerCstBackup)(void *, void *) = nullptr;
|
||||||
|
|
||||||
void (*deoptMethod)(void *, void *) = nullptr;
|
void (*deoptMethod)(void *, void *) = nullptr;
|
||||||
|
|
||||||
|
|
@ -131,38 +130,38 @@ static void hookIsInSamePackage(int api_level, void *artHandle,
|
||||||
reinterpret_cast<void **>(&isInSamePackageBackup));
|
reinterpret_cast<void **>(&isInSamePackageBackup));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *my_instruCst(void *instru) {
|
void *my_classLinkerCst(void *classLinker, void *internTable) {
|
||||||
if (!instrCstBackup) {
|
LOGI("classLinkerCst starts");
|
||||||
LOGE("instrCstBackup is null");
|
void *result = (*classLinkerCstBackup)(classLinker, internTable);
|
||||||
return instru;
|
if (class_linker_ != classLinker) {
|
||||||
}
|
LOGI("class_linker_ changed from %p to %p", class_linker_, classLinker);
|
||||||
LOGI("instrCst starts");
|
class_linker_ = classLinker;
|
||||||
void *result = (*instrCstBackup)(instru);
|
|
||||||
LOGI("instrCst finishes");
|
|
||||||
if (instru_ != instru) {
|
|
||||||
LOGI("instru_ changed from %p to %p", instru_, instru);
|
|
||||||
instru_ = instru;
|
|
||||||
}
|
}
|
||||||
|
LOGI("classLinkerCst finishes");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hookInstrumentation(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) {
|
void hookInstrumentation(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) {
|
||||||
if (api_level < ANDROID_P) {
|
if (api_level < ANDROID_M) {
|
||||||
// TODO support other api levels
|
// 5.x not supported
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void *classLinkerCstSym = dlsym(artHandle,
|
||||||
|
"_ZN3art11ClassLinkerC2EPNS_11InternTableE");
|
||||||
|
if (!classLinkerCstSym) {
|
||||||
|
LOGE("can't get classLinkerCstSym: %s", dlerror());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void *instruCstSym = dlsym(artHandle,
|
|
||||||
"_ZN3art15instrumentation15InstrumentationC2Ev");
|
|
||||||
deoptMethod = reinterpret_cast<void (*)(void *, void *)>(
|
deoptMethod = reinterpret_cast<void (*)(void *, void *)>(
|
||||||
dlsym(artHandle,
|
dlsym(artHandle,
|
||||||
"_ZN3art15instrumentation15Instrumentation40UpdateMethodsCodeToInterpreterEntryPointEPNS_9ArtMethodE"));
|
"_ZNK3art11ClassLinker27SetEntryPointsToInterpreterEPNS_9ArtMethodE"));
|
||||||
if (!instruCstSym) {
|
if (!deoptMethod) {
|
||||||
LOGE("can't get instruCstSym: %s", dlerror());
|
LOGE("can't get deoptMethodSym: %s", dlerror());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(*hookFun)(instruCstSym, reinterpret_cast<void *>(my_instruCst),
|
(*hookFun)(classLinkerCstSym, reinterpret_cast<void *>(my_classLinkerCst),
|
||||||
reinterpret_cast<void **>(&instrCstBackup));
|
reinterpret_cast<void **>(&classLinkerCstBackup));
|
||||||
LOGI("instrCst hooked");
|
LOGI("classLinkerCst hooked");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<void *> deoptedMethods;
|
std::vector<void *> deoptedMethods;
|
||||||
|
|
@ -172,16 +171,20 @@ void deoptimize_method(JNIEnv *env, jclass clazz, jobject method) {
|
||||||
LOGE("deoptMethodSym is null, skip deopt");
|
LOGE("deoptMethodSym is null, skip deopt");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!class_linker_) {
|
||||||
|
LOGE("class_linker_ is null, skip deopt");
|
||||||
|
return;
|
||||||
|
}
|
||||||
void *reflected_method = env->FromReflectedMethod(method);
|
void *reflected_method = env->FromReflectedMethod(method);
|
||||||
if (std::find(deoptedMethods.begin(), deoptedMethods.end(), reflected_method) !=
|
if (std::find(deoptedMethods.begin(), deoptedMethods.end(), reflected_method) !=
|
||||||
deoptedMethods.end()) {
|
deoptedMethods.end()) {
|
||||||
LOGD("method %p has been deopted before, skip...", reflected_method);
|
LOGD("method %p has been deopted before, skip...", reflected_method);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOGD("deoptimize method: %p", reflected_method);
|
LOGD("deoptimizing method: %p", reflected_method);
|
||||||
(*deoptMethod)(instru_, reflected_method);
|
(*deoptMethod)(class_linker_, reflected_method);
|
||||||
deoptedMethods.push_back(reflected_method);
|
deoptedMethods.push_back(reflected_method);
|
||||||
LOGD("deoptimize method done: %p");
|
LOGD("method deoptimized: %p", reflected_method);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hookRuntime(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) {
|
void hookRuntime(int api_level, void *artHandle, void (*hookFun)(void *, void *, void **)) {
|
||||||
|
|
@ -249,7 +252,6 @@ void getSuspendSyms(int api_level, void *artHandle, void (*hookFun)(void *, void
|
||||||
LOGI("heapPreFork hooked.");
|
LOGI("heapPreFork hooked.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api_level >= ANDROID_N) {
|
if (api_level >= ANDROID_N) {
|
||||||
suspendAll = reinterpret_cast<void (*)(ScopedSuspendAll *, const char *, bool)>(dlsym(
|
suspendAll = reinterpret_cast<void (*)(ScopedSuspendAll *, const char *, bool)>(dlsym(
|
||||||
artHandle,
|
artHandle,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue