diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/Main.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/Main.java index 31bdc641..bb5c0c35 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/Main.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/Main.java @@ -123,6 +123,11 @@ public class Main implements KeepAll { return edxpImplRef.get(); } + @EdxpImpl.Variant + public static synchronized int getEdxpVariant() { + return getEdxpImpl().getVariant(); + } + private static void loadEdxpImpls() { AccessController.doPrivileged(new PrivilegedAction() { public Void run() { @@ -133,7 +138,7 @@ public class Main implements KeepAll { iterator.next(); } } catch (Throwable t) { - // Do nothing + Utils.logE("error when loadEdxpImpls", t); } return null; } diff --git a/edxp-core/build.gradle b/edxp-core/build.gradle index f2adc708..8818ada5 100644 --- a/edxp-core/build.gradle +++ b/edxp-core/build.gradle @@ -3,10 +3,10 @@ import org.gradle.internal.os.OperatingSystem apply plugin: 'com.android.library' -version "v0.4.4.0_alpha" +version "v0.4.4.1_alpha" ext { - versionCode = "4400" + versionCode = "4410" module_name = "EdXposed" jar_dest_dir = "${projectDir}/template_override/system/framework/" is_windows = OperatingSystem.current().isWindows() diff --git a/edxp-core/src/main/cpp/main/include/JNIHelper.h b/edxp-core/src/main/cpp/main/include/JNIHelper.h index a28708a0..d3dab8a2 100644 --- a/edxp-core/src/main/cpp/main/include/JNIHelper.h +++ b/edxp-core/src/main/cpp/main/include/JNIHelper.h @@ -85,7 +85,11 @@ ALWAYS_INLINE static int ClearException(JNIEnv *env) { #define JNI_CallStaticObjectMethod(env, obj, ...) \ env->CallStaticObjectMethod(obj, __VA_ARGS__); \ - if (ClearException(env)) LOGE("CallStaticVoidMethod " #obj " " #__VA_ARGS__); + if (ClearException(env)) LOGE("CallStaticObjectMethod " #obj " " #__VA_ARGS__); + +#define JNI_CallStaticIntMethod(env, obj, ...) \ + env->CallStaticIntMethod(obj, __VA_ARGS__); \ + if (ClearException(env)) LOGE("CallStaticIntMethod " #obj " " #__VA_ARGS__); #define JNI_GetArrayLength(env, array) \ env->GetArrayLength(array); \ diff --git a/edxp-core/src/main/cpp/main/include/art/runtime/jni_env_ext.h b/edxp-core/src/main/cpp/main/include/art/runtime/jni_env_ext.h index 1f34f6cf..015122dd 100644 --- a/edxp-core/src/main/cpp/main/include/art/runtime/jni_env_ext.h +++ b/edxp-core/src/main/cpp/main/include/art/runtime/jni_env_ext.h @@ -13,16 +13,25 @@ namespace art { return NewLocalRefSym(env, mirror_ptr); } + CREATE_FUNC_SYMBOL_ENTRY(void, DeleteLocalRef, void *env, jobject obj) { + DeleteLocalRefSym(env, obj); + } + public: JNIEnvExt(void *thiz) : HookedObject(thiz) {} static void Setup(void *handle, HookFunType hook_func) { RETRIEVE_FUNC_SYMBOL(NewLocalRef, "_ZN3art9JNIEnvExt11NewLocalRefEPNS_6mirror6ObjectE"); + RETRIEVE_FUNC_SYMBOL(DeleteLocalRef, "_ZN3art9JNIEnvExt14DeleteLocalRefEP8_jobject"); } jobject NewLocalRefer(void *mirror_ptr) { return NewLocalRef(thiz_, mirror_ptr); } + + void DeleteLocalRef(jobject obj) { + DeleteLocalRef(thiz_, obj); + } }; diff --git a/edxp-core/src/main/cpp/main/src/edxp_context.cpp b/edxp-core/src/main/cpp/main/src/edxp_context.cpp index de15cf73..831d8d8c 100644 --- a/edxp-core/src/main/cpp/main/src/edxp_context.cpp +++ b/edxp-core/src/main/cpp/main/src/edxp_context.cpp @@ -33,13 +33,14 @@ namespace edxp { } void Context::CallOnPostFixupStaticTrampolines(void *class_ptr) { - if (post_fixup_static_mid_ != nullptr) { - JNIEnv *env; - vm_->GetEnv((void **) (&env), JNI_VERSION_1_4); - art::JNIEnvExt env_ext(env); - jobject clazz = env_ext.NewLocalRefer(class_ptr); - JNI_CallStaticVoidMethod(env, class_linker_class_, post_fixup_static_mid_, clazz); + if (UNLIKELY(!post_fixup_static_mid_ || !class_linker_class_)) { + return; } + JNIEnv *env; + vm_->GetEnv((void **) (&env), JNI_VERSION_1_4); + art::JNIEnvExt env_ext(env); + ScopedLocalRef clazz(env, env_ext.NewLocalRefer(class_ptr)); + JNI_CallStaticVoidMethod(env, class_linker_class_, post_fixup_static_mid_, clazz.get()); } void Context::LoadDexAndInit(JNIEnv *env, const char *dex_path) { @@ -60,12 +61,22 @@ namespace edxp { "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V"); jobject my_cl = JNI_NewObject(env, path_classloader, initMid, env->NewStringUTF(dex_path), nullptr, sys_classloader); - if (UNLIKELY(!my_cl)) { + + env->DeleteLocalRef(classloader); + env->DeleteLocalRef(sys_classloader); + env->DeleteLocalRef(path_classloader); + + if (UNLIKELY(my_cl == nullptr)) { LOG(ERROR) << "PathClassLoader creation failed!!!"; return; } + + // TODO clear up all these global refs if blacklisted? + inject_class_loader_ = env->NewGlobalRef(my_cl); + env->DeleteLocalRef(my_cl); + // initialize pending methods related env->GetJavaVM(&vm_); class_linker_class_ = (jclass) env->NewGlobalRef( @@ -84,22 +95,36 @@ namespace edxp { RegisterArtHeap(env); RegisterEdxpYahfa(env); + // must call entry class's methods after all native methods registered + if (LIKELY(entry_class_)) { + jmethodID get_variant_mid = JNI_GetStaticMethodID(env, entry_class_, + "getEdxpVariant", "()I"); + if (LIKELY(get_variant_mid)) { + int variant = JNI_CallStaticIntMethod(env, entry_class_, get_variant_mid); + variant_ = static_cast(variant); + } + } + initialized_ = true; - //for SandHook variant - ScopedDlHandle sandhook_handle(kLibSandHookPath.c_str()); - if (!sandhook_handle.IsValid()) { - return; - } - typedef bool *(*TYPE_JNI_LOAD)(JNIEnv *, jclass, jclass); - auto jni_load = sandhook_handle.DlSym("JNI_Load_Ex"); - jclass sandhook_class = FindClassFromLoader(env, kSandHookClassName); - jclass nevercall_class = FindClassFromLoader(env, kSandHookNeverCallClassName); - if (!sandhook_class || !nevercall_class) { // fail-fast - return; - } - if (!jni_load(env, sandhook_class, nevercall_class)) { - LOGE("SandHook: HookEntry class error. %d", getpid()); + if (variant_ == SANDHOOK) { + //for SandHook variant + ScopedDlHandle sandhook_handle(kLibSandHookPath.c_str()); + if (!sandhook_handle.IsValid()) { + return; + } + typedef bool *(*TYPE_JNI_LOAD)(JNIEnv *, jclass, jclass); + auto jni_load = sandhook_handle.DlSym("JNI_Load_Ex"); + ScopedLocalRef sandhook_class(env, FindClassFromLoader(env, kSandHookClassName)); + ScopedLocalRef nevercall_class(env, + FindClassFromLoader(env, kSandHookNeverCallClassName)); + if (sandhook_class == nullptr || nevercall_class == nullptr) { // fail-fast + return; + } + if (!jni_load(env, sandhook_class.get(), nevercall_class.get())) { + LOGE("SandHook: HookEntry class error. %d", getpid()); + } + } } @@ -136,7 +161,7 @@ namespace edxp { inline void Context::FindAndCall(JNIEnv *env, const char *method_name, const char *method_sig, ...) const { - if (!entry_class_) { + if (UNLIKELY(!entry_class_)) { LOGE("cannot call method %s, entry class is null", method_name); return; } @@ -235,8 +260,7 @@ namespace edxp { if (res == 0) { PrepareJavaEnv(env); FindAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;Ljava/lang/String;)V", - res, - app_data_dir_, nice_name_); + res, app_data_dir_, nice_name_); } else { // in zygote process, res is child zygote pid // don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66 diff --git a/edxp-core/src/main/cpp/main/src/edxp_context.h b/edxp-core/src/main/cpp/main/src/edxp_context.h index 45369f21..135a6b93 100644 --- a/edxp-core/src/main/cpp/main/src/edxp_context.h +++ b/edxp-core/src/main/cpp/main/src/edxp_context.h @@ -8,6 +8,13 @@ namespace edxp { #define SYSTEM_SERVER_DATA_DIR "/data/user/0/android" + enum Variant { + NONE = 0, + YAHFA = 1, + SANDHOOK = 2, + WHALE = 3 + }; + class Context { public: @@ -52,6 +59,7 @@ namespace edxp { private: static Context *instance_; bool initialized_ = false; + Variant variant_ = NONE; jobject inject_class_loader_ = nullptr; jclass entry_class_ = nullptr; jstring app_data_dir_ = nullptr; diff --git a/edxp-core/src/main/cpp/main/src/native_hook.cpp b/edxp-core/src/main/cpp/main/src/native_hook.cpp index 4bcf72fc..2115af77 100644 --- a/edxp-core/src/main/cpp/main/src/native_hook.cpp +++ b/edxp-core/src/main/cpp/main/src/native_hook.cpp @@ -62,13 +62,12 @@ namespace edxp { hook_func = reinterpret_cast(hook_func_symbol); if (api_level >= ANDROID_P) { - void *handle = DlOpen(kLibDlPath.c_str()); + ScopedDlHandle dl_handle(kLibDlPath.c_str()); + void *handle = dl_handle.Get(); HOOK_FUNC(mydlopen, "__loader_dlopen"); - dlclose(handle); } else { - void *art_handle = DlOpen(kLibArtPath.c_str()); - InstallArtHooks(art_handle); - dlclose(art_handle); + ScopedDlHandle art_handle(kLibArtPath.c_str()); + InstallArtHooks(art_handle.Get()); } } diff --git a/edxp-core/template_override/common/util_functions.sh b/edxp-core/template_override/common/util_functions.sh index 6ed34e9c..f6795fd5 100644 --- a/edxp-core/template_override/common/util_functions.sh +++ b/edxp-core/template_override/common/util_functions.sh @@ -1,6 +1,6 @@ #!/system/bin/sh -EDXP_VERSION="0.4.4.0_alpha (4400)" +EDXP_VERSION="0.4.4.1_alpha (4410)" ANDROID_SDK=`getprop ro.build.version.sdk` BUILD_DESC=`getprop ro.build.description` PRODUCT=`getprop ro.build.product`