diff --git a/README.md b/README.md index 5734ebe..adda800 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,11 @@ ## 简介 -☘ 基于 Xposed 实现 OneBot 标准的 QQ 机器人框架,原作者[**fuqiuluo**](https://github.com/fuqiuluo)已脱离开发,接下来由白池接手哦!本项目为OpenShamrock,不会有任何收费行为,欢迎大家的加入! +☘ 基于 Lsposed(**Non**-Riru) 实现 OneBot 标准的 QQ 机器人框架,原作者[**fuqiuluo**](https://github.com/fuqiuluo)已脱离开发,接下来由白池接手哦!本项目为OpenShamrock,不会有任何收费行为,欢迎大家的加入! > 本项目仅提供学习与交流用途,请在24小时内删除。 > 本项目目的是研究 Xposed 和 LSPosed 框架的使用。 Epic 框架开发相关知识。 +> Riru可能导致封禁,请减少使用。 > 如有违反法律,请联系删除。 > 请勿在任何平台宣传,宣扬,转发本项目,请勿恶意修改企业安装包造成相关企业产生损失,如有违背,必将追责到底。 > 官方论坛,[点我直达](https://forum.libfekit.so/)! diff --git a/xposed/src/main/cpp/anti_detection/anti_detection.h b/xposed/src/main/cpp/anti_detection/anti_detection.h index b915af4..bc14dbf 100644 --- a/xposed/src/main/cpp/anti_detection/anti_detection.h +++ b/xposed/src/main/cpp/anti_detection/anti_detection.h @@ -15,6 +15,8 @@ static std::vector qemu_detect_props = { static int (*backup_system_property_get)(const char *name, char *value); static FILE* (*backup_fopen)(const char *filename, const char *mode); +static int (*backup_memcmp)(const void* __lhs, const void* __rhs, size_t __n); +//static const char* (*backup_strstr)(const char* h, const char* n); //int fake_system_property_get(const char *name, char *value); //FILE* fake_fopen(const char *filename, const char *mode); diff --git a/xposed/src/main/cpp/clover.cpp b/xposed/src/main/cpp/clover.cpp index abee4b8..d7020c8 100644 --- a/xposed/src/main/cpp/clover.cpp +++ b/xposed/src/main/cpp/clover.cpp @@ -85,8 +85,6 @@ int fake_system_property_get(const char *name, char *value) { 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"); @@ -117,6 +115,54 @@ FILE* fake_fopen(const char *filename, const char *mode) { return backup_fopen(filename, mode); } +char * __cdecl my_strstr(const char *lhs, const char *rhs) { + char *cur = (char *)lhs; + char *l; + char *r; + if (!*rhs) { + return ((char *)lhs); + } + while (*cur) { + l = cur; + r = (char *)rhs; + while (*r && !(*l - *r)) { + l++; + r++; + } + if (!*r) { + return cur; + } + cur++; + } + return nullptr; +} + +int fake_memcmp(const void* __lhs, const void* __rhs, size_t __n) { + if (my_strstr((const char*) __rhs, "lsposed")) { + return -1; + } + if (my_strstr((const char*) __rhs, "xposed")) { + return -1; + } + if (my_strstr((const char*) __rhs, "shamrock")) { + if (backup_memcmp(__lhs, __rhs, __n) == 0) { + // 底层广播判断 + return 0; + } + return -1; + } + if (my_strstr((const char*) __rhs, "riru")) { + return -1; + } + if (my_strstr((const char*) __rhs, "zygisk")) { + return -1; + } + if (my_strstr((const char*) __rhs, "magisk")) { + return -1; + } + return backup_memcmp(__lhs, __rhs, __n); +} + void on_library_loaded(const char *name, void *handle) { } @@ -136,5 +182,8 @@ Java_moe_fuqiuluo_shamrock_xposed_actions_AntiDetection_antiNativeDetections(JNI if (hook_function == nullptr) return false; 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); + //hook_function((void*) strstr, (void*) fake_strstr, (void**) &backup_strstr); + hook_function((void*) memcmp, (void*) fake_memcmp, (void**) &backup_memcmp); + return true; } diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/actions/AntiDetection.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/actions/AntiDetection.kt index a27598c..54c702d 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/actions/AntiDetection.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/xposed/actions/AntiDetection.kt @@ -5,12 +5,14 @@ import android.content.Context import android.content.pm.PackageManager import android.content.pm.VersionedPackage import android.os.Build +import android.os.Looper import de.robv.android.xposed.XC_MethodReplacement import de.robv.android.xposed.XSharedPreferences import de.robv.android.xposed.XposedHelpers import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig +import moe.fuqiuluo.shamrock.tools.MethodHooker import moe.fuqiuluo.shamrock.tools.hookMethod import moe.fuqiuluo.shamrock.xposed.XposedEntry import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader @@ -181,6 +183,22 @@ class AntiDetection: IAction { return className.isModuleStack() } + val stackTraceHooker: MethodHooker = { + val result = it.result as Array + var zygote = false + val newResult = result.filter { + if (it.className == ZYGOTE_NAME) { + zygote = true + } + !it.isModuleStack() + }.toTypedArray() + if (!zygote && Thread.currentThread() == Looper.getMainLooper().thread) { + it.result = arrayListOf(StackTraceElement(ZYGOTE_NAME, "main", ZYGOTE_NAME, 0), *newResult) + } else { + it.result = newResult + } + } + Thread::class.java.hookMethod("getName").after { val result = it.result as String if (result.contains("fuqiuluo") || result.contains("shamrock") || result.contains("whitechi")) { @@ -188,30 +206,15 @@ class AntiDetection: IAction { } } - Thread::class.java.hookMethod("getStackTrace").after { - val result = it.result as Array - it.result = result.filter { - !it.isModuleStack() - }.toTypedArray() - } - - Throwable::class.java.hookMethod("getStackTrace").after { - val result = it.result as Array - it.result = result.filter { - !it.isModuleStack() - }.toTypedArray() - } - - Throwable::class.java.hookMethod("getOurStackTrace").after { - val result = it.result as Array - it.result = result.filter { - !it.isModuleStack() - }.toTypedArray() - } + Thread::class.java.hookMethod("getStackTrace").after(stackTraceHooker) + Throwable::class.java.hookMethod("getStackTrace").after(stackTraceHooker) + Throwable::class.java.hookMethod("getOurStackTrace").after(stackTraceHooker) } companion object { @JvmStatic var isAntiFindPackage = false + + const val ZYGOTE_NAME = "com.android.internal.os.ZygoteInit" } } \ No newline at end of file