From a0ad07ef3170dbe1d91ebd40f11d97b63d1c63d0 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 12 Nov 2024 00:44:28 +0100 Subject: [PATCH 1/5] fix(Sync for Reddit - Fix /s/ links): Fix patch by using correct fingerprints --- .../sync/syncforreddit/fix/slink/FixSLinksPatch.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/FixSLinksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/FixSLinksPatch.kt index a640936a2..06ee67fe4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/FixSLinksPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/fix/slink/FixSLinksPatch.kt @@ -6,8 +6,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.reddit.customclients.RESOLVE_S_LINK_METHOD import app.revanced.patches.reddit.customclients.SET_ACCESS_TOKEN_METHOD -import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.getOAuthAccessTokenFingerprint -import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.handleNavigationFingerprint import app.revanced.patches.reddit.customclients.fixSLinksPatch import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch @@ -26,7 +24,7 @@ val fixSLinksPatch = fixSLinksPatch( execute { // region Patch navigation handler. - handleNavigationFingerprint.method.apply { + linkHelperOpenLinkFingerprint.method.apply { val urlRegister = "p3" val tempRegister = "v2" @@ -46,7 +44,7 @@ val fixSLinksPatch = fixSLinksPatch( // region Patch set access token. - getOAuthAccessTokenFingerprint.method.addInstruction( + setAuthorizationHeaderFingerprint.method.addInstruction( 0, "invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->$SET_ACCESS_TOKEN_METHOD", ) From 5776de3cfbfa62360267eb6026525d2da8c45654 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Tue, 12 Nov 2024 00:55:01 +0100 Subject: [PATCH 2/5] fix(Sync for Reddit - Spoof client): Fix patch by using correct fingerprints --- .../sync/syncforreddit/api/SpoofClientPatch.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt index 3f9cbf9e9..481d9c3d1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/sync/syncforreddit/api/SpoofClientPatch.kt @@ -63,20 +63,20 @@ val spoofClientPatch = spoofClientPatch( val randomName = (0..100000).random() val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)" - imgurImageAPIFingerprint.method.replaceInstruction( + getUserAgentFingerprint.method.replaceInstruction( 0, """ - const-string v0, "$userAgent" - return-object v0 - """, + const-string v0, "$userAgent" + return-object v0 + """, ) // endregion // region Patch Imgur API URL. - val apiUrlIndex = getUserAgentFingerprint.stringMatches!!.first().index - getUserAgentFingerprint.method.replaceInstruction( + val apiUrlIndex = imgurImageAPIFingerprint.stringMatches!!.first().index + imgurImageAPIFingerprint.method.replaceInstruction( apiUrlIndex, "const-string v1, \"https://api.imgur.com/3/image\"", ) From 53cb19f4a9e29cf34f14e13cac061af085544ad4 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 11 Nov 2024 23:57:42 +0000 Subject: [PATCH 3/5] chore: Release v5.0.2-dev.1 [skip ci] ## [5.0.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.1...v5.0.2-dev.1) (2024-11-11) ### Bug Fixes * **Sync for Reddit - Fix /s/ links:** Fix patch by using correct fingerprints ([a0ad07e](https://github.com/ReVanced/revanced-patches/commit/a0ad07ef3170dbe1d91ebd40f11d97b63d1c63d0)) * **Sync for Reddit - Spoof client:** Fix patch by using correct fingerprints ([5776de3](https://github.com/ReVanced/revanced-patches/commit/5776de3cfbfa62360267eb6026525d2da8c45654)) --- CHANGELOG.md | 8 ++++++++ gradle.properties | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcb2f69a8..8b3d3f201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [5.0.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.1...v5.0.2-dev.1) (2024-11-11) + + +### Bug Fixes + +* **Sync for Reddit - Fix /s/ links:** Fix patch by using correct fingerprints ([a0ad07e](https://github.com/ReVanced/revanced-patches/commit/a0ad07ef3170dbe1d91ebd40f11d97b63d1c63d0)) +* **Sync for Reddit - Spoof client:** Fix patch by using correct fingerprints ([5776de3](https://github.com/ReVanced/revanced-patches/commit/5776de3cfbfa62360267eb6026525d2da8c45654)) + ## [5.0.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.0...v5.0.1) (2024-11-11) diff --git a/gradle.properties b/gradle.properties index 91d6594da..614acc17e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.0.1 +version = 5.0.2-dev.1 From bb526bc00a384eb808f46267e5802c8e5beaa7d5 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Tue, 12 Nov 2024 10:07:32 +0400 Subject: [PATCH 4/5] fix(YouTube - Player controls): Show player control buttons with A/B layout (#3901) --- .../youtube/patches/EnableDebuggingPatch.java | 14 +++++++++ .../youtube/patches/PlayerControlsPatch.java | 8 +++++ patches/api/patches.api | 2 ++ .../misc/debugging/EnableDebuggingPatch.kt | 21 +++++++++++-- .../youtube/misc/debugging/Fingerprints.kt | 6 ++++ .../misc/playercontrols/Fingerprints.kt | 9 +++++- .../playercontrols/PlayerControlsPatch.kt | 30 +++++++++++++++++-- .../kotlin/app/revanced/util/BytecodeUtils.kt | 21 +++++++++++++ 8 files changed, 106 insertions(+), 5 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/EnableDebuggingPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/EnableDebuggingPatch.java index 60ffa53ed..333420f40 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/EnableDebuggingPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/EnableDebuggingPatch.java @@ -53,4 +53,18 @@ public final class EnableDebuggingPatch { return value; } + + /** + * Injection point. + */ + public static String isStringFeatureFlagEnabled(String value, long flag, String defaultValue) { + if (BaseSettings.DEBUG.get() && !defaultValue.equals(value)) { + if (featureFlags.putIfAbsent(flag, true) == null) { + Logger.printDebug(() -> " string feature is enabled: " + flag + + " value: " + value + (defaultValue.isEmpty() ? "" : " default: " + defaultValue)); + } + } + + return value; + } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/PlayerControlsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/PlayerControlsPatch.java index 5dc3dde26..9ce74d118 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/PlayerControlsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/PlayerControlsPatch.java @@ -8,6 +8,7 @@ import app.revanced.extension.shared.Logger; @SuppressWarnings("unused") public class PlayerControlsPatch { + /** * Injection point. */ @@ -41,4 +42,11 @@ public class PlayerControlsPatch { public static void fullscreenButtonVisibilityChanged(boolean isVisible) { // Code added during patching. } + + /** + * Injection point. + */ + public static String getPlayerTopControlsLayoutResourceName(String original) { + return "default"; + } } diff --git a/patches/api/patches.api b/patches/api/patches.api index 04e8b64e2..1bed18e28 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -1444,10 +1444,12 @@ public final class app/revanced/util/BytecodeUtilsKt { public static final fun indexOfFirstInstructionOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I public static synthetic fun indexOfFirstInstructionOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)I + public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;)I public static final fun indexOfFirstInstructionReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I public static synthetic fun indexOfFirstInstructionReversed$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I public static synthetic fun indexOfFirstInstructionReversed$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)I + public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;)I public static final fun indexOfFirstInstructionReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lkotlin/jvm/functions/Function1;)I public static synthetic fun indexOfFirstInstructionReversedOrThrow$default (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/Integer;Lcom/android/tools/smali/dexlib2/Opcode;ILjava/lang/Object;)I diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt index 9696418eb..a5f8331e1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt @@ -11,6 +11,7 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode private const val EXTENSION_CLASS_DESCRIPTOR = @@ -105,7 +106,23 @@ val enableDebuggingPatch = bytecodePatch( ) } - // There exists other experimental accessor methods for String, byte[], and wrappers for obfuscated classes, - // but currently none of those are hooked. + experimentalStringFeatureFlagFingerprint.match( + experimentalFeatureFlagParentFingerprint.originalClassDef + ).method.apply { + val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT) + + addInstructions( + insertIndex, + """ + move-result-object v0 + invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String; + move-result-object v0 + return-object v0 + """ + ) + } + + // There exists other experimental accessor methods for byte[] + // and wrappers for obfuscated classes, but currently none of those are hooked. } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt index 549994eb5..fe3f75eb1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt @@ -28,3 +28,9 @@ internal val experimentalLongFeatureFlagFingerprint = fingerprint { parameters("J", "J") } +internal val experimentalStringFeatureFlagFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("Ljava/lang/String;") + parameters("J", "Ljava/lang/String;") +} + diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt index 9fca4d89c..824022590 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt @@ -47,10 +47,17 @@ internal val controlsOverlayVisibilityFingerprint = fingerprint { parameters("Z", "Z") } -internal val playerControlsExploderFeatureFlagFingerprint = fingerprint { +internal val playerBottomControlsExploderFeatureFlagFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") parameters() literal { 45643739L } } +internal val playerTopControlsExperimentalLayoutFeatureFlagFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("I") + parameters() + literal { 45629424L } +} + diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt index d2a20deb0..d8e72d87f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/PlayerControlsPatch.kt @@ -1,6 +1,7 @@ package app.revanced.patches.youtube.misc.playercontrols import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch @@ -10,6 +11,7 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch import app.revanced.patches.shared.misc.mapping.resourceMappings +import app.revanced.patches.youtube.misc.playservice.is_19_25_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_35_or_greater import app.revanced.util.* import com.android.tools.smali.dexlib2.Opcode @@ -263,12 +265,36 @@ val playerControlsPatch = bytecodePatch( visibilityImmediateMethod = playerControlsExtensionHookFingerprint.method - // A/B test for a slightly different overlay controls, + // A/B test for a slightly different bottom overlay controls, // that uses layout file youtube_video_exploder_controls_bottom_ui_container.xml // The change to support this is simple and only requires adding buttons to both layout files, // but for now force this different layout off since it's still an experimental test. if (is_19_35_or_greater) { - playerControlsExploderFeatureFlagFingerprint.method.returnEarly() + playerBottomControlsExploderFeatureFlagFingerprint.method.returnEarly() + } + + // A/B test of new top overlay controls. Two different layouts can be used: + // youtube_cf_navigation_improvement_controls_layout.xml + // youtube_cf_minimal_impact_controls_layout.xml + // + // Visually there is no noticeable difference between either of these compared to the default. + // There is additional logic that is active when youtube_cf_navigation_improvement_controls_layout + // is active, but what it does is not entirely clear. + // + // For now force this a/b feature off as it breaks the top player buttons. + if (is_19_25_or_greater) { + playerTopControlsExperimentalLayoutFeatureFlagFingerprint.method.apply { + val index = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_OBJECT) + val register = getInstruction(index).registerA + + addInstructions( + index + 1, + """ + invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getPlayerTopControlsLayoutResourceName(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$register + """ + ) + } } } } diff --git a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index db7d2664b..ec75cb0a5 100644 --- a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -309,6 +309,17 @@ fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, filter: Inst return instructions.indexOfLast(filter) } +/** + * Get the index of matching instruction, + * starting from the end of the method and searching down. + * + * @return -1 if the instruction is not found. + */ +fun Method.indexOfFirstInstructionReversed(targetOpcode: Opcode): Int = + indexOfFirstInstructionReversed { + opcode == targetOpcode + } + /** * Get the index of matching instruction, * starting from and [startIndex] and searching down. @@ -322,6 +333,16 @@ fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targe opcode == targetOpcode } +/** + * Get the index of matching instruction, + * starting from the end of the method and searching down. + * + * @return -1 if the instruction is not found. + */ +fun Method.indexOfFirstInstructionReversedOrThrow(targetOpcode: Opcode): Int = + indexOfFirstInstructionReversedOrThrow { + opcode == targetOpcode + } /** * Get the index of matching instruction, * starting from and [startIndex] and searching down. From 874de60be3c0811ac537197479e25a0b719057df Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 12 Nov 2024 06:10:45 +0000 Subject: [PATCH 5/5] chore: Release v5.0.2-dev.2 [skip ci] ## [5.0.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.2-dev.1...v5.0.2-dev.2) (2024-11-12) ### Bug Fixes * **YouTube - Player controls:** Show player control buttons with A/B layout ([#3901](https://github.com/ReVanced/revanced-patches/issues/3901)) ([bb526bc](https://github.com/ReVanced/revanced-patches/commit/bb526bc00a384eb808f46267e5802c8e5beaa7d5)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b3d3f201..9df9ba254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.0.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.0.2-dev.1...v5.0.2-dev.2) (2024-11-12) + + +### Bug Fixes + +* **YouTube - Player controls:** Show player control buttons with A/B layout ([#3901](https://github.com/ReVanced/revanced-patches/issues/3901)) ([bb526bc](https://github.com/ReVanced/revanced-patches/commit/bb526bc00a384eb808f46267e5802c8e5beaa7d5)) + ## [5.0.2-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.0.1...v5.0.2-dev.1) (2024-11-11) diff --git a/gradle.properties b/gradle.properties index 614acc17e..170336dc8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.0.2-dev.1 +version = 5.0.2-dev.2