mirror of
https://github.com/LSPosed/LSPlant.git
synced 2025-05-05 22:16:37 +08:00
Avoid using too much java debuggable guard
This commit is contained in:
parent
899766f2bd
commit
a29f3e81a4
@ -85,8 +85,8 @@ jmethodID class_get_name = nullptr;
|
|||||||
jmethodID class_get_class_loader = nullptr;
|
jmethodID class_get_class_loader = nullptr;
|
||||||
jmethodID class_get_declared_constructors = nullptr;
|
jmethodID class_get_declared_constructors = nullptr;
|
||||||
jfieldID class_access_flags = nullptr;
|
jfieldID class_access_flags = nullptr;
|
||||||
jclass in_memory_class_loader = nullptr;
|
jmethodID dex_file_init_with_cl = nullptr;
|
||||||
jmethodID in_memory_class_loader_init = nullptr;
|
jmethodID dex_file_init = nullptr;
|
||||||
jmethodID load_class = nullptr;
|
jmethodID load_class = nullptr;
|
||||||
jmethodID set_accessible = nullptr;
|
jmethodID set_accessible = nullptr;
|
||||||
jclass executable = nullptr;
|
jclass executable = nullptr;
|
||||||
@ -95,13 +95,12 @@ jclass executable = nullptr;
|
|||||||
jmethodID method_get_parameter_types = nullptr;
|
jmethodID method_get_parameter_types = nullptr;
|
||||||
jmethodID method_get_return_type = nullptr;
|
jmethodID method_get_return_type = nullptr;
|
||||||
// for old platform
|
// for old platform
|
||||||
jclass path_class_loader = nullptr;
|
|
||||||
jmethodID path_class_loader_init = nullptr;
|
jmethodID path_class_loader_init = nullptr;
|
||||||
|
|
||||||
constexpr auto kInternalMethods = std::make_tuple(
|
constexpr auto kInternalMethods = std::make_tuple(
|
||||||
&method_get_name, &method_get_declaring_class, &class_get_name, &class_get_class_loader,
|
&method_get_name, &method_get_declaring_class, &class_get_name, &class_get_class_loader,
|
||||||
&class_get_declared_constructors, &in_memory_class_loader_init, &load_class, &set_accessible,
|
&class_get_declared_constructors, &dex_file_init, &dex_file_init_with_cl, &load_class,
|
||||||
&method_get_parameter_types, &method_get_return_type, &path_class_loader_init);
|
&set_accessible, &method_get_parameter_types, &method_get_return_type, &path_class_loader_init);
|
||||||
|
|
||||||
std::string generated_class_name;
|
std::string generated_class_name;
|
||||||
std::string generated_source_name;
|
std::string generated_source_name;
|
||||||
@ -194,32 +193,37 @@ bool InitJNI(JNIEnv *env) {
|
|||||||
LOGE("Failed to find Class.accessFlags");
|
LOGE("Failed to find Class.accessFlags");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (sdk_int >= __ANDROID_API_O__ &&
|
auto path_class_loader = JNI_FindClass(env, "dalvik/system/PathClassLoader");
|
||||||
(in_memory_class_loader = JNI_NewGlobalRef(
|
if (!path_class_loader) {
|
||||||
env, JNI_FindClass(env, "dalvik/system/InMemoryDexClassLoader")))) [[likely]] {
|
LOGE("Failed to find PathClassLoader");
|
||||||
in_memory_class_loader_init =
|
return false;
|
||||||
JNI_GetMethodID(env, in_memory_class_loader, "<init>",
|
|
||||||
"(Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
|
|
||||||
load_class = JNI_GetMethodID(env, in_memory_class_loader, "loadClass",
|
|
||||||
"(Ljava/lang/String;)Ljava/lang/Class;");
|
|
||||||
if (!load_class) {
|
|
||||||
load_class = JNI_GetMethodID(env, in_memory_class_loader, "findClass",
|
|
||||||
"(Ljava/lang/String;)Ljava/lang/Class;");
|
|
||||||
}
|
|
||||||
} else if (auto dex_file = JNI_FindClass(env, "dalvik/system/DexFile");
|
|
||||||
dex_file && (path_class_loader = JNI_NewGlobalRef(
|
|
||||||
env, JNI_FindClass(env, "dalvik/system/PathClassLoader")))) {
|
|
||||||
path_class_loader_init = JNI_GetMethodID(env, path_class_loader, "<init>",
|
|
||||||
"(Ljava/lang/String;Ljava/lang/ClassLoader;)V");
|
|
||||||
if (!path_class_loader_init) {
|
|
||||||
LOGE("Failed to find PathClassLoader.<init>");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
load_class =
|
|
||||||
JNI_GetMethodID(env, dex_file, "loadClass",
|
|
||||||
"(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;");
|
|
||||||
}
|
}
|
||||||
if (!load_class) {
|
if (path_class_loader_init = JNI_GetMethodID(env, path_class_loader, "<init>",
|
||||||
|
"(Ljava/lang/String;Ljava/lang/ClassLoader;)V");
|
||||||
|
!path_class_loader_init) {
|
||||||
|
LOGE("Failed to find PathClassLoader.<init>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto dex_file_class = JNI_FindClass(env, "dalvik/system/DexFile");
|
||||||
|
if (!dex_file_class) {
|
||||||
|
LOGE("Failed to find DexFile");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (sdk_int >= __ANDROID_API_Q__) {
|
||||||
|
dex_file_init_with_cl = JNI_GetMethodID(
|
||||||
|
env, dex_file_class, "<init>",
|
||||||
|
"([Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)V");
|
||||||
|
} else if (sdk_int >= __ANDROID_API_O__) {
|
||||||
|
dex_file_init = JNI_GetMethodID(env, dex_file_class, "<init>", "(Ljava/nio/ByteBuffer;)V");
|
||||||
|
}
|
||||||
|
if (sdk_int >= __ANDROID_API_O__ && !dex_file_init_with_cl && !dex_file_init) {
|
||||||
|
LOGE("Failed to find DexFile.<init>");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (load_class =
|
||||||
|
JNI_GetMethodID(env, dex_file_class, "loadClass",
|
||||||
|
"(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;");
|
||||||
|
!load_class) {
|
||||||
LOGE("Failed to find a suitable way to load class");
|
LOGE("Failed to find a suitable way to load class");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -370,7 +374,6 @@ std::tuple<jclass, jfieldID, jmethodID, jmethodID> BuildDex(JNIEnv *env, jobject
|
|||||||
|
|
||||||
auto parameter_types = std::vector<TypeDescriptor>();
|
auto parameter_types = std::vector<TypeDescriptor>();
|
||||||
parameter_types.reserve(shorty.size() - 1);
|
parameter_types.reserve(shorty.size() - 1);
|
||||||
std::string storage;
|
|
||||||
auto return_type =
|
auto return_type =
|
||||||
shorty[0] == 'L' ? TypeDescriptor::Object : TypeDescriptor::FromDescriptor(shorty[0]);
|
shorty[0] == 'L' ? TypeDescriptor::Object : TypeDescriptor::FromDescriptor(shorty[0]);
|
||||||
if (!is_static) parameter_types.push_back(TypeDescriptor::Object); // this object
|
if (!is_static) parameter_types.push_back(TypeDescriptor::Object); // this object
|
||||||
@ -447,21 +450,19 @@ std::tuple<jclass, jfieldID, jmethodID, jmethodID> BuildDex(JNIEnv *env, jobject
|
|||||||
|
|
||||||
jclass target_class = nullptr;
|
jclass target_class = nullptr;
|
||||||
|
|
||||||
if (in_memory_class_loader_init) [[likely]] {
|
ScopedLocalRef<jobject> java_dex_file{nullptr};
|
||||||
auto dex_buffer = JNI_NewDirectByteBuffer(env, const_cast<void *>(image.ptr()),
|
|
||||||
static_cast<jlong>(image.size()));
|
|
||||||
// FIXME: a very hacky way to disable background verification of the hooker classloader,
|
|
||||||
// which fixes a crash for art 34+; there should be a better way to do this.
|
|
||||||
JavaDebuggableGuard guard;
|
|
||||||
|
|
||||||
auto my_cl = JNI_NewObject(env, in_memory_class_loader, in_memory_class_loader_init,
|
if (auto dex_file_class = JNI_FindClass(env, "dalvik/system/DexFile"); dex_file_init_with_cl) {
|
||||||
dex_buffer, class_loader);
|
java_dex_file = JNI_NewObject(
|
||||||
if (my_cl) {
|
env, dex_file_class, dex_file_init_with_cl,
|
||||||
target_class = JNI_Cast<jclass>(JNI_CallObjectMethod(
|
JNI_NewObjectArray(
|
||||||
env, my_cl, load_class,
|
env, 1, JNI_FindClass(env, "java/nio/ByteBuffer"),
|
||||||
JNI_NewStringUTF(env, generated_class_name.data())))
|
JNI_NewDirectByteBuffer(env, const_cast<void *>(image.ptr()), image.size())),
|
||||||
.release();
|
nullptr, nullptr);
|
||||||
}
|
} else if (dex_file_init) {
|
||||||
|
java_dex_file = JNI_NewObject(
|
||||||
|
env, dex_file_class, dex_file_init,
|
||||||
|
JNI_NewDirectByteBuffer(env, const_cast<void *>(image.ptr()), image.size()));
|
||||||
} else {
|
} else {
|
||||||
void *target =
|
void *target =
|
||||||
mmap(nullptr, image.size(), PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
mmap(nullptr, image.size(), PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||||
@ -473,17 +474,20 @@ std::tuple<jclass, jfieldID, jmethodID, jmethodID> BuildDex(JNIEnv *env, jobject
|
|||||||
&err_msg);
|
&err_msg);
|
||||||
if (!dex) {
|
if (!dex) {
|
||||||
LOGE("Failed to open memory dex: %s", err_msg.data());
|
LOGE("Failed to open memory dex: %s", err_msg.data());
|
||||||
|
} else {
|
||||||
|
java_dex_file = WrapScope(env, dex ? dex->ToJavaDexFile(env) : jobject{nullptr});
|
||||||
}
|
}
|
||||||
auto java_dex_file = WrapScope(env, dex ? dex->ToJavaDexFile(env) : jobject{nullptr});
|
}
|
||||||
if (dex && java_dex_file) {
|
|
||||||
auto my_cl = JNI_NewObject(env, path_class_loader, path_class_loader_init,
|
if (auto path_class_loader = JNI_FindClass(env, "dalvik/system/PathClassLoader");
|
||||||
JNI_NewStringUTF(env, ""), class_loader);
|
java_dex_file) {
|
||||||
target_class =
|
auto my_cl = JNI_NewObject(env, path_class_loader, path_class_loader_init,
|
||||||
JNI_Cast<jclass>(
|
JNI_NewStringUTF(env, ""), class_loader);
|
||||||
JNI_CallObjectMethod(env, java_dex_file, load_class,
|
target_class =
|
||||||
JNI_NewStringUTF(env, generated_class_name.data()), my_cl))
|
JNI_Cast<jclass>(
|
||||||
.release();
|
JNI_CallObjectMethod(env, java_dex_file, load_class,
|
||||||
}
|
JNI_NewStringUTF(env, generated_class_name.data()), my_cl))
|
||||||
|
.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_class) {
|
if (target_class) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user