diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 849737d420..f82f86e45c 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -284,6 +284,18 @@ public final class app/revanced/patches/messenger/inputfield/patch/DisableTyping public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + +public final class app/revanced/patches/mifitness/misc/login/FixLoginPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/mifitness/misc/login/FixLoginPatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/moneymanager/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/moneymanager/UnlockProPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V diff --git a/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt b/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt new file mode 100644 index 0000000000..c71b0c6265 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt @@ -0,0 +1,39 @@ +package app.revanced.patches.mifitness.misc.locale + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.mifitness.misc.locale.fingerprints.SyncBluetoothLanguageFingerprint +import app.revanced.patches.mifitness.misc.login.FixLoginPatch +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch( + name = "Force English locale", + description = "Forces wearable devices to use the English locale.", + compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")], + dependencies = [FixLoginPatch::class], +) +@Suppress("unused") +object ForceEnglishLocalePatch : BytecodePatch( + setOf(SyncBluetoothLanguageFingerprint), +) { + override fun execute(context: BytecodeContext) { + SyncBluetoothLanguageFingerprint.result?.let { + val resolvePhoneLocaleInstruction = it.scanResult.patternScanResult!!.startIndex + + it.mutableMethod.apply { + val registerIndexToUpdate = + getInstruction(resolvePhoneLocaleInstruction).registerA + + replaceInstruction( + resolvePhoneLocaleInstruction, + "const-string v$registerIndexToUpdate, \"en_gb\"", + ) + } + } ?: throw SyncBluetoothLanguageFingerprint.exception + } +} diff --git a/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/fingerprints/SyncBluetoothLanguageFingerprint.kt b/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/fingerprints/SyncBluetoothLanguageFingerprint.kt new file mode 100644 index 0000000000..95c9a43f05 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/fingerprints/SyncBluetoothLanguageFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.mifitness.misc.locale.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +internal object SyncBluetoothLanguageFingerprint : MethodFingerprint( + customFingerprint = { methodDef, _ -> + methodDef.definingClass == "Lcom/xiaomi/fitness/devicesettings/DeviceSettingsSyncer;" && + methodDef.name == "syncBluetoothLanguage" + }, + opcodes = listOf(Opcode.MOVE_RESULT_OBJECT), +) diff --git a/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt b/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt new file mode 100644 index 0000000000..cf67c893de --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.mifitness.misc.login + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.mifitness.misc.login.fingerprints.XiaomiAccountManagerConstructorFingerprint +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch( + name = "Fix login", + description = "Fixes login for uncertified Mi Fitness app", + compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")], +) +@Suppress("unused") +object FixLoginPatch : BytecodePatch( + setOf(XiaomiAccountManagerConstructorFingerprint), +) { + override fun execute(context: BytecodeContext) { + XiaomiAccountManagerConstructorFingerprint.result?.let { + it.mutableMethod.apply { + val isCertifiedIndex = it.scanResult.patternScanResult!!.startIndex + val isCertifiedRegister = getInstruction(isCertifiedIndex).registerA + + addInstruction( + isCertifiedIndex, + "const/4 p$isCertifiedRegister, 0x0", + ) + } + } ?: throw XiaomiAccountManagerConstructorFingerprint.exception + } +} diff --git a/src/main/kotlin/app/revanced/patches/mifitness/misc/login/fingerprints/XiaomiAccountManagerConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/mifitness/misc/login/fingerprints/XiaomiAccountManagerConstructorFingerprint.kt new file mode 100644 index 0000000000..e5d06acef8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/mifitness/misc/login/fingerprints/XiaomiAccountManagerConstructorFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.mifitness.misc.login.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object XiaomiAccountManagerConstructorFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PRIVATE or AccessFlags.CONSTRUCTOR, + customFingerprint = { methodDef, _ -> + methodDef.definingClass == "Lcom/xiaomi/passport/accountmanager/XiaomiAccountManager;" + }, + opcodes = listOf(Opcode.IF_NEZ), +)