From 780f3577a5895517ecf3955ab5824a1fbbc3c360 Mon Sep 17 00:00:00 2001 From: WhiteChi Date: Mon, 27 Nov 2023 00:42:15 +0800 Subject: [PATCH] `Shamrock`: optimize clover.cpp --- xposed/src/main/cpp/CMakeLists.txt | 36 ++----- .../cpp/anti_detection/anti_detection.cpp | 80 +++++++++++++++ .../main/cpp/anti_detection/anti_detection.h | 18 ++++ xposed/src/main/cpp/clover.cpp | 98 +------------------ xposed/src/main/cpp/helper/jnihelper.cpp | 30 ++++++ xposed/src/main/cpp/helper/jnihelper.h | 18 ++++ xposed/src/main/cpp/{ => helper}/lsposed.h | 0 xposed/src/main/cpp/jnihelper.h | 40 -------- 8 files changed, 154 insertions(+), 166 deletions(-) create mode 100644 xposed/src/main/cpp/anti_detection/anti_detection.cpp create mode 100644 xposed/src/main/cpp/anti_detection/anti_detection.h create mode 100644 xposed/src/main/cpp/helper/jnihelper.cpp create mode 100644 xposed/src/main/cpp/helper/jnihelper.h rename xposed/src/main/cpp/{ => helper}/lsposed.h (100%) delete mode 100644 xposed/src/main/cpp/jnihelper.h diff --git a/xposed/src/main/cpp/CMakeLists.txt b/xposed/src/main/cpp/CMakeLists.txt index f2a3f8b..116c8df 100644 --- a/xposed/src/main/cpp/CMakeLists.txt +++ b/xposed/src/main/cpp/CMakeLists.txt @@ -1,41 +1,17 @@ - -# For more information about using CMake with Android Studio, read the -# documentation: https://d.android.com/studio/projects/add-native-code.html. -# For more examples on how to use CMake, see https://github.com/android/ndk-samples. - -# Sets the minimum CMake version required for this project. cmake_minimum_required(VERSION 3.22.1) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Declares the project name. The project name can be accessed via ${ PROJECT_NAME}, -# Since this is the top level CMakeLists.txt, the project name is also accessible -# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level -# build script scope). project("clover") -# Creates and names a library, sets it as either STATIC -# or SHARED, and provides the relative paths to its source code. -# You can define multiple libraries, and CMake builds them for you. -# Gradle automatically packages shared libraries with your APK. -# -# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define -# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME} -# is preferred for the same purpose. -# -# In order to load a library into your app from Java/Kotlin, you must call -# System.loadLibrary() and pass the name of the library defined here; -# for GameActivity/NativeActivity derived applications, the same library name must be -# used in the AndroidManifest.xml file. -add_library(${CMAKE_PROJECT_NAME} SHARED - # List C/C++ source files with relative paths to this CMakeLists.txt. - clover.cpp) +include_directories(helper) + +add_library(${CMAKE_PROJECT_NAME} SHARED + anti_detection/anti_detection.cpp + helper/jnihelper.cpp + clover.cpp) -# Specifies libraries CMake should link to your target library. You -# can link libraries from various origins, such as libraries defined in this -# build script, prebuilt third-party libraries, or Android system libraries. target_link_libraries(${CMAKE_PROJECT_NAME} - # List libraries link to the target library android log) diff --git a/xposed/src/main/cpp/anti_detection/anti_detection.cpp b/xposed/src/main/cpp/anti_detection/anti_detection.cpp new file mode 100644 index 0000000..21fc76e --- /dev/null +++ b/xposed/src/main/cpp/anti_detection/anti_detection.cpp @@ -0,0 +1,80 @@ +#include "anti_detection.h" + +int (*backup_system_property_get)(const char *name, char *value); +FILE* (*backup_fopen)(const char *filename, const char *mode); + +int fake_system_property_get(const char *name, char *value) { + for (auto &prop: qemu_detect_props) { + if (strstr(name, prop.c_str())) { + LOGI("[Shamrock] bypass qemu detection"); + value[0] = 0; + return 0; + } + } + + if (strstr(name, "ro.debuggable") + || strstr(name, "ro.kernel.qemu.gles") + || strstr(name, "debug.atrace.tags.enableflags")) { + strcpy(value, "0"); + return 1; + } + + if (strstr(name, "ro.product.cpu.abilist")) { + int len = backup_system_property_get(name, value); + if (len > 0) { + if (strstr(value, "x86")) { + strcpy(value, "arm64-v8a,armeabi-v7a,armeabi"); + return 29; + } + } + return len; + } + + if (strstr(name, "ro.hardware")) { + int len = backup_system_property_get(name, value); + if (len > 0) { + if (strstr(value, "generic") + || strstr(value, "unknown") + || strstr(value, "emulator") + || strstr(value, "vbox") + || strstr(value, "genymotion") + || strstr(value, "goldfish")) { + strcpy(value, "qcom"); + return 4; + } + } + return len; + } + + //LOGI("[Shamrock] fake_system_property_get(%s)", name); + return backup_system_property_get(name, value); +} + +FILE* fake_fopen(const char *filename, const char *mode) { + if (strstr(filename, "qemu_pipe")) { + LOGI("[Shamrock] bypass qemu detection"); + return nullptr; + } + + if (strstr(filename, "libhoudini.so")) { + LOGI("[Shamrock] bypass emu detection"); + return nullptr; + } + + return backup_fopen(filename, mode); +} + +void on_library_loaded(const char *name, void *handle) { + +} + +extern "C" [[gnu::visibility("default")]] [[gnu::used]] +NativeOnModuleLoaded native_init(const NativeAPIEntries *entries) { + hook_function = entries->hook_func; + LOGI("[Shamrock] LSPosed NativeModule Init: %p", hook_function); + + hook_function((void*) __system_property_get, (void *)fake_system_property_get, (void **) &backup_system_property_get); + hook_function((void*) fopen, (void*) fake_fopen, (void**) &backup_fopen); + + return on_library_loaded; +} diff --git a/xposed/src/main/cpp/anti_detection/anti_detection.h b/xposed/src/main/cpp/anti_detection/anti_detection.h new file mode 100644 index 0000000..ccbb9d7 --- /dev/null +++ b/xposed/src/main/cpp/anti_detection/anti_detection.h @@ -0,0 +1,18 @@ +#ifndef SHAMROCK_ANTI_DETECTION_H +#define SHAMROCK_ANTI_DETECTION_H + +#include +#include +#include +#include "lsposed.h" +#include "jnihelper.h" + +static HookFunType hook_function = nullptr; + +static std::vector qemu_detect_props = { + "init.svc.qemu-props", "qemu.hw.mainkeys", "qemu.sf.fake_camera", "ro.kernel.android.qemud", + "qemu.sf.lcd_density", "init.svc.qemud", "ro.kernel.qemu", + "libc.debug.malloc" +}; + +#endif //SHAMROCK_ANTI_DETECTION_H diff --git a/xposed/src/main/cpp/clover.cpp b/xposed/src/main/cpp/clover.cpp index edd3147..b0e0113 100644 --- a/xposed/src/main/cpp/clover.cpp +++ b/xposed/src/main/cpp/clover.cpp @@ -1,91 +1,8 @@ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include "lsposed.h" +#include "anti_detection/anti_detection.h" +#include "helper/lsposed.h" #include "jnihelper.h" -static HookFunType hook_function = nullptr; - -static std::vector qemu_detect_props = { - "init.svc.qemu-props", "qemu.hw.mainkeys", "qemu.sf.fake_camera", "ro.kernel.android.qemud", - "qemu.sf.lcd_density", "init.svc.qemud", "ro.kernel.qemu", - "libc.debug.malloc" -}; - -int (*backup_system_property_get)(const char *name, char *value); -FILE* (*backup_fopen)(const char *filename, const char *mode); - -int fake_system_property_get(const char *name, char *value) { - for (auto &prop: qemu_detect_props) { - if (strstr(name, prop.c_str())) { - LOGI("[Shamrock] bypass qemu detection"); - value[0] = 0; - return 0; - } - } - - if (strstr(name, "ro.debuggable") - || strstr(name, "ro.kernel.qemu.gles") - || strstr(name, "debug.atrace.tags.enableflags")) { - strcpy(value, "0"); - return 1; - } - - if (strstr(name, "ro.product.cpu.abilist")) { - int len = backup_system_property_get(name, value); - if (len > 0) { - if (strstr(value, "x86")) { - strcpy(value, "arm64-v8a,armeabi-v7a,armeabi"); - return 29; - } - } - return len; - } - - if (strstr(name, "ro.hardware")) { - int len = backup_system_property_get(name, value); - if (len > 0) { - if (strstr(value, "generic") - || strstr(value, "unknown") - || strstr(value, "emulator") - || strstr(value, "vbox") - || strstr(value, "genymotion") - || strstr(value, "goldfish")) { - strcpy(value, "qcom"); - return 4; - } - } - return len; - } - - //LOGI("[Shamrock] fake_system_property_get(%s)", name); - return backup_system_property_get(name, value); -} - -FILE* fake_fopen(const char *filename, const char *mode) { - if (strstr(filename, "qemu_pipe")) { - LOGI("[Shamrock] bypass qemu detection"); - return nullptr; - } - - if (strstr(filename, "libhoudini.so")) { - LOGI("[Shamrock] bypass emu detection"); - return nullptr; - } - - return backup_fopen(filename, mode); -} - -void on_library_loaded(const char *name, void *handle) { - -} - extern "C" [[gnu::visibility("default")]] [[gnu::used]] jint JNI_OnLoad(JavaVM *jvm, void*) { JNIHelper::initJavaVM(jvm); @@ -103,17 +20,6 @@ jint JNI_OnLoad(JavaVM *jvm, void*) { return JNI_VERSION_1_6; } -extern "C" [[gnu::visibility("default")]] [[gnu::used]] -NativeOnModuleLoaded native_init(const NativeAPIEntries *entries) { - hook_function = entries->hook_func; - LOGI("[Shamrock] LSPosed NativeModule Init: %p", hook_function); - - hook_function((void*) __system_property_get, (void *)fake_system_property_get, (void **) &backup_system_property_get); - hook_function((void*) fopen, (void*) fake_fopen, (void**) &backup_fopen); - - return on_library_loaded; -} - extern "C" JNIEXPORT jboolean JNICALL Java_moe_fuqiuluo_shamrock_xposed_XposedEntry_00024Companion_injected(JNIEnv *env, jobject thiz) { diff --git a/xposed/src/main/cpp/helper/jnihelper.cpp b/xposed/src/main/cpp/helper/jnihelper.cpp new file mode 100644 index 0000000..246132f --- /dev/null +++ b/xposed/src/main/cpp/helper/jnihelper.cpp @@ -0,0 +1,30 @@ +#include "jnihelper.h" + +void JNIHelper::initJavaVM(JavaVM *jvm) { + global_jvm = jvm; +} + +JNIEnv *JNIHelper::getJNIEnv(int *attach) { + if (global_jvm == NULL) return NULL; + + *attach = 0; + JNIEnv *jni_env = NULL; + + int status = global_jvm->GetEnv((void **)&jni_env, JNI_VERSION_1_6); + + if (status == JNI_EDETACHED || jni_env == NULL) { + status = global_jvm->AttachCurrentThread(&jni_env, NULL); + if (status < 0) { + jni_env = NULL; + } else { + *attach = 1; + } + } + return jni_env; +} + +jint JNIHelper::delJNIEnv() { + if (global_jvm == nullptr) return 0; + return global_jvm->DetachCurrentThread(); +} + diff --git a/xposed/src/main/cpp/helper/jnihelper.h b/xposed/src/main/cpp/helper/jnihelper.h new file mode 100644 index 0000000..122b825 --- /dev/null +++ b/xposed/src/main/cpp/helper/jnihelper.h @@ -0,0 +1,18 @@ +#ifndef SHAMROCK_JNIHELPER_H +#define SHAMROCK_JNIHELPER_H + +#include "jni.h" +#include "android/log.h" + +namespace JNIHelper { + static JavaVM *global_jvm = nullptr; + + void initJavaVM(JavaVM *jvm); + + JNIEnv *getJNIEnv(int *attach); + + jint delJNIEnv(); +} + + +#endif //SHAMROCK_JNIHELPER_H diff --git a/xposed/src/main/cpp/lsposed.h b/xposed/src/main/cpp/helper/lsposed.h similarity index 100% rename from xposed/src/main/cpp/lsposed.h rename to xposed/src/main/cpp/helper/lsposed.h diff --git a/xposed/src/main/cpp/jnihelper.h b/xposed/src/main/cpp/jnihelper.h deleted file mode 100644 index a45fef6..0000000 --- a/xposed/src/main/cpp/jnihelper.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef SHAMROCK_JNIHELPER_H -#define SHAMROCK_JNIHELPER_H - -#include "android/log.h" - -namespace JNIHelper { - static JavaVM *global_jvm = nullptr; - - void initJavaVM(JavaVM *jvm) { - global_jvm = jvm; - } - - JNIEnv *getJNIEnv(int *attach) { - if (global_jvm == NULL) return NULL; - - *attach = 0; - JNIEnv *jni_env = NULL; - - int status = global_jvm->GetEnv((void **)&jni_env, JNI_VERSION_1_6); - - if (status == JNI_EDETACHED || jni_env == NULL) { - status = global_jvm->AttachCurrentThread(&jni_env, NULL); - if (status < 0) { - jni_env = NULL; - } else { - *attach = 1; - } - } - return jni_env; - } - - jint delJNIEnv() { - if (global_jvm == nullptr) return 0; - return global_jvm->DetachCurrentThread(); - } -} - - - -#endif //SHAMROCK_JNIHELPER_H