diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cc9b0e3..c066725 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -56,6 +56,9 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + - name: Setup ninja uses: seanmiddleditch/gha-setup-ninja@master with: diff --git a/build.gradle.kts b/build.gradle.kts index c9d1154..a4ff58e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -53,7 +53,7 @@ val coreVerName by extra(coreLatestTag) val androidMinSdkVersion by extra(28) val androidTargetSdkVersion by extra(35) val androidCompileSdkVersion by extra(35) -val androidCompileNdkVersion by extra("27.1.12297006") +val androidCompileNdkVersion by extra("29.0.13113456") val androidBuildToolsVersion by extra("35.0.0") val androidSourceCompatibility by extra(JavaVersion.VERSION_21) val androidTargetCompatibility by extra(JavaVersion.VERSION_21) diff --git a/core b/core index c9e11c6..90d3712 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit c9e11c6770d5a6c9a0b7f9a5a243d031c25e0e0a +Subproject commit 90d3712c6e99199ae9797de15710dd12c4b107e4 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b9..9bbc975 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72..37f853b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6..faf9300 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -206,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. diff --git a/patch-loader/src/main/jni/CMakeLists.txt b/patch-loader/src/main/jni/CMakeLists.txt index 5f1e66d..e56e88f 100644 --- a/patch-loader/src/main/jni/CMakeLists.txt +++ b/patch-loader/src/main/jni/CMakeLists.txt @@ -1,6 +1,7 @@ project(lspatch) cmake_minimum_required(VERSION 3.4.1) +set(CMAKE_CXX_STANDARD 23) add_subdirectory(${CORE_ROOT} core) aux_source_directory(src SRC_LIST) diff --git a/patch-loader/src/main/jni/include/art/runtime/jit/profile_saver.h b/patch-loader/src/main/jni/include/art/runtime/jit/profile_saver.h index c6bcec9..003f667 100644 --- a/patch-loader/src/main/jni/include/art/runtime/jit/profile_saver.h +++ b/patch-loader/src/main/jni/include/art/runtime/jit/profile_saver.h @@ -12,45 +12,44 @@ using namespace lsplant; namespace art { class ProfileSaver { private: - inline static MemberHooker<"_ZN3art12ProfileSaver20ProcessProfilingInfoEbPt", ProfileSaver, - bool(bool, uint16_t *)> - ProcessProfilingInfo_ = +[](ProfileSaver *thiz, bool a, uint16_t *b) { - LOGD("skipped profile saving"); - return true; - }; + inline static auto ProcessProfilingInfo_ = + "_ZN3art12ProfileSaver20ProcessProfilingInfoEbPt"_sym.hook->* + [](ProfileSaver *thiz, bool a, uint16_t *b) static -> bool { + LOGD("skipped profile saving"); + return true; + }; - inline static MemberHooker<"_ZN3art12ProfileSaver20ProcessProfilingInfoEbbPt", ProfileSaver, - bool(bool, bool, uint16_t *)> - ProcessProfilingInfoWithBool_ = +[](ProfileSaver *thiz, bool, bool, uint16_t *) { - LOGD("skipped profile saving"); - return true; - }; + inline static auto ProcessProfilingInfoWithBool_ = + "_ZN3art12ProfileSaver20ProcessProfilingInfoEbbPt"_sym.hook->* + [](ProfileSaver *thiz, bool, bool, uint16_t *) static -> bool { + LOGD("skipped profile saving"); + return true; + }; - inline static Hooker<"execve", - int(const char *pathname, const char *argv[], char *const envp[])> - execve_ = +[](const char *pathname, const char *argv[], char *const envp[]) { - if (strstr(pathname, "dex2oat")) { - size_t count = 0; - while (argv[count++] != nullptr); - std::unique_ptr new_args = - std::make_unique(count + 1); - for (size_t i = 0; i < count - 1; ++i) new_args[i] = argv[i]; - new_args[count - 1] = "--inline-max-code-units=0"; - new_args[count] = nullptr; + inline static auto execve_ = + "execve"_sym.hook->*[](const char *pathname, const char *argv[], + char *const envp[]) static -> int { + if (strstr(pathname, "dex2oat")) { + size_t count = 0; + while (argv[count++] != nullptr); + std::unique_ptr new_args = std::make_unique(count + 1); + for (size_t i = 0; i < count - 1; ++i) new_args[i] = argv[i]; + new_args[count - 1] = "--inline-max-code-units=0"; + new_args[count] = nullptr; - LOGD("dex2oat by disable inline!"); - int ret = execve_(pathname, new_args.get(), envp); - return ret; - } - int ret = execve_(pathname, argv, envp); + LOGD("dex2oat by disable inline!"); + int ret = backup(pathname, new_args.get(), envp); return ret; - }; + } + int ret = backup(pathname, argv, envp); + return ret; + }; public: static void DisableInline(const HookHandler &handler) { - handler.hook(ProcessProfilingInfo_); - handler.hook(ProcessProfilingInfoWithBool_); - handler.hook(execve_); + handler(ProcessProfilingInfo_); + handler(ProcessProfilingInfoWithBool_); + handler(execve_); } }; } // namespace art diff --git a/patch-loader/src/main/jni/include/art/runtime/oat_file_manager.h b/patch-loader/src/main/jni/include/art/runtime/oat_file_manager.h index 2f904d5..6a48a90 100644 --- a/patch-loader/src/main/jni/include/art/runtime/oat_file_manager.h +++ b/patch-loader/src/main/jni/include/art/runtime/oat_file_manager.h @@ -20,6 +20,8 @@ #ifndef LSPATCH_OAT_FILE_MANAGER_H #define LSPATCH_OAT_FILE_MANAGER_H +#include + #include "context.h" #include "utils/hook_helper.hpp" @@ -28,41 +30,40 @@ using namespace lsplant; namespace art { class FileManager { public: - inline static MemberHooker< - "_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__" - "16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobjectPKc", - FileManager, void(const std::vector &, jobject, const char *)> - RunBackgroundVerificationWithContext_ = - +[](FileManager *thiz, const std::vector &dex_files, jobject class_loader, - const char *class_loader_context) { - if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) { - LOGD("Disabled background verification"); - return; - } - RunBackgroundVerificationWithContext_(thiz, dex_files, class_loader, - class_loader_context); - }; + inline static auto RunBackgroundVerificationWithContext_ = + ("_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__"_sym | + "16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobjectPKc"_sym) + .hook + ->*[]( + FileManager *thiz, const std::vector &dex_files, + jobject class_loader, const char *class_loader_context) static -> void { + if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) { + LOGD("Disabled background verification"); + return; + } + backup(thiz, dex_files, class_loader, class_loader_context); + }; - inline static MemberHooker< - "_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__" - "16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobject", - FileManager, void(const std::vector &, jobject)> - RunBackgroundVerification_ = - +[](FileManager *thiz, const std::vector &dex_files, - jobject class_loader) { - if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) { - LOGD("Disabled background verification"); - return; - } - RunBackgroundVerification_(thiz, dex_files, class_loader); - }; + inline static auto RunBackgroundVerification_ = + ("_ZN3art14OatFileManager25RunBackgroundVerificationERKNSt3__"_sym | + "16vectorIPKNS_7DexFileENS1_9allocatorIS5_EEEEP8_jobject"_sym) + .hook + ->* + [](FileManager *thiz, const std::vector &dex_files, + jobject class_loader) static -> void { + if (lspd::Context::GetInstance()->GetCurrentClassLoader() == nullptr) { + LOGD("Disabled background verification"); + return; + } + backup(thiz, dex_files, class_loader); + }; public: static void DisableBackgroundVerification(const lsplant::HookHandler &handler) { const int api_level = lspd::GetAndroidApiLevel(); if (api_level >= __ANDROID_API_Q__) { - handler.hook(RunBackgroundVerificationWithContext_); - handler.hook(RunBackgroundVerification_); + handler(RunBackgroundVerificationWithContext_); + handler(RunBackgroundVerification_); } } }; diff --git a/patch-loader/src/main/jni/src/jni/bypass_sig.cpp b/patch-loader/src/main/jni/src/jni/bypass_sig.cpp index 06d993b..f08e60f 100644 --- a/patch-loader/src/main/jni/src/jni/bypass_sig.cpp +++ b/patch-loader/src/main/jni/src/jni/bypass_sig.cpp @@ -12,6 +12,8 @@ #include "utils/hook_helper.hpp" #include "utils/jni_helper.hpp" +using lsplant::operator""_sym; + namespace lspd { std::string apkPath; @@ -19,7 +21,7 @@ std::string redirectPath; inline static constexpr auto kLibCName = "libc.so"; -std::unique_ptr& GetC(bool release = false) { +std::unique_ptr &GetC(bool release = false) { static std::unique_ptr kImg = nullptr; if (release) { kImg.reset(); @@ -29,23 +31,24 @@ std::unique_ptr& GetC(bool release = false) { return kImg; } -inline static lsplant::Hooker<"__openat", int(int, const char*, int, int)> __openat_ = - +[](int fd, const char* pathname, int flag, int mode) { - if (pathname == apkPath) { - LOGD("Redirect openat from {} to {}", pathname, redirectPath); - return __openat_(fd, redirectPath.c_str(), flag, mode); - } - return __openat_(fd, pathname, flag, mode); - }; +inline static auto __openat_ = + "__openat"_sym.hook->*[](int fd, const char *pathname, int flag, + int mode) static -> int { + if (pathname == apkPath) { + LOGD("Redirect openat from {} to {}", pathname, redirectPath); + return backup(fd, redirectPath.c_str(), flag, mode); + } + return backup(fd, pathname, flag, mode); +}; -bool HookOpenat(const lsplant::HookHandler& handler) { return handler.hook(__openat_); } +bool HookOpenat(const lsplant::HookHandler &handler) { return handler(__openat_); } LSP_DEF_NATIVE_METHOD(void, SigBypass, enableOpenatHook, jstring origApkPath, jstring cacheApkPath) { auto r = HookOpenat(lsplant::InitInfo{ .inline_hooker = [](auto t, auto r) { - void* bk = nullptr; + void *bk = nullptr; return HookInline(t, r, &bk) == 0 ? bk : nullptr; }, .art_symbol_resolver = [](auto symbol) { return GetC()->getSymbAddress(symbol); }, @@ -66,6 +69,6 @@ LSP_DEF_NATIVE_METHOD(void, SigBypass, enableOpenatHook, jstring origApkPath, static JNINativeMethod gMethods[] = { LSP_NATIVE_METHOD(SigBypass, enableOpenatHook, "(Ljava/lang/String;Ljava/lang/String;)V")}; -void RegisterBypass(JNIEnv* env) { REGISTER_LSP_NATIVE_METHODS(SigBypass); } +void RegisterBypass(JNIEnv *env) { REGISTER_LSP_NATIVE_METHODS(SigBypass); } } // namespace lspd