From 3d863cb4c25a39d6787480a2c829aaee35203cf6 Mon Sep 17 00:00:00 2001 From: solohsu Date: Thu, 13 Jun 2019 18:16:54 +0800 Subject: [PATCH] Add support for Android Q (API Level 29) --- .../elderdrivers/riru/edxp/util/Utils.java | 11 ++- edxp-core/build.gradle | 4 +- .../main/cpp/external/yahfa/src/HookMain.c | 1 + .../src/main/cpp/external/yahfa/src/env.h | 1 + .../main/include/art/runtime/class_linker.h | 6 +- .../cpp/main/include/art/runtime/hidden_api.h | 32 +++++++-- edxp-core/src/main/cpp/main/include/config.h | 29 ++++---- .../src/main/cpp/main/src/edxp_context.cpp | 7 +- edxp-core/src/main/cpp/main/src/main.cpp | 71 +++++++++---------- .../src/main/cpp/main/src/native_hook.cpp | 46 +++++++++--- .../common/util_functions.sh | 2 +- 11 files changed, 133 insertions(+), 77 deletions(-) diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/util/Utils.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/util/Utils.java index 7cfe7965..4f0e7b24 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/util/Utils.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/util/Utils.java @@ -46,7 +46,14 @@ public class Utils { } public static String getSysProp(String key) { - Class sysProps = XposedHelpers.findClassIfExists("android.os.SystemProperties", null); - return (String) XposedHelpers.callStaticMethod(sysProps, "get", key); + try { + Class sysProps = XposedHelpers.findClassIfExists("android.os.SystemProperties", null); + if (sysProps != null) { + return (String) XposedHelpers.callStaticMethod(sysProps, "get", key); + } + } catch (Throwable throwable) { + Utils.logE("error when get sys prop", throwable); + } + return ""; } } diff --git a/edxp-core/build.gradle b/edxp-core/build.gradle index dfd67fa9..f2adc708 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.3.7_alpha" +version "v0.4.4.0_alpha" ext { - versionCode = "4370" + versionCode = "4400" module_name = "EdXposed" jar_dest_dir = "${projectDir}/template_override/system/framework/" is_windows = OperatingSystem.current().isWindows() diff --git a/edxp-core/src/main/cpp/external/yahfa/src/HookMain.c b/edxp-core/src/main/cpp/external/yahfa/src/HookMain.c index c15a5687..8cad76f1 100644 --- a/edxp-core/src/main/cpp/external/yahfa/src/HookMain.c +++ b/edxp-core/src/main/cpp/external/yahfa/src/HookMain.c @@ -37,6 +37,7 @@ void Java_lab_galaxy_yahfa_HookMain_init(JNIEnv *env, jclass clazz, jint sdkVers SDKVersion = sdkVersion; LOGI("init to SDK %d", sdkVersion); switch (sdkVersion) { + case ANDROID_Q: case ANDROID_P: kAccCompileDontBother = 0x02000000; OFFSET_ArtMehod_in_Object = 0; diff --git a/edxp-core/src/main/cpp/external/yahfa/src/env.h b/edxp-core/src/main/cpp/external/yahfa/src/env.h index 105c4586..026f20ed 100644 --- a/edxp-core/src/main/cpp/external/yahfa/src/env.h +++ b/edxp-core/src/main/cpp/external/yahfa/src/env.h @@ -13,6 +13,7 @@ #define ANDROID_O 26 #define ANDROID_O2 27 #define ANDROID_P 28 +#define ANDROID_Q 29 #define roundUpTo4(v) ((v+4-1) - ((v+4-1)&3)) #define roundUpTo8(v) ((v+8-1) - ((v+8-1)&7)) diff --git a/edxp-core/src/main/cpp/main/include/art/runtime/class_linker.h b/edxp-core/src/main/cpp/main/include/art/runtime/class_linker.h index 816d8518..6f1749a6 100644 --- a/edxp-core/src/main/cpp/main/include/art/runtime/class_linker.h +++ b/edxp-core/src/main/cpp/main/include/art/runtime/class_linker.h @@ -40,11 +40,13 @@ namespace art { } static void Setup(void *handle, HookFunType hook_func) { - HOOK_FUNC(Constructor, "_ZN3art11ClassLinkerC2EPNS_11InternTableE"); + HOOK_FUNC(Constructor, "_ZN3art11ClassLinkerC2EPNS_11InternTableE", + "_ZN3art11ClassLinkerC2EPNS_11InternTableEb"); // 10.0 RETRIEVE_FUNC_SYMBOL(SetEntryPointsToInterpreter, "_ZNK3art11ClassLinker27SetEntryPointsToInterpreterEPNS_9ArtMethodE"); - HOOK_FUNC(FixupStaticTrampolines, "_ZN3art11ClassLinker22FixupStaticTrampolinesENS_6ObjPtrINS_6mirror5ClassEEE"); + HOOK_FUNC(FixupStaticTrampolines, + "_ZN3art11ClassLinker22FixupStaticTrampolinesENS_6ObjPtrINS_6mirror5ClassEEE"); } ALWAYS_INLINE void SetEntryPointsToInterpreter(void *art_method) const { diff --git a/edxp-core/src/main/cpp/main/include/art/runtime/hidden_api.h b/edxp-core/src/main/cpp/main/include/art/runtime/hidden_api.h index ae6eddbf..abb3d394 100644 --- a/edxp-core/src/main/cpp/main/include/art/runtime/hidden_api.h +++ b/edxp-core/src/main/cpp/main/include/art/runtime/hidden_api.h @@ -22,16 +22,34 @@ namespace art { return Action::kAllow; } + CREATE_HOOK_STUB_ENTRIES(bool, ShouldDenyAccessToMethodImpl) { + return false; + } + + CREATE_HOOK_STUB_ENTRIES(bool, ShouldDenyAccessToFieldImpl) { + return false; + } + static void DisableHiddenApi(void *handle, HookFunType hook_func) { - if (GetAndroidApiLevel() < ANDROID_P) { + const int api_level = GetAndroidApiLevel(); + if (api_level < ANDROID_P) { return; } - HOOK_FUNC(GetMethodActionImpl, - "_ZN3art9hiddenapi6detail19GetMemberActionImplINS_9ArtMethodEEENS0_" - "6ActionEPT_NS_20HiddenApiAccessFlags7ApiListES4_NS0_12AccessMethodE"); - HOOK_FUNC(GetFieldActionImpl, - "_ZN3art9hiddenapi6detail19GetMemberActionImplINS_8ArtFieldEEENS0_" - "6ActionEPT_NS_20HiddenApiAccessFlags7ApiListES4_NS0_12AccessMethodE"); + if (api_level == ANDROID_P) { + HOOK_FUNC(GetMethodActionImpl, + "_ZN3art9hiddenapi6detail19GetMemberActionImplINS_9ArtMethodEEENS0_" + "6ActionEPT_NS_20HiddenApiAccessFlags7ApiListES4_NS0_12AccessMethodE"); + HOOK_FUNC(GetFieldActionImpl, + "_ZN3art9hiddenapi6detail19GetMemberActionImplINS_8ArtFieldEEENS0_" + "6ActionEPT_NS_20HiddenApiAccessFlags7ApiListES4_NS0_12AccessMethodE"); + } else { + HOOK_FUNC(ShouldDenyAccessToMethodImpl, + "_ZN3art9hiddenapi6detail28ShouldDenyAccessToMemberImplINS_" + "9ArtMethodEEEbPT_NS0_7ApiListENS0_12AccessMethodE"); + HOOK_FUNC(ShouldDenyAccessToFieldImpl, + "_ZN3art9hiddenapi6detail28ShouldDenyAccessToMemberImplINS_" + "8ArtFieldEEEbPT_NS0_7ApiListENS0_12AccessMethodE"); + } }; } diff --git a/edxp-core/src/main/cpp/main/include/config.h b/edxp-core/src/main/cpp/main/include/config.h index f0e8cb2e..4ff0dd96 100644 --- a/edxp-core/src/main/cpp/main/include/config.h +++ b/edxp-core/src/main/cpp/main/include/config.h @@ -5,6 +5,7 @@ #include #include #include "art/base/macros.h" +#include "android_build.h" namespace edxp { @@ -17,19 +18,23 @@ namespace edxp { # define LP_SELECT(lp32, lp64) (lp32) #endif - static constexpr const char *kInjectDexPath = "/system/framework/edxp.jar:" - "/system/framework/eddalvikdx.jar:" - "/system/framework/eddexmaker.jar"; - static constexpr const char *kEntryClassName = "com.elderdrivers.riru.edxp.core.Main"; - static constexpr const char *kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker"; - static constexpr const char *kSandHookClassName = "com.swift.sandhook.SandHook"; - static constexpr const char *kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall"; + static constexpr auto kInjectDexPath = "/system/framework/edxp.jar:" + "/system/framework/eddalvikdx.jar:" + "/system/framework/eddexmaker.jar"; + static constexpr auto kEntryClassName = "com.elderdrivers.riru.edxp.core.Main"; + static constexpr auto kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker"; + static constexpr auto kSandHookClassName = "com.swift.sandhook.SandHook"; + static constexpr auto kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall"; - static const std::string kLibBasePath = LP_SELECT("/system/lib/", "/system/lib64/"); - static const std::string kLibArtPath = kLibBasePath + "libart.so"; - static const std::string kLibWhalePath = kLibBasePath + "libwhale.edxp.so"; - static const std::string kLibSandHookPath = kLibBasePath + "libsandhook.edxp.so"; - static const std::string kLibFwPath = kLibBasePath + "libandroidfw.so"; + static const auto kLibBasePath = std::string(LP_SELECT("/system/lib/", "/system/lib64/")); + static const auto kLibRuntimeBasePath = std::string(LP_SELECT("/apex/com.android.runtime/lib/", + "/apex/com.android.runtime/lib64/")); + static const auto kLibArtPath = + (GetAndroidApiLevel() >= ANDROID_Q ? kLibRuntimeBasePath : kLibBasePath) + "libart.so"; + static const auto kLibWhalePath = kLibBasePath + "libwhale.edxp.so"; + static const auto kLibSandHookPath = kLibBasePath + "libsandhook.edxp.so"; + static const auto kLibFwPath = kLibBasePath + "libandroidfw.so"; + static const auto kLibDlPath = kLibBasePath + "libdl.so"; inline const char *const BoolToString(bool b) { return b ? "true" : "false"; 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 37d6a0bc..de15cf73 100644 --- a/edxp-core/src/main/cpp/main/src/edxp_context.cpp +++ b/edxp-core/src/main/cpp/main/src/edxp_context.cpp @@ -133,6 +133,7 @@ namespace edxp { LoadDexAndInit(env, kInjectDexPath); } + inline void Context::FindAndCall(JNIEnv *env, const char *method_name, const char *method_sig, ...) const { if (!entry_class_) { @@ -209,14 +210,14 @@ namespace edxp { jobjectArray rlimits, jint mount_external, jstring se_info, - jstring se_name, + jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir) { app_data_dir_ = app_data_dir; - nice_name_ = se_name; + nice_name_ = nice_name; if (ConfigManager::GetInstance()->IsBlackWhiteListEnabled() && ConfigManager::GetInstance()->IsDynamicModulesEnabled()) { // when black/white list is on, never inject into zygote if dynamic modules mode is on @@ -226,7 +227,7 @@ namespace edxp { FindAndCall(env, "forkAndSpecializePre", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)V", uid, gid, gids, runtime_flags, rlimits, - mount_external, se_info, se_name, fds_to_close, fds_to_ignore, + mount_external, se_info, nice_name, fds_to_close, fds_to_ignore, is_child_zygote, instruction_set, app_data_dir); } diff --git a/edxp-core/src/main/cpp/main/src/main.cpp b/edxp-core/src/main/cpp/main/src/main.cpp index 66026e43..94b24eb8 100644 --- a/edxp-core/src/main/cpp/main/src/main.cpp +++ b/edxp-core/src/main/cpp/main/src/main.cpp @@ -19,67 +19,65 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" +#define EXPORT extern "C" __attribute__((visibility("default"))) + namespace edxp { - extern "C" { - - __attribute__((visibility("default"))) void onModuleLoaded() { + EXPORT void onModuleLoaded() { LOG(INFO) << "onModuleLoaded: welcome to EdXposed!"; InstallInlineHooks(); } - __attribute__((visibility("default"))) int shouldSkipUid(int uid) { + EXPORT int shouldSkipUid(int uid) { return 0; } - __attribute__((visibility("default"))) void - nativeForkAndSpecializePre(JNIEnv *env, jclass clazz, jint *_uid, jint *gid, jintArray *gids, - jint *runtime_flags, - jobjectArray *rlimits, jint *mount_external, jstring *se_info, - jstring *se_name, - jintArray *fds_to_close, jintArray *fds_to_ignore, - jboolean *is_child_zygote, - jstring *instruction_set, jstring *app_data_dir, - jstring *package_name, - jobjectArray *packages_for_uid, jstring *sandbox_id) { + EXPORT void nativeForkAndSpecializePre(JNIEnv *env, jclass clazz, jint *_uid, jint *gid, + jintArray *gids, jint *runtime_flags, + jobjectArray *rlimits, jint *mount_external, + jstring *se_info, jstring *nice_name, + jintArray *fds_to_close, jintArray *fds_to_ignore, + jboolean *start_child_zygote, jstring *instruction_set, + jstring *app_data_dir, + /* parameters added in Android Q */ + jstring *package_name, jobjectArray *packages_for_uid, + jstring *sandbox_id) { Context::GetInstance()->OnNativeForkAndSpecializePre(env, clazz, *_uid, *gid, *gids, *runtime_flags, *rlimits, - *mount_external, *se_info, *se_name, + *mount_external, *se_info, *nice_name, *fds_to_close, *fds_to_ignore, - *is_child_zygote, *instruction_set, + *start_child_zygote, *instruction_set, *app_data_dir); } - __attribute__((visibility("default"))) int - nativeForkAndSpecializePost(JNIEnv *env, jclass clazz, - jint res) { + EXPORT int nativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) { return Context::GetInstance()->OnNativeForkAndSpecializePost(env, clazz, res); } - __attribute__((visibility("default"))) - void - nativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t *uid, gid_t *gid, jintArray *gids, - jint *runtime_flags, - jobjectArray *rlimits, jlong *permitted_capabilities, - jlong *effective_capabilities) { + EXPORT void nativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t *uid, gid_t *gid, + jintArray *gids, jint *runtime_flags, + jobjectArray *rlimits, jlong *permitted_capabilities, + jlong *effective_capabilities) { Context::GetInstance()->OnNativeForkSystemServerPre(env, clazz, *uid, *gid, *gids, *runtime_flags, *rlimits, *permitted_capabilities, - *effective_capabilities); + *effective_capabilities + ); } - __attribute__((visibility("default"))) - int nativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) { + EXPORT int nativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) { return Context::GetInstance()->OnNativeForkSystemServerPost(env, clazz, res); } - __attribute__((visibility("default"))) void specializeAppProcessPre( - JNIEnv *env, jclass clazz, jint *_uid, jint *gid, jintArray *gids, jint *runtime_flags, - jobjectArray *rlimits, jint *mount_external, jstring *se_info, jstring *nice_name, - jboolean *start_child_zygote, jstring *instruction_set, jstring *app_data_dir, - jstring *package_name, jobjectArray *packages_for_uid, jstring *sandbox_id) { - Context::GetInstance()->OnNativeForkAndSpecializePre(env, clazz, *_uid, *gid, *gids, + /* method added in Android Q */ + EXPORT void specializeAppProcessPre(JNIEnv *env, jclass clazz, jint *uid, jint *gid, + jintArray *gids, jint *runtime_flags, jobjectArray *rlimits, + jint *mount_external, jstring *se_info, jstring *nice_name, + jboolean *start_child_zygote, jstring *instruction_set, + jstring *app_data_dir, jstring *package_name, + jobjectArray *packages_for_uid, jstring *sandbox_id) { + Context::GetInstance()->OnNativeForkAndSpecializePre(env, clazz, *uid, *gid, *gids, *runtime_flags, *rlimits, *mount_external, *se_info, *nice_name, nullptr, nullptr, @@ -87,13 +85,10 @@ namespace edxp { *app_data_dir); } - __attribute__((visibility("default"))) int specializeAppProcessPost( - JNIEnv *env, jclass clazz) { + EXPORT int specializeAppProcessPost(JNIEnv *env, jclass clazz) { return Context::GetInstance()->OnNativeForkAndSpecializePost(env, clazz, 0); } - } - } #pragma clang diagnostic pop \ No newline at end of file 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 a3d6d790..4bcf72fc 100644 --- a/edxp-core/src/main/cpp/main/src/native_hook.cpp +++ b/edxp-core/src/main/cpp/main/src/native_hook.cpp @@ -20,6 +20,19 @@ namespace edxp { static bool installed = false; + static bool art_hooks_installed = false; + static HookFunType hook_func = nullptr; + + void InstallArtHooks(void *art_handle); + + CREATE_HOOK_STUB_ENTRIES(void *, mydlopen, const char *file_name, int flags, + const void *caller) { + void *handle = mydlopenBackup(file_name, flags, caller); + if (std::string(file_name).find("libart.so") != std::string::npos) { + InstallArtHooks(handle); + } + return handle; + } void InstallInlineHooks() { if (installed) { @@ -46,18 +59,31 @@ namespace edxp { if (!hook_func_symbol) { return; } - auto hook_func = reinterpret_cast(hook_func_symbol); - ScopedDlHandle art_handle(kLibArtPath.c_str()); - if (!art_handle.IsValid()) { + hook_func = reinterpret_cast(hook_func_symbol); + + if (api_level >= ANDROID_P) { + void *handle = DlOpen(kLibDlPath.c_str()); + HOOK_FUNC(mydlopen, "__loader_dlopen"); + dlclose(handle); + } else { + void *art_handle = DlOpen(kLibArtPath.c_str()); + InstallArtHooks(art_handle); + dlclose(art_handle); + } + } + + void InstallArtHooks(void *art_handle) { + if (art_hooks_installed) { return; } - art::hidden_api::DisableHiddenApi(art_handle.Get(), hook_func); - art::Runtime::Setup(art_handle.Get(), hook_func); - art::gc::Heap::Setup(art_handle.Get(), hook_func); - art::ClassLinker::Setup(art_handle.Get(), hook_func); - art::mirror::Class::Setup(art_handle.Get(), hook_func); - art::JNIEnvExt::Setup(art_handle.Get(), hook_func); - LOGI("Inline hooks installed"); + art::hidden_api::DisableHiddenApi(art_handle, hook_func); + art::Runtime::Setup(art_handle, hook_func); + art::gc::Heap::Setup(art_handle, hook_func); + art::ClassLinker::Setup(art_handle, hook_func); + art::mirror::Class::Setup(art_handle, hook_func); + art::JNIEnvExt::Setup(art_handle, hook_func); + art_hooks_installed = true; + LOGI("ART hooks installed"); } } diff --git a/edxp-core/template_override/common/util_functions.sh b/edxp-core/template_override/common/util_functions.sh index 8ccd75ee..6ed34e9c 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.3.7_alpha (4370)" +EDXP_VERSION="0.4.4.0_alpha (4400)" ANDROID_SDK=`getprop ro.build.version.sdk` BUILD_DESC=`getprop ro.build.description` PRODUCT=`getprop ro.build.product`