From 3d9ce59bb33a9334bc168e951c430b782ce6cbf2 Mon Sep 17 00:00:00 2001 From: xob0t <32616886+xob0t@users.noreply.github.com> Date: Sat, 22 Jun 2024 00:23:14 +0300 Subject: [PATCH 1/4] feat(bandcamp): patch to bypass play limits --- api/revanced-patches.api | 6 +++++ .../fingerprints/playLimitsFingerprint.kt | 7 ++++++ .../removeplaylimits/removePlayLimitsPatch.kt | 24 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/fingerprints/playLimitsFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 75d89226c5..67f0446c6a 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -169,6 +169,12 @@ public final class app/revanced/patches/backdrops/misc/pro/ProUnlockPatch : app/ public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch; + 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/candylinkvpn/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/candylinkvpn/UnlockProPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V diff --git a/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/fingerprints/playLimitsFingerprint.kt b/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/fingerprints/playLimitsFingerprint.kt new file mode 100644 index 0000000000..058782d561 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/fingerprints/playLimitsFingerprint.kt @@ -0,0 +1,7 @@ +package app.revanced.patches.bandcamp.removeplaylimits.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object playLimitsFingerprint : MethodFingerprint( + strings = listOf("play limits processing track", "found play_count"), +) diff --git a/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch.kt b/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch.kt new file mode 100644 index 0000000000..9cb925e405 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch.kt @@ -0,0 +1,24 @@ +package app.revanced.patches.bandcamp.removeplaylimits + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.bandcamp.removeplaylimits.fingerprints.playLimitsFingerprint +import app.revanced.util.exception + +@Patch( + name = "Remove Play Limits", + description = "Disables purchase nagging and playback limits of not purchased tracks", + compatiblePackages = [CompatiblePackage("com.bandcamp.android")], +) +object removePlayLimitsPatch : BytecodePatch( + setOf(playLimitsFingerprint) +) { + override fun execute(context: BytecodeContext) { + playLimitsFingerprint.result?.mutableMethod?.addInstructions( + 0,"return-void" + ) ?: throw playLimitsFingerprint.exception + } +} From e15258d2d3a4b50e0ed7e02d4a55e73f56fa0766 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Thu, 27 Jun 2024 13:30:50 +0200 Subject: [PATCH 2/4] refactor --- api/revanced-patches.api | 4 ++-- .../limitations/RemovePlayLimitsPatch.kt | 23 ++++++++++++++++++ .../HandlePlaybackLimitsPatch.kt} | 4 ++-- .../removeplaylimits/removePlayLimitsPatch.kt | 24 ------------------- 4 files changed, 27 insertions(+), 28 deletions(-) create mode 100644 src/main/kotlin/app/revanced/patches/bandcamp/limitations/RemovePlayLimitsPatch.kt rename src/main/kotlin/app/revanced/patches/bandcamp/{removeplaylimits/fingerprints/playLimitsFingerprint.kt => limitations/fingerprints/HandlePlaybackLimitsPatch.kt} (51%) delete mode 100644 src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 67f0446c6a..35127dd53a 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -169,8 +169,8 @@ public final class app/revanced/patches/backdrops/misc/pro/ProUnlockPatch : app/ public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } -public final class app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch : app/revanced/patcher/patch/BytecodePatch { - public static final field INSTANCE Lapp/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch; +public final class app/revanced/patches/bandcamp/limitations/RemovePlayLimitsPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/bandcamp/limitations/RemovePlayLimitsPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } diff --git a/src/main/kotlin/app/revanced/patches/bandcamp/limitations/RemovePlayLimitsPatch.kt b/src/main/kotlin/app/revanced/patches/bandcamp/limitations/RemovePlayLimitsPatch.kt new file mode 100644 index 0000000000..b7620bfacd --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/bandcamp/limitations/RemovePlayLimitsPatch.kt @@ -0,0 +1,23 @@ +package app.revanced.patches.bandcamp.limitations + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.bandcamp.limitations.fingerprints.HandlePlaybackLimitsPatch +import app.revanced.util.exception + +@Patch( + name = "Remove play limits", + description = "Disables purchase nagging and playback limits of not purchased tracks.", + compatiblePackages = [CompatiblePackage("com.bandcamp.android")], +) +@Suppress("unused") +object RemovePlayLimitsPatch : BytecodePatch( + setOf(HandlePlaybackLimitsPatch), +) { + override fun execute(context: BytecodeContext) = + HandlePlaybackLimitsPatch.result?.mutableMethod?.addInstructions(0, "return-void") + ?: throw HandlePlaybackLimitsPatch.exception +} diff --git a/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/fingerprints/playLimitsFingerprint.kt b/src/main/kotlin/app/revanced/patches/bandcamp/limitations/fingerprints/HandlePlaybackLimitsPatch.kt similarity index 51% rename from src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/fingerprints/playLimitsFingerprint.kt rename to src/main/kotlin/app/revanced/patches/bandcamp/limitations/fingerprints/HandlePlaybackLimitsPatch.kt index 058782d561..5465800e9f 100644 --- a/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/fingerprints/playLimitsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/bandcamp/limitations/fingerprints/HandlePlaybackLimitsPatch.kt @@ -1,7 +1,7 @@ -package app.revanced.patches.bandcamp.removeplaylimits.fingerprints +package app.revanced.patches.bandcamp.limitations.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint -internal object playLimitsFingerprint : MethodFingerprint( +internal object HandlePlaybackLimitsPatch : MethodFingerprint( strings = listOf("play limits processing track", "found play_count"), ) diff --git a/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch.kt b/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch.kt deleted file mode 100644 index 9cb925e405..0000000000 --- a/src/main/kotlin/app/revanced/patches/bandcamp/removeplaylimits/removePlayLimitsPatch.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.bandcamp.removeplaylimits - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.bandcamp.removeplaylimits.fingerprints.playLimitsFingerprint -import app.revanced.util.exception - -@Patch( - name = "Remove Play Limits", - description = "Disables purchase nagging and playback limits of not purchased tracks", - compatiblePackages = [CompatiblePackage("com.bandcamp.android")], -) -object removePlayLimitsPatch : BytecodePatch( - setOf(playLimitsFingerprint) -) { - override fun execute(context: BytecodeContext) { - playLimitsFingerprint.result?.mutableMethod?.addInstructions( - 0,"return-void" - ) ?: throw playLimitsFingerprint.exception - } -} From 97f5a4b0506f52f1d975b6b70482499a246177eb Mon Sep 17 00:00:00 2001 From: xob0t <5348245@gmail.com> Date: Sun, 22 Sep 2024 18:33:16 +0300 Subject: [PATCH 3/4] feat(Google Photos): Show hidden 'Back up while charging' toggle "This toggle is hidden by default, when enabled, backups run only when the device is charging --- api/revanced-patches.api | 6 ++++ .../ShowBackUpWhileChargingPatch.kt | 33 +++++++++++++++++++ .../BackupPreferencesFingerprint.kt | 10 ++++++ 3 files changed, 49 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/googlephotos/preferences/ShowBackUpWhileChargingPatch.kt create mode 100644 src/main/kotlin/app/revanced/patches/googlephotos/preferences/fingerprints/BackupPreferencesFingerprint.kt diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 7b5140448d..06a1dfe77e 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -301,6 +301,12 @@ public final class app/revanced/patches/googlephotos/misc/integrations/Integrati public static final field INSTANCE Lapp/revanced/patches/googlephotos/misc/integrations/IntegrationsPatch; } +public final class app/revanced/patches/googlephotos/preferences/BackupPreferencesFingerprint : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/googlephotos/preferences/BackupPreferencesFingerprint; + 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/googlerecorder/restrictions/RemoveDeviceRestrictions : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V diff --git a/src/main/kotlin/app/revanced/patches/googlephotos/preferences/ShowBackUpWhileChargingPatch.kt b/src/main/kotlin/app/revanced/patches/googlephotos/preferences/ShowBackUpWhileChargingPatch.kt new file mode 100644 index 0000000000..ffa66a2531 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlephotos/preferences/ShowBackUpWhileChargingPatch.kt @@ -0,0 +1,33 @@ +package app.revanced.patches.googlephotos.preferences + +import app.revanced.util.exception +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.googlephotos.preferences.fingerprints.BackupPreferencesFingerprint +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch( + name = "Show hidden 'Back up while charging' toggle", + description = "This toggle is hidden by default, when enabled, backups run only when the device is charging", + compatiblePackages = [CompatiblePackage("com.google.android.apps.photos")] +) +@Suppress("unused") +object BackupPreferencesFingerprint : BytecodePatch( + setOf(BackupPreferencesFingerprint) +) { + override fun execute(context: BytecodeContext) { + // patches 'backup_prefs_had_backup_only_when_charging_enabled' to always be true + BackupPreferencesFingerprint.result?.let { + val chargingPrefStringIndex = it.scanResult.stringsScanResult!!.matches.first().index + it.mutableMethod.apply { + val resultRegister = getInstruction(chargingPrefStringIndex+2).registerA + // override result as true + addInstruction(chargingPrefStringIndex + 3, "const/4 v$resultRegister, 0x1") + } + } ?: throw Exception("BackupPreferencesFingerprint result not found") + } +} diff --git a/src/main/kotlin/app/revanced/patches/googlephotos/preferences/fingerprints/BackupPreferencesFingerprint.kt b/src/main/kotlin/app/revanced/patches/googlephotos/preferences/fingerprints/BackupPreferencesFingerprint.kt new file mode 100644 index 0000000000..0b182c1485 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/googlephotos/preferences/fingerprints/BackupPreferencesFingerprint.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.googlephotos.preferences.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint + +internal object BackupPreferencesFingerprint : MethodFingerprint( + returnType = "Lcom/google/android/apps/photos/backup/data/BackupPreferences;", + strings = listOf( + "backup_prefs_had_backup_only_when_charging_enabled", + ), +) From 4063a07b611f2b1c377ecf94d10bdd98876c8d4a Mon Sep 17 00:00:00 2001 From: xob0t <5348245@gmail.com> Date: Mon, 23 Sep 2024 16:11:37 +0300 Subject: [PATCH 4/4] requested fixes --- api/revanced-patches.api | 4 ++-- ...reHiddenBackUpWhileChargingTogglePatch.kt} | 20 +++++++++---------- .../BackupPreferencesFingerprint.kt | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) rename src/main/kotlin/app/revanced/patches/googlephotos/preferences/{ShowBackUpWhileChargingPatch.kt => RestoreHiddenBackUpWhileChargingTogglePatch.kt} (66%) diff --git a/api/revanced-patches.api b/api/revanced-patches.api index 06a1dfe77e..7a62e576a6 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -301,8 +301,8 @@ public final class app/revanced/patches/googlephotos/misc/integrations/Integrati public static final field INSTANCE Lapp/revanced/patches/googlephotos/misc/integrations/IntegrationsPatch; } -public final class app/revanced/patches/googlephotos/preferences/BackupPreferencesFingerprint : app/revanced/patcher/patch/BytecodePatch { - public static final field INSTANCE Lapp/revanced/patches/googlephotos/preferences/BackupPreferencesFingerprint; +public final class app/revanced/patches/googlephotos/preferences/RestoreHiddenBackUpWhileChargingTogglePatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/googlephotos/preferences/RestoreHiddenBackUpWhileChargingTogglePatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } diff --git a/src/main/kotlin/app/revanced/patches/googlephotos/preferences/ShowBackUpWhileChargingPatch.kt b/src/main/kotlin/app/revanced/patches/googlephotos/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt similarity index 66% rename from src/main/kotlin/app/revanced/patches/googlephotos/preferences/ShowBackUpWhileChargingPatch.kt rename to src/main/kotlin/app/revanced/patches/googlephotos/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt index ffa66a2531..0b935afd91 100644 --- a/src/main/kotlin/app/revanced/patches/googlephotos/preferences/ShowBackUpWhileChargingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/googlephotos/preferences/RestoreHiddenBackUpWhileChargingTogglePatch.kt @@ -1,6 +1,5 @@ package app.revanced.patches.googlephotos.preferences -import app.revanced.util.exception import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction @@ -11,21 +10,22 @@ import app.revanced.patches.googlephotos.preferences.fingerprints.BackupPreferen import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Patch( - name = "Show hidden 'Back up while charging' toggle", - description = "This toggle is hidden by default, when enabled, backups run only when the device is charging", - compatiblePackages = [CompatiblePackage("com.google.android.apps.photos")] + name = "Restore hidden 'Back up while charging' toggle", + description = "Restores a hidden toggle to only run backups when the device is charging.", + compatiblePackages = [CompatiblePackage("com.google.android.apps.photos")], ) @Suppress("unused") -object BackupPreferencesFingerprint : BytecodePatch( - setOf(BackupPreferencesFingerprint) +object RestoreHiddenBackUpWhileChargingTogglePatch : BytecodePatch( + setOf(BackupPreferencesFingerprint), ) { override fun execute(context: BytecodeContext) { - // patches 'backup_prefs_had_backup_only_when_charging_enabled' to always be true + // Patches 'backup_prefs_had_backup_only_when_charging_enabled' to always be true. BackupPreferencesFingerprint.result?.let { - val chargingPrefStringIndex = it.scanResult.stringsScanResult!!.matches.first().index + val chargingPrefStringIndex = it.scanResult.stringsScanResult!!.matches.first().index it.mutableMethod.apply { - val resultRegister = getInstruction(chargingPrefStringIndex+2).registerA - // override result as true + // Get the register of move-result. + val resultRegister = getInstruction(chargingPrefStringIndex + 2).registerA + // Insert const after move-result to override register as true. addInstruction(chargingPrefStringIndex + 3, "const/4 v$resultRegister, 0x1") } } ?: throw Exception("BackupPreferencesFingerprint result not found") diff --git a/src/main/kotlin/app/revanced/patches/googlephotos/preferences/fingerprints/BackupPreferencesFingerprint.kt b/src/main/kotlin/app/revanced/patches/googlephotos/preferences/fingerprints/BackupPreferencesFingerprint.kt index 0b182c1485..7d12ed5b0b 100644 --- a/src/main/kotlin/app/revanced/patches/googlephotos/preferences/fingerprints/BackupPreferencesFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/googlephotos/preferences/fingerprints/BackupPreferencesFingerprint.kt @@ -5,6 +5,6 @@ import app.revanced.patcher.fingerprint.MethodFingerprint internal object BackupPreferencesFingerprint : MethodFingerprint( returnType = "Lcom/google/android/apps/photos/backup/data/BackupPreferences;", strings = listOf( - "backup_prefs_had_backup_only_when_charging_enabled", - ), + "backup_prefs_had_backup_only_when_charging_enabled", + ), )