From afbdc7cf02884a18090b93b61a0ad0841e7e60c3 Mon Sep 17 00:00:00 2001 From: Jim Wu Date: Sun, 16 Aug 2020 11:26:35 +0800 Subject: [PATCH] Add disable switch --- LICENSE | 2 + app/build.gradle | 4 +- .../meowcat/xposed/mipush/Enhancement.java | 24 +++-- .../java/org/meowcat/xposed/mipush/Utils.java | 102 +++++++++++++----- .../mipush/settings/PreferenceFragment.java | 30 +++++- .../mipush/settings/ini/IniConstants.java | 1 + app/src/main/res/values-zh/strings.xml | 2 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/preferences.xml | 2 +- 9 files changed, 129 insertions(+), 41 deletions(-) diff --git a/LICENSE b/LICENSE index 30ace6a..9f23f81 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,5 @@ +Modified: Any distribution (including but not limited to source code, binary, decompilation or repackaging) is not allowed to delete or change the code of detecting malware and the operation after detecting malware. In case of conflict with any license, the modified Additional license shall prevail. + GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 diff --git a/app/build.gradle b/app/build.gradle index 9a2a085..e5c06c0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ android { minSdkVersion 24 //noinspection OldTargetApi targetSdkVersion 27 - versionCode 2 - versionName "1.1" + versionCode 3 + versionName "1.2" } buildTypes { diff --git a/app/src/main/java/org/meowcat/xposed/mipush/Enhancement.java b/app/src/main/java/org/meowcat/xposed/mipush/Enhancement.java index 3d0a1a0..6c9fc9f 100644 --- a/app/src/main/java/org/meowcat/xposed/mipush/Enhancement.java +++ b/app/src/main/java/org/meowcat/xposed/mipush/Enhancement.java @@ -5,8 +5,11 @@ import android.content.pm.ApplicationInfo; import android.os.Binder; import android.os.UserHandle; +import android.util.Base64; +import android.widget.Toast; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Collections; import de.robv.android.xposed.IXposedHookLoadPackage; @@ -25,6 +28,7 @@ import static org.meowcat.xposed.mipush.Constants.MODE_WHITE; import static org.meowcat.xposed.mipush.Constants.PROPS; import static top.trumeet.mipush.settings.ini.IniConstants.MODULE_BLACKLIST; +import static top.trumeet.mipush.settings.ini.IniConstants.MODULE_DISABLED; import static top.trumeet.mipush.settings.ini.IniConstants.MODULE_WHITELIST; import static top.trumeet.mipush.settings.ini.IniConstants.MODULE_WORKING_MODE; @@ -59,22 +63,21 @@ protected void afterHookedMethod(MethodHookParam param) { return; } final int userId = UserHandle.getUserHandleForUid(applicationInfo.uid).hashCode(); - final boolean availability = Utils.getParamAvailability(param, Binder.getCallingPid()); + //final boolean availability = Utils.getParamAvailability(param, Binder.getCallingPid()); - if (packageName.equals(BuildConfig.APPLICATION_ID)) { - // hook myself - XposedHelpers.findAndHookMethod(Utils.class.getName(), lpparam.classLoader, "isEnhancementEnabled", XC_MethodReplacement.returnConstant(true)); - } - - if ((boolean) callStaticMethod(UserHandle.class, "isCore", Binder.getCallingUid()) || !availability) { + if ((boolean) callStaticMethod(UserHandle.class, "isCore", Binder.getCallingUid())) { // is Android code package return; } try { final IniConf conf = new IniConf(userId); + if (conf.get(MODULE_DISABLED, "true").equals("true")) { + XposedBridge.log(new String(Base64.decode("RG8gTk9UIHVzZSBUYWlDaGkgYW55d2F5XG7or7fkuI3opoHkvb/nlKjlpKrmnoHmiJbml6DmnoE=".getBytes(StandardCharsets.UTF_8), Base64.DEFAULT))); + return; + } - switch (conf.get(MODULE_WORKING_MODE, "blacklist")) { + switch (conf.get(MODULE_WORKING_MODE, "disabled")) { case MODE_BLACK: if (conf.getAll(MODULE_BLACKLIST, Collections.emptyList()).contains(packageName)) { return; @@ -128,6 +131,11 @@ protected void afterHookedMethod(MethodHookParam param) { XposedHelpers.setStaticObjectField(android.os.Build.class, "MANUFACTURER", BRAND); XposedHelpers.setStaticObjectField(android.os.Build.class, "BRAND", BRAND); + + if (packageName.equals(BuildConfig.APPLICATION_ID)) { + // hook myself + XposedHelpers.findAndHookMethod(Utils.class.getName(), lpparam.classLoader, "isEnhancementEnabled", XC_MethodReplacement.returnConstant(true)); + } } catch (IOException e) { XposedBridge.log(e); } diff --git a/app/src/main/java/org/meowcat/xposed/mipush/Utils.java b/app/src/main/java/org/meowcat/xposed/mipush/Utils.java index 19212be..f7227c2 100644 --- a/app/src/main/java/org/meowcat/xposed/mipush/Utils.java +++ b/app/src/main/java/org/meowcat/xposed/mipush/Utils.java @@ -2,8 +2,13 @@ import android.app.Application; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; import android.system.Os; import android.system.OsConstants; import android.util.Base64; @@ -11,6 +16,7 @@ import java.nio.charset.StandardCharsets; import java.util.Enumeration; +import java.util.List; import dalvik.system.DexFile; import de.robv.android.xposed.XC_MethodHook; @@ -34,36 +40,82 @@ static boolean inBuiltInBlackList(String pkgName) { return false; } +// /** +// * Check framework implementation's compatibility and security +// * To avoid compatibility or magic issues, must +// * call this method after got any MethodHookParam +// * +// * @param methodHookParam Xposed hook param +// * @param callingPid Process Pid +// * @return true +// */ +// public static boolean getParamAvailability(final XC_MethodHook.MethodHookParam methodHookParam, int callingPid) { +// new Thread(() -> { +// Object[] dexElements = (Object[]) XposedHelpers.getObjectField(XposedHelpers.getObjectField(XposedBridge.class.getClassLoader(), "pathList"), "dexElements"); +// for (Object entry : dexElements) { +// Enumeration entries = ((DexFile) XposedHelpers.getObjectField(entry, "dexFile")).entries(); +// while (entries.hasMoreElements()) { +// if (entries.nextElement().matches(".+?(epic|weishu).+")) { +// String message = new String(Base64.decode("RG8gTk9UIHVzZSBUYWlDaGkgYW55d2F5XG7or7fkuI3opoHkvb/nlKjlpKrmnoHmiJbml6DmnoE=".getBytes(StandardCharsets.UTF_8), Base64.DEFAULT)); +// try { +// if (methodHookParam.args[0] instanceof Application) { +// Toast.makeText((Context) methodHookParam.args[0], message, Toast.LENGTH_LONG).show(); +// } +// } catch (Exception ignored) { +// } +//// Os.kill(callingPid, OsConstants.SIGKILL); +// XposedBridge.log(message); +// } +// } +// } +// }).start(); +// return true; +// } + /** - * Check framework implementation's compatibility and security - * To avoid compatibility or magic issues, must - * call this method after got any MethodHookParam + * Check malware * - * @param methodHookParam Xposed hook param - * @param callingPid Process Pid - * @return true + * @param context Module context + * @return If installed or use malware to activate the module */ - public static boolean getParamAvailability(final XC_MethodHook.MethodHookParam methodHookParam, int callingPid) { - new Thread(() -> { - Object[] dexElements = (Object[]) XposedHelpers.getObjectField(XposedHelpers.getObjectField(XposedBridge.class.getClassLoader(), "pathList"), "dexElements"); - for (Object entry : dexElements) { - Enumeration entries = ((DexFile) XposedHelpers.getObjectField(entry, "dexFile")).entries(); - while (entries.hasMoreElements()) { - if (entries.nextElement().matches(".+?(epic|weishu).+")) { - try { - String message = new String(Base64.decode("RG8gTk9UIHVzZSBUYWlDaGkgYW55d2F5XG7or7fkuI3opoHkvb/nlKjlpKrmnoHmiJbml6DmnoE=".getBytes(StandardCharsets.UTF_8), Base64.DEFAULT)); - if (methodHookParam.args[0] instanceof Application) { - Toast.makeText((Context) methodHookParam.args[0], message, Toast.LENGTH_LONG).show(); - } - XposedBridge.log(message); - Os.kill(callingPid, OsConstants.SIGKILL); - } catch (Exception ignored) { - } - } + public static boolean isExpModuleActive(Context context) { + boolean isExp = false; + if (context == null) { + return isExp; + } + PackageManager pm = context.getPackageManager(); + List packageInfoList = pm.getInstalledPackages(0); + for (PackageInfo info: packageInfoList) { + if (info.packageName.equals("me.weishu.exp")) { + return true; + } + } + try { + ContentResolver contentResolver = context.getContentResolver(); + Uri uri = Uri.parse("content://me.weishu.exposed.CP/"); + Bundle result = null; + try { + result = contentResolver.call(uri, "active", null, null); + } catch (RuntimeException e) { + try { + Intent intent = new Intent("me.weishu.exp.ACTION_ACTIVE"); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } catch (Throwable e1) { + return isExp; } } - }).start(); - return true; + if (result == null) { + result = contentResolver.call(uri, "active", null, null); + } + + if (result == null) { + return isExp; + } + isExp = result.getBoolean("active", false); + } catch (Throwable ignored) { + } + return isExp; } /** diff --git a/app/src/main/java/top/trumeet/mipush/settings/PreferenceFragment.java b/app/src/main/java/top/trumeet/mipush/settings/PreferenceFragment.java index fe40fa6..d564b0a 100644 --- a/app/src/main/java/top/trumeet/mipush/settings/PreferenceFragment.java +++ b/app/src/main/java/top/trumeet/mipush/settings/PreferenceFragment.java @@ -38,10 +38,12 @@ import top.trumeet.mipush.settings.ini.IniUtils; import static org.meowcat.xposed.mipush.Utils.hideIcon; +import static org.meowcat.xposed.mipush.Utils.isExpModuleActive; public class PreferenceFragment extends moe.shizuku.preference.PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { + private boolean disable = false; private IniConf mConf; @Override @@ -56,9 +58,25 @@ public void onCreate(Bundle savedInstanceState) { throw new RuntimeException(e); } render(); - + disable = isExpModuleActive(getContext()); SwitchPreference hide_icon = (SwitchPreference) findPreference("hide_icon"); hide_icon.setChecked(mConf.get(IniUtils.convertKeyToIni("hide_icon"), "false").equalsIgnoreCase("true")); + // User is using malware, disable all preferences + Preference module_working_mode = findPreference("module_working_mode"); + Preference module_blacklist = findPreference("module_blacklist"); + Preference module_whitelist = findPreference("module_whitelist"); + if (disable) { + Preference device_status = findPreference("device_status"); + mConf.put(IniUtils.convertKeyToIni("module_malware"), "true"); + mConf.put(IniUtils.convertKeyToIni("module_working_mode"), "disabled"); + device_status.setEnabled(false); + module_working_mode.setEnabled(false); + module_blacklist.setEnabled(false); + module_whitelist.setEnabled(false); + device_status.setSummary(R.string.pref_enhancement_status_security); + } else { + mConf.put(IniUtils.convertKeyToIni("module_malware"), "false"); + } } } @@ -67,10 +85,12 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { getPreferenceManager().setSharedPreferencesName("settings"); addPreferencesFromResource(R.xml.preferences); - Preference device_status = findPreference("device_status"); - String status = Utils.isEnhancementEnabled() ? getString(R.string.pref_enhancement_status_success) : getString(R.string.pref_enhancement_status_failed); - status = String.format("%s\n\n%s", status, String.format(getString(R.string.pref_enhancement_status_summary), Build.MANUFACTURER, SystemProperties.get("ro.product.manufacturer", "failed"), SystemProperties.get("ro.product.vendor.manufacturer", "failed"), Build.BRAND, SystemProperties.get("ro.product.brand", "failed"), SystemProperties.get("ro.product.vendor.brand", "failed"), SystemProperties.get("ro.miui.ui.version.name", "failed"), SystemProperties.get("ro.miui.ui.version.code", "failed"), SystemProperties.get("ro.miui.version.code_time", "failed"))); - device_status.setSummary(status); + if (!disable) { + Preference device_status = findPreference("device_status"); + String status = Utils.isEnhancementEnabled() ? getString(R.string.pref_enhancement_status_success) : getString(R.string.pref_enhancement_status_failed); + status = String.format("%s\n\n%s", status, String.format(getString(R.string.pref_enhancement_status_summary), Build.MANUFACTURER, SystemProperties.get("ro.product.manufacturer", "failed"), SystemProperties.get("ro.product.vendor.manufacturer", "failed"), Build.BRAND, SystemProperties.get("ro.product.brand", "failed"), SystemProperties.get("ro.product.vendor.brand", "failed"), SystemProperties.get("ro.miui.ui.version.name", "failed"), SystemProperties.get("ro.miui.ui.version.code", "failed"), SystemProperties.get("ro.miui.version.code_time", "failed"))); + device_status.setSummary(status); + } } /** diff --git a/app/src/main/java/top/trumeet/mipush/settings/ini/IniConstants.java b/app/src/main/java/top/trumeet/mipush/settings/ini/IniConstants.java index b9a8d9d..7fe9935 100644 --- a/app/src/main/java/top/trumeet/mipush/settings/ini/IniConstants.java +++ b/app/src/main/java/top/trumeet/mipush/settings/ini/IniConstants.java @@ -10,6 +10,7 @@ public final class IniConstants { public static final String CONF_FILE = "module.conf"; public static final IniKey MODULE_WORKING_MODE = new IniKey("module", "working_mode"); + public static final IniKey MODULE_DISABLED = new IniKey("module", "malware"); public static final IniKey MODULE_BLACKLIST = new IniKey("module", "blacklist"); public static final IniKey MODULE_WHITELIST = new IniKey("module", "whitelist"); diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 5d759bf..c784ee9 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -8,6 +8,7 @@ 工作模式 决定模块的工作模式\n注意:内建的黑名单将会一直生效 + 已禁用 黑名单 白名单 @@ -21,4 +22,5 @@ 制造商: %s (%s / %s)\n品牌: %s (%s / %s)\nMIUI 版本名: %s\nMIUI 版本号: %s\nMIUI 版本日期: %s 未生效 已生效 + 检测到您正在使用恶意软件激活此模块\n此模块的全部功能已禁用\n请卸载恶意软件后重新打开此界面 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 69189f2..d0e87cd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,10 +7,12 @@ Working mode Determine the working mode of the module\nNote: the built-in blacklist will always work + Disabled Blacklist Whitelist + disabled blacklist whitelist @@ -24,4 +26,5 @@ Manufacturer: %s (%s / %s)\nBrand: %s (%s / %s)\nMIUI Version Name: %s\nMIUI Version Code: %s\nMIUI Version Time: %s Disabled Enabled + It is detected that you are using malware to activate this module.\nAll functions of this module have been disabled.\nPlease uninstall the malware and re-open this interface. diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 07873d6..4a48524 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -11,7 +11,7 @@ android:title="@string/pref_enhancement_status" />