diff --git a/app/build.gradle b/app/build.gradle
index 896e9ae..dcb1628 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,10 +2,17 @@ plugins {
alias(libs.plugins.android.application)
}
+static def getGitHash() {
+ def process = "git rev-parse HEAD".execute()
+ process.in.text.trim()
+}
+
android {
namespace 'com.sevtinge.vojazento'
compileSdk 34
+ def gitHash = getGitHash()
+
defaultConfig {
applicationId "com.sevtinge.vojazento"
minSdk 24
@@ -19,8 +26,10 @@ android {
buildTypes {
release {
minifyEnabled false
+ android.buildFeatures.buildConfig true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
versionNameSuffix "_" + java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd").format(java.time.LocalDateTime.now())
+ buildConfigField "String", "GIT_HASH", "\"${gitHash}\""
}
}
compileOptions {
diff --git a/app/src/main/java/com/sevtinge/vojazento/XposedInit.java b/app/src/main/java/com/sevtinge/vojazento/XposedInit.java
index ebea3fb..e26c010 100644
--- a/app/src/main/java/com/sevtinge/vojazento/XposedInit.java
+++ b/app/src/main/java/com/sevtinge/vojazento/XposedInit.java
@@ -1,15 +1,107 @@
+/*
+ * This file is part of Vojazento.
+
+ * Vojazento is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+
+ * Copyright (C) 2024 Sevtinge
+ */
package com.sevtinge.vojazento;
+import static com.sevtinge.vojazento.utils.PackageUtils.*;
+
+import com.sevtinge.vojazento.utils.XposedLogUtils;
+
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
-import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class XposedInit implements IXposedHookLoadPackage {
+ boolean IS_CHINA_MAINLAND_BUILD = false;
+
+ int ERROR_COUNTER = 0;
+
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
- XposedHelpers.setStaticBooleanField(XposedHelpers.findClassIfExists("miui.os.Build", lpparam.classLoader), "IS_INTERNATIONAL_BUILD", true);
+ XposedLogUtils.logI(lpparam.packageName, "versionName = " + getPackageVersionName(lpparam) + ", versionCode = " + getPackageVersionCode(lpparam));
+ try {
+ XposedHelpers.setStaticBooleanField(XposedHelpers.findClassIfExists("miui.os.Build", lpparam.classLoader), "IS_INTERNATIONAL_BUILD", !IS_CHINA_MAINLAND_BUILD); //是否为国际构建
+ } catch (Throwable t) {
+ ERROR_COUNTER = ERROR_COUNTER + 1;
+ XposedLogUtils.logE(lpparam.packageName, "A problem occurred hook \"miui.os.Build.IS_INTERNATIONAL_BUILD\":" + t);
+ }
+ try {
+ XposedHelpers.setStaticBooleanField(XposedHelpers.findClassIfExists("miuix.os.Build", lpparam.classLoader), "IS_INTERNATIONAL_BUILD", !IS_CHINA_MAINLAND_BUILD); //MiuiX是否为国际构建
+ } catch (Throwable t) {
+ ERROR_COUNTER = ERROR_COUNTER + 1;
+ XposedLogUtils.logE(lpparam.packageName, "A problem occurred hook \"miuix.os.Build.IS_INTERNATIONAL_BUILD\":" + t);
+ }
+ try {
+ XposedHelpers.setStaticBooleanField(XposedHelpers.findClassIfExists("miui.os.Build", lpparam.classLoader), "IS_GLOBAL_BUILD", !IS_CHINA_MAINLAND_BUILD); //是否为全球构建
+ } catch (Throwable t) {
+ ERROR_COUNTER = ERROR_COUNTER + 1;
+ XposedLogUtils.logE(lpparam.packageName, "A problem occurred hook \"miui.os.Build.IS_GLOBAL_BUILD\":" + t);
+ }
+ try {
+ XposedHelpers.setStaticBooleanField(XposedHelpers.findClassIfExists("miui.os.Build", lpparam.classLoader), "IS_CM_CUSTOMIZATION", IS_CHINA_MAINLAND_BUILD); //是否为中国大陆版
+ } catch (Throwable t) {
+ ERROR_COUNTER = ERROR_COUNTER + 1;
+ XposedLogUtils.logE(lpparam.packageName, "A problem occurred hook \"miui.os.Build.IS_CM_CUSTOMIZATION\":" + t);
+ }
+ try {
+ XposedHelpers.setStaticBooleanField(XposedHelpers.findClassIfExists("miui.os.Build", lpparam.classLoader), "IS_CM_CUSTOMIZATION_TEST", IS_CHINA_MAINLAND_BUILD); //是否为中国大陆测试版
+ } catch (Throwable t) {
+ ERROR_COUNTER = ERROR_COUNTER + 1;
+ XposedLogUtils.logE(lpparam.packageName, "A problem occurred hook \"miui.os.Build.IS_CM_CUSTOMIZATION_TEST\":" + t);
+ }
+ try {
+ XposedHelpers.findAndHookMethod(XposedHelpers.findClassIfExists("android.os.SystemProperties", lpparam.classLoader), "get", String.class, String.class, new XC_MethodHook() { //设备名称中是否包含国际版标识
+ @Override
+ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
+ String RETURN = (String) param.args[1];
+ if (param.args[0].equals("ro.product.mod_device")) {
+ if (RETURN.contains("_global") && IS_CHINA_MAINLAND_BUILD) {
+ param.args[1] = RETURN.replace("_global", "");
+ } else if (!RETURN.contains("_global") && !IS_CHINA_MAINLAND_BUILD) {
+ param.args[1] = param.args[1] + "_global";
+ }
+ }
+ }
+ });
+ } catch (Throwable t) {
+ ERROR_COUNTER = ERROR_COUNTER + 1;
+ XposedLogUtils.logE(lpparam.packageName, "A problem occurred hook \"android.os.SystemProperties.get(String, String)\":" + t);
+ }
+ try {
+ XposedHelpers.findAndHookMethod(XposedHelpers.findClassIfExists("miuix.core.util.SystemProperties", lpparam.classLoader), "get", String.class, String.class, new XC_MethodHook() { //miuix设备名称中是否包含国际版标识
+ @Override
+ protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
+ String RETURN = (String) param.args[1];
+ if (param.args[0].equals("ro.product.mod_device")) {
+ if (RETURN.contains("_global") && IS_CHINA_MAINLAND_BUILD) {
+ param.args[1] = RETURN.replace("_global", "");
+ } else if (!RETURN.contains("_global") && !IS_CHINA_MAINLAND_BUILD) {
+ param.args[1] = param.args[1] + "_global";
+ }
+ }
+ }
+ });
+ } catch (Throwable t) {
+ ERROR_COUNTER = ERROR_COUNTER + 1;
+ XposedLogUtils.logE(lpparam.packageName, "A problem occurred hook \"miuix.core.util.SystemProperties.get(String, String)\":" + t);
+ }
+ XposedLogUtils.logI(lpparam.packageName, "Hook over with " + ERROR_COUNTER + " error(s).");
}
}
diff --git a/app/src/main/java/com/sevtinge/vojazento/utils/PackageUtils.java b/app/src/main/java/com/sevtinge/vojazento/utils/PackageUtils.java
new file mode 100644
index 0000000..6032257
--- /dev/null
+++ b/app/src/main/java/com/sevtinge/vojazento/utils/PackageUtils.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of Vojazento.
+
+ * Vojazento is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+
+ * Copyright (C) 2024 Sevtinge
+ */
+package com.sevtinge.vojazento.utils;
+
+import java.io.File;
+
+import de.robv.android.xposed.XposedHelpers;
+import de.robv.android.xposed.callbacks.XC_LoadPackage;
+
+public class PackageUtils {
+ public static String getPackageVersionName(XC_LoadPackage.LoadPackageParam lpparam) {
+ try {
+ Class> parserCls = XposedHelpers.findClass("android.content.pm.PackageParser", lpparam.classLoader);
+ Object parser = parserCls.newInstance();
+ File apkPath = new File(lpparam.appInfo.sourceDir);
+ Object pkg = XposedHelpers.callMethod(parser, "parsePackage", apkPath, 0);
+ return (String) XposedHelpers.getObjectField(pkg, "mVersionName");
+ } catch (Throwable e) {
+ return "null";
+ }
+ }
+
+ public static int getPackageVersionCode(XC_LoadPackage.LoadPackageParam lpparam) {
+ try {
+ Class> parserCls = XposedHelpers.findClass("android.content.pm.PackageParser", lpparam.classLoader);
+ Object parser = parserCls.newInstance();
+ File apkPath = new File(lpparam.appInfo.sourceDir);
+ Object pkg = XposedHelpers.callMethod(parser, "parsePackage", apkPath, 0);
+ return XposedHelpers.getIntField(pkg, "mVersionCode");
+ } catch (Throwable e) {
+ return -1;
+ }
+ }
+}
diff --git a/app/src/main/java/com/sevtinge/vojazento/utils/XposedLogUtils.java b/app/src/main/java/com/sevtinge/vojazento/utils/XposedLogUtils.java
new file mode 100644
index 0000000..78d2590
--- /dev/null
+++ b/app/src/main/java/com/sevtinge/vojazento/utils/XposedLogUtils.java
@@ -0,0 +1,109 @@
+/*
+ * This file is part of Vojazento.
+
+ * Vojazento is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+
+ * Copyright (C) 2024 Sevtinge
+ */
+package com.sevtinge.vojazento.utils;
+
+import de.robv.android.xposed.XposedBridge;
+
+
+public class XposedLogUtils {
+ public static void logI(String msg) {
+ XposedBridge.log("[Vojazento][I]: " + msg);
+ }
+
+ public static void logI(String tagOpkg, String msg) {
+ XposedBridge.log("[Vojazento][I][" + tagOpkg + "]: " + msg);
+ }
+
+ public static void logI(String tag, String pkg, String msg) {
+ XposedBridge.log("[Vojazento][I][" + pkg + "][" + tag + "]: " + msg);
+ }
+
+ public static void logW(String msg) {
+ XposedBridge.log("[Vojazento][W]: " + msg);
+ }
+
+ public static void logW(String tag, String pkg, String msg) {
+ XposedBridge.log("[Vojazento][W][" + pkg + "][" + tag + "]: " + msg);
+ }
+
+ public static void logW(String tag, String pkg, Throwable log) {
+ XposedBridge.log("[Vojazento][W][" + pkg + "][" + tag + "]: " + log);
+ }
+
+ public static void logW(String tag, String pkg, String msg, Exception exp) {
+ XposedBridge.log("[Vojazento][W][" + pkg + "][" + tag + "]: " + msg + ", by: " + exp);
+ }
+
+ public static void logW(String tag, String pkg, String msg, Throwable log) {
+ XposedBridge.log("[Vojazento][W][" + pkg + "][" + tag + "]: " + msg + ", by: " + log);
+ }
+
+ public static void logW(String tag, String msg) {
+ XposedBridge.log("[Vojazento][W][" + tag + "]: " + msg);
+ }
+
+ public static void logW(String tag, Throwable log) {
+ XposedBridge.log("[Vojazento][W][" + tag + "]: " + log);
+ }
+
+ public static void logW(String tag, String msg, Exception exp) {
+ XposedBridge.log("[Vojazento][W][" + tag + "]: " + msg + ", by: " + exp);
+ }
+
+ public static void logE(String tagORpkg, String msg) {
+ XposedBridge.log("[Vojazento][E][" + tagORpkg + "]: " + msg);
+ }
+
+ public static void logE(String msg) {
+ XposedBridge.log("[Vojazento][E]: " + msg);
+ }
+
+ public static void logE(String tag, Throwable log) {
+ XposedBridge.log("[Vojazento][E][" + tag + "]: " + log);
+ }
+
+ public static void logE(String tag, String pkg, String msg) {
+ XposedBridge.log("[Vojazento][E][" + pkg + "][" + tag + "]: " + msg);
+ }
+
+ public static void logE(String tag, String pkg, Throwable log) {
+ XposedBridge.log("[Vojazento][E][" + pkg + "][" + tag + "]: " + log);
+ }
+
+ public static void logE(String tag, String pkg, Exception exp) {
+ XposedBridge.log("[Vojazento][E][" + pkg + "][" + tag + "]: " + exp);
+ }
+
+ public static void logE(String tag, String pkg, String msg, Throwable log) {
+ XposedBridge.log("[Vojazento][E][" + pkg + "][" + tag + "]: " + msg + ", by: " + log);
+ }
+
+ public static void logE(String tag, String pkg, String msg, Exception exp) {
+ XposedBridge.log("[Vojazento][E][" + pkg + "][" + tag + "]: " + msg + ", by: " + exp);
+ }
+
+ public static void logD(String msg) {
+ XposedBridge.log("[Vojazento][D]: " + msg);
+ }
+
+ public static void logD(String tag, String pkg, String msg) {
+ XposedBridge.log("[Vojazento][D][" + pkg + "][" + tag + "]: " + msg);
+ }
+
+}