diff --git a/edxp-core/build.gradle b/edxp-core/build.gradle index e2bc209d..030b43f0 100644 --- a/edxp-core/build.gradle +++ b/edxp-core/build.gradle @@ -43,9 +43,19 @@ ext { riruModuleId = "edxp" zipPathMagiskRelease = "$buildDir/tmp/release/magisk" - moduleMinRiruApiVersion = 9 - moduleMinRiruVersionName = "v22.0" - moduleMaxRiruApiVersion = 9 + moduleMinRiruApiVersion = 10 + moduleMinRiruVersionName = "v23.0" + moduleMaxRiruApiVersion = 10 +} + +repositories { + mavenLocal() + jcenter() + maven { url 'https://dl.bintray.com/rikkaw/Libraries' } +} + +dependencies { + implementation 'rikka.ndk:riru:10' } android { @@ -54,6 +64,10 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion + buildFeatures { + prefab true + } + externalNativeBuild { cmake { abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64' diff --git a/edxp-core/src/main/cpp/external/CMakeLists.txt b/edxp-core/src/main/cpp/external/CMakeLists.txt index 3fd40857..be39affc 100644 --- a/edxp-core/src/main/cpp/external/CMakeLists.txt +++ b/edxp-core/src/main/cpp/external/CMakeLists.txt @@ -1,7 +1,6 @@ cmake_minimum_required(VERSION 3.4.1) add_subdirectory(xhook) -add_subdirectory(riru) add_subdirectory(yahfa) add_subdirectory(android) diff --git a/edxp-core/src/main/cpp/external/riru/CMakeLists.txt b/edxp-core/src/main/cpp/external/riru/CMakeLists.txt deleted file mode 100644 index 7c9e84ef..00000000 --- a/edxp-core/src/main/cpp/external/riru/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -cmake_minimum_required(VERSION 3.4.1) - -aux_source_directory(src SRC_LIST) -add_library(riru STATIC ${SRC_LIST}) - -target_include_directories(riru INTERFACE src) \ No newline at end of file diff --git a/edxp-core/src/main/cpp/external/riru/src/riru.c b/edxp-core/src/main/cpp/external/riru/src/riru.c deleted file mode 100644 index e69de29b..00000000 diff --git a/edxp-core/src/main/cpp/external/riru/src/riru.h b/edxp-core/src/main/cpp/external/riru/src/riru.h deleted file mode 100644 index caaaed32..00000000 --- a/edxp-core/src/main/cpp/external/riru/src/riru.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef RIRU_H -#define RIRU_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -// --------------------------------------------------------- - -typedef void(onModuleLoaded_v9)(); - -typedef int(shouldSkipUid_v9)(int uid); - -typedef void(nativeForkAndSpecializePre_v9)( - JNIEnv *env, jclass cls, jint *uid, jint *gid, jintArray *gids, jint *runtimeFlags, - jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName, - jintArray *fdsToClose, jintArray *fdsToIgnore, jboolean *is_child_zygote, - jstring *instructionSet, jstring *appDataDir, jboolean *isTopApp, jobjectArray *pkgDataInfoList, - jobjectArray *whitelistedDataInfoList, jboolean *bindMountAppDataDirs, jboolean *bindMountAppStorageDirs); - -typedef void(nativeForkAndSpecializePost_v9)(JNIEnv *env, jclass cls, jint res); - -typedef void(nativeForkSystemServerPre_v9)( - JNIEnv *env, jclass cls, uid_t *uid, gid_t *gid, jintArray *gids, jint *runtimeFlags, - jobjectArray *rlimits, jlong *permittedCapabilities, jlong *effectiveCapabilities); - -typedef void(nativeForkSystemServerPost_v9)(JNIEnv *env, jclass cls, jint res); - -typedef void(nativeSpecializeAppProcessPre_v9)( - JNIEnv *env, jclass cls, jint *uid, jint *gid, jintArray *gids, jint *runtimeFlags, - jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName, - jboolean *startChildZygote, jstring *instructionSet, jstring *appDataDir, - jboolean *isTopApp, jobjectArray *pkgDataInfoList, jobjectArray *whitelistedDataInfoList, - jboolean *bindMountAppDataDirs, jboolean *bindMountAppStorageDirs); - -typedef void(nativeSpecializeAppProcessPost_v9)(JNIEnv *env, jclass cls); - -typedef struct { - int supportHide; - int version; - const char *versionName; - onModuleLoaded_v9 *onModuleLoaded; - shouldSkipUid_v9 *shouldSkipUid; - nativeForkAndSpecializePre_v9 *forkAndSpecializePre; - nativeForkAndSpecializePost_v9 *forkAndSpecializePost; - nativeForkSystemServerPre_v9 *forkSystemServerPre; - nativeForkSystemServerPost_v9 *forkSystemServerPost; - nativeSpecializeAppProcessPre_v9 *specializeAppProcessPre; - nativeSpecializeAppProcessPost_v9 *specializeAppProcessPost; -} RiruModuleInfoV9; - -// --------------------------------------------------------- - -typedef void *(RiruGetFunc_v9)(uint32_t token, const char *name); - -typedef void (RiruSetFunc_v9)(uint32_t token, const char *name, void *func); - -typedef void *(RiruGetJNINativeMethodFunc_v9)(uint32_t token, const char *className, const char *name, const char *signature); - -typedef void (RiruSetJNINativeMethodFunc_v9)(uint32_t token, const char *className, const char *name, const char *signature, void *func); - -typedef const JNINativeMethod *(RiruGetOriginalJNINativeMethodFunc_v9)(const char *className, const char *name, const char *signature); - -typedef void *(RiruGetGlobalValue_v9)(const char *key); - -typedef void(RiruPutGlobalValue_v9)(const char *key, void *value); - -typedef struct { - - uint32_t token; - RiruGetFunc_v9 *getFunc; - RiruGetJNINativeMethodFunc_v9 *getJNINativeMethodFunc; - RiruSetFunc_v9 *setFunc; - RiruSetJNINativeMethodFunc_v9 *setJNINativeMethodFunc; - RiruGetOriginalJNINativeMethodFunc_v9 *getOriginalJNINativeMethodFunc; - RiruGetGlobalValue_v9 *getGlobalValue; - RiruPutGlobalValue_v9 *putGlobalValue; -} RiruApiV9; - -typedef void *(RiruInit_t)(void *); - -#ifdef RIRU_MODULE -#define RIRU_EXPORT __attribute__((visibility("default"))) __attribute__((used)) - -/* - * Init will be called three times. - * - * The first time: - * Returns the highest version number supported by both Riru and the module. - * - * arg: (int *) Riru's API version - * returns: (int *) the highest possible API version - * - * The second time: - * Returns the RiruModuleX struct created by the module (X is the return of the first call). - * - * arg: (RiruApiVX *) RiruApi strcut, this pointer can be saved for further use - * returns: (RiruModuleX *) RiruModule strcut - * - * The second time: - * Let the module to cleanup (such as RiruModuleX struct created before). - * - * arg: null - * returns: (ignored) - * - */ -void* init(void *arg) RIRU_EXPORT; - -extern int riru_api_version; -extern RiruApiV9 *riru_api_v9; - -inline void *riru_get_func(const char *name) { - if (riru_api_version == 9) { - return riru_api_v9->getFunc(riru_api_v9->token, name); - } - return NULL; -} - -inline void *riru_get_native_method_func(const char *className, const char *name, const char *signature) { - if (riru_api_version == 9) { - return riru_api_v9->getJNINativeMethodFunc(riru_api_v9->token, className, name, signature); - } - return NULL; -} - -inline const JNINativeMethod *riru_get_original_native_methods(const char *className, const char *name, const char *signature) { - if (riru_api_version == 9) { - return riru_api_v9->getOriginalJNINativeMethodFunc(className, name, signature); - } - return NULL; -} - -inline void riru_set_func(const char *name, void *func) { - if (riru_api_version == 9) { - riru_api_v9->setFunc(riru_api_v9->token, name, func); - } -} - -inline void riru_set_native_method_func(const char *className, const char *name, const char *signature, - void *func) { - if (riru_api_version == 9) { - riru_api_v9->setJNINativeMethodFunc(riru_api_v9->token, className, name, signature, func); - } -} - -inline void *riru_get_global_value(const char *key) { - if (riru_api_version == 9) { - return riru_api_v9->getGlobalValue(key); - } - return NULL; -} - -inline void riru_put_global_value(const char *key, void *value) { - if (riru_api_version == 9) { - riru_api_v9->putGlobalValue(key, value); - } -} - -#endif - -#ifdef __cplusplus -} -#endif - -#endif //RIRU_H \ No newline at end of file diff --git a/edxp-core/src/main/cpp/main/CMakeLists.txt b/edxp-core/src/main/cpp/main/CMakeLists.txt index 971a3562..23c71d45 100644 --- a/edxp-core/src/main/cpp/main/CMakeLists.txt +++ b/edxp-core/src/main/cpp/main/CMakeLists.txt @@ -7,5 +7,6 @@ aux_source_directory(src/jni SRC_JNI_LIST) include_directories(include src) add_library(riru_edxp SHARED ${SRC_LIST} ${SRC_JNI_LIST}) +find_package(riru REQUIRED CONFIG) find_library(log-lib log) -target_link_libraries(riru_edxp yahfa riru xhook android dobby ${log-lib}) \ No newline at end of file +target_link_libraries(riru_edxp yahfa riru::riru xhook android dobby ${log-lib}) \ No newline at end of file diff --git a/edxp-core/src/main/cpp/main/src/config_manager.cpp b/edxp-core/src/main/cpp/main/src/config_manager.cpp index aff556ff..4691dbd1 100644 --- a/edxp-core/src/main/cpp/main/src/config_manager.cpp +++ b/edxp-core/src/main/cpp/main/src/config_manager.cpp @@ -19,6 +19,7 @@ #include "art/runtime/native/native_util.h" #include "config_manager.h" #include "utils.h" +#include "rirud_socket.h" /* * Logic: @@ -79,22 +80,23 @@ * of the conf on its own data dir) * */ + namespace edxp { namespace fs = std::filesystem; fs::path ConfigManager::RetrieveBaseConfigPath() const { fs::path misc_path("/data/adb/edxp/misc_path"); - if (path_exists(misc_path)) { - std::ifstream ifs(misc_path); - if (ifs.good()) { - return fs::path("/data/misc") / - std::string{std::istream_iterator(ifs), - std::istream_iterator()} / - std::to_string(user_); - } + try { + RirudSocket rirud_socket{}; + auto path = rirud_socket.ReadFile(misc_path); + path.erase(std::find_if(path.rbegin(), path.rend(), [](unsigned char ch) { + return !std::isspace(ch); + }).base(), path.end()); + return fs::path("/data/misc") / path / std::to_string(user_); + } catch (const RirudSocket::RirudSocketException &e) { + LOGE("%s", e.what()); + return {}; } - LOGW("fallback because %s is not accessible", misc_path.c_str()); - return data_path_prefix_ / kPrimaryInstallerPkgName; } std::string ConfigManager::RetrieveInstallerPkgName() const { @@ -257,7 +259,7 @@ namespace edxp { } bool ConfigManager::InitConfigPath() const { - if (base_config_path_.string().rfind("/data/misc") != 0) return true; + if (base_config_path_.empty()) return false; try { fs::create_directories(base_config_path_); fs::permissions(base_config_path_.parent_path(), diff --git a/edxp-core/src/main/cpp/main/src/main.cpp b/edxp-core/src/main/cpp/main/src/main.cpp index 0eab6f46..df423d87 100644 --- a/edxp-core/src/main/cpp/main/src/main.cpp +++ b/edxp-core/src/main/cpp/main/src/main.cpp @@ -14,7 +14,7 @@ #include "logging.h" #include "config.h" #include "edxp_context.h" -#include "riru.h" +#include #include "config_manager.h" #include "native_hook.h" @@ -90,7 +90,7 @@ namespace edxp { } int riru_api_version; -RiruApiV9 *riru_api_v9; +RiruApiV10 *riru_api_v10; RIRU_EXPORT void *init(void *arg) { static int step = 0; @@ -106,11 +106,13 @@ RIRU_EXPORT void *init(void *arg) { } case 2: { switch (riru_api_version) { + case 10: + [[fallthrough]]; case 9: { - riru_api_v9 = (RiruApiV9 *) arg; + riru_api_v10 = (RiruApiV10 *) arg; - auto module = (RiruModuleInfoV9 *) malloc(sizeof(RiruModuleInfoV9)); - memset(module, 0, sizeof(RiruModuleInfoV9)); + auto module = (RiruModuleInfoV10 *) malloc(sizeof(RiruModuleInfoV10)); + memset(module, 0, sizeof(RiruModuleInfoV10)); _module = module; module->supportHide = true; diff --git a/edxp-core/src/main/cpp/main/src/rirud_socket.cpp b/edxp-core/src/main/cpp/main/src/rirud_socket.cpp new file mode 100644 index 00000000..e030ea1b --- /dev/null +++ b/edxp-core/src/main/cpp/main/src/rirud_socket.cpp @@ -0,0 +1,105 @@ +// +// Created by loves on 12/2/2020. +// + +#include "rirud_socket.h" +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; + +template<> +void RirudSocket::Write(const std::string &str) { + auto count = str.size(); + auto *buf = str.data(); + Write(buf, count); +} + +template +void RirudSocket::Write(const T &obj) { + auto len = sizeof(T); + auto *buf = &obj; + Write(reinterpret_cast(buf), len); +} + +template<> +void RirudSocket::Read(std::string &str) { + auto count = str.size(); + auto *buf = str.data(); + Read(buf, count); +} + +template +void RirudSocket::Read(T &obj) { + auto len = sizeof(T); + auto *buf = &obj; + Read(reinterpret_cast(buf), len); +} + +RirudSocket::RirudSocket() { + if ((fd_ = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) { + throw RirudSocketException(strerror(errno)); + } + + struct sockaddr_un addr{ + .sun_family = AF_UNIX, + .sun_path={0} + }; + strcpy(addr.sun_path + 1, "rirud"); + socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path + 1) + 1; + + if (connect(fd_, reinterpret_cast(&addr), socklen) == -1) { + throw RirudSocketException(strerror(errno)); + } +} + +RirudSocket::~RirudSocket() { + if (fd_ != -1) + close(fd_); +} + +std::string RirudSocket::ReadFile(const fs::path &path) { + Write(ACTION_READ_FILE); + Write(path.string().size()); + Write(path.string()); + int32_t rirud_errno; + Read(rirud_errno); + if(rirud_errno != 0) { + throw RirudSocketException(strerror(rirud_errno)); + } + uint32_t file_size; + Read(file_size); + std::string content; + content.resize(file_size); + Read(content); + return content; +} + +void RirudSocket::Write(const char *buf, size_t len) const { + auto count = len; + while (count > 0) { + ssize_t size = write(fd_, buf, count < SSIZE_MAX ? count : SSIZE_MAX); + if (size == -1) { + if (errno == EINTR) continue; + else throw RirudSocketException(strerror(errno)); + } + buf = buf + size; + count -= size; + } +} + +void RirudSocket::Read(char *out, size_t len) const { + while (len > 0) { + ssize_t ret = read(fd_, out, len); + if (ret <= 0) { + if(errno == EINTR) continue; + else throw RirudSocketException(strerror(errno)); + } + out = out + ret; + len -= ret; + } +} + diff --git a/edxp-core/src/main/cpp/main/src/rirud_socket.h b/edxp-core/src/main/cpp/main/src/rirud_socket.h new file mode 100644 index 00000000..f239a39c --- /dev/null +++ b/edxp-core/src/main/cpp/main/src/rirud_socket.h @@ -0,0 +1,47 @@ +// +// Created by loves on 12/2/2020. +// +#pragma once + +#include +#include + + +class RirudSocket { +public: +// class DirIter {}; + + class RirudSocketException : public std::runtime_error { + public: + RirudSocketException(const std::string &what) : std::runtime_error(what) {} + }; + + RirudSocket(); + + std::string ReadFile(const std::filesystem::path &path); + +// DirIter ReadDir(const std::filesystem::path &path); +// DirIter RecursiveReadDir(const std::filesystem::path &path); + + ~RirudSocket(); + +private: + RirudSocket(const RirudSocket &) = delete; + + RirudSocket operator=(const RirudSocket &) = delete; + + + inline static const uint32_t ACTION_READ_FILE = 4; + + template + void Write(const T &); + + template + void Read(T &); + + void Write(const char *buf, size_t len) const; + + void Read(char *buf, size_t len) const; + + int fd_ = -1; +}; diff --git a/edxp-core/template_override/sepolicy.rule b/edxp-core/template_override/sepolicy.rule index b4b0d6d6..aec216d2 100644 --- a/edxp-core/template_override/sepolicy.rule +++ b/edxp-core/template_override/sepolicy.rule @@ -1,4 +1,2 @@ allow system_server system_server process execmem -allow system_server system_server memprotect mmap_zero -# TODO: use rirud -allow zygote adb_data_file file { getattr read } +allow system_server system_server memprotect mmap_zero \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 6eeb58e9..3032043d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,3 @@ androidCompileSdkVersion=30 -androidCompileNdkVersion=22.0.6917172 \ No newline at end of file +androidCompileNdkVersion=22.0.6917172 +android.prefabVersion=1.1.2 \ No newline at end of file