diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/DislikeRedirectionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/DislikeRedirectionPatch.kt index a39582645..bd019dfa4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/DislikeRedirectionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/redirection/DislikeRedirectionPatch.kt @@ -49,9 +49,14 @@ val dislikeRedirectionPatch = bytecodePatch( val onClickMethod = getWalkerMethod(onClickMethodIndex) onClickMethod.apply { - val onClickIndex = indexOfFirstInstructionOrThrow { - val reference = - ((this as? ReferenceInstruction)?.reference as? MethodReference) + val relativeIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.INVOKE_VIRTUAL && + getReference() + ?.parameterTypes + ?.contains("Ljava/util/Map;") == true + } + val onClickIndex = indexOfFirstInstructionOrThrow(relativeIndex) { + val reference = getReference() opcode == Opcode.INVOKE_INTERFACE && reference?.returnType == "V" && diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt index ac6fb70e0..d3c021bce 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt @@ -12,6 +12,8 @@ import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus import app.revanced.patches.music.utils.settings.addPreferenceWithIntent import app.revanced.patches.music.utils.settings.settingsPatch import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.indexOfFirstStringInstructionOrThrow import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Suppress("unused") @@ -25,20 +27,18 @@ val changeStartPagePatch = bytecodePatch( execute { - coldStartUpFingerprint.matchOrThrow().let { - it.method.apply { - val targetIndex = it.patternMatch!!.endIndex - val targetRegister = getInstruction(targetIndex).registerA + coldStartUpFingerprint.methodOrThrow().apply { + val targetIndex = indexOfFirstStringInstructionOrThrow(DEFAULT_BROWSE_ID) + 1 + val targetRegister = getInstruction(targetIndex).registerA - addInstructions( - targetIndex + 1, """ - invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->changeStartPage(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$targetRegister - return-object v$targetRegister - """ - ) - removeInstruction(targetIndex) - } + addInstructions( + targetIndex + 1, """ + invoke-static {v$targetRegister}, $GENERAL_CLASS_DESCRIPTOR->changeStartPage(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$targetRegister + return-object v$targetRegister + """ + ) + removeInstruction(targetIndex) } addPreferenceWithIntent( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt index 613adde88..9da6c2b7e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt @@ -5,16 +5,17 @@ import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +const val DEFAULT_BROWSE_ID = "FEmusic_home" + internal val coldStartUpFingerprint = legacyFingerprint( name = "coldStartUpFingerprint", returnType = "Ljava/lang/String;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = emptyList(), opcodes = listOf( - Opcode.GOTO, Opcode.CONST_STRING, Opcode.RETURN_OBJECT ), - strings = listOf("FEmusic_library_sideloaded_tracks", "FEmusic_home") + strings = listOf("FEmusic_library_sideloaded_tracks", DEFAULT_BROWSE_ID) ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/album/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/album/Fingerprints.kt index 52f0bf163..7700b9b4f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/album/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/album/Fingerprints.kt @@ -22,7 +22,9 @@ internal val audioVideoSwitchToggleConstructorFingerprint = legacyFingerprint( internal fun indexOfAudioVideoSwitchSetOnClickListenerInstruction(method: Method) = method.indexOfFirstInstruction { opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.toString() == "Lcom/google/android/apps/youtube/music/player/AudioVideoSwitcherToggleView;->setOnClickListener(Landroid/view/View${'$'}OnClickListener;)V" + getReference() + ?.toString() + ?.endsWith("/AudioVideoSwitcherToggleView;->setOnClickListener(Landroid/view/View${'$'}OnClickListener;)V") == true } internal val snackBarParentFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt index ed45770dc..3ce8e4b7c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt @@ -40,6 +40,7 @@ val cairoSplashAnimationPatch = bytecodePatch( "7.06.54", "7.16.53", "7.25.53", + "8.02.53", ), ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt index bf5204063..b1c99a5f6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt @@ -23,7 +23,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference const val AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY = - "Lcom/google/android/apps/youtube/music/player/AudioVideoSwitcherToggleView;->setVisibility(I)V" + "/AudioVideoSwitcherToggleView;->setVisibility(I)V" internal val audioVideoSwitchToggleFingerprint = legacyFingerprint( name = "audioVideoSwitchToggleFingerprint", @@ -33,7 +33,9 @@ internal val audioVideoSwitchToggleFingerprint = legacyFingerprint( customFingerprint = { method, _ -> method.indexOfFirstInstruction { opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.toString() == AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY + getReference() + ?.toString() + ?.endsWith(AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY) == true } >= 0 } ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt index bba1dbab8..6f49240a4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt @@ -799,7 +799,7 @@ val playerComponentsPatch = bytecodePatch( val reference = (instruction as? ReferenceInstruction)?.reference instruction.opcode == Opcode.INVOKE_VIRTUAL && reference is MethodReference && - reference.toString() == AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY + reference.toString().endsWith(AUDIO_VIDEO_SWITCH_TOGGLE_VISIBILITY) } .map { (index, _) -> index } .reversed() @@ -995,7 +995,7 @@ val playerComponentsPatch = bytecodePatch( val reference = getReference() opcode == Opcode.INVOKE_INTERFACE && reference?.returnType == "Z" && - reference.parameterTypes.size == 0 + reference.parameterTypes.isEmpty() } + 1 val targetRegister = getInstruction(targetIndex).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt index b964b90bb..f7d70c001 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt @@ -14,7 +14,8 @@ internal object Constants { "6.42.55", // This is the latest version that supports Android 7.0 "6.51.53", // This is the latest version of YouTube Music 6.xx.xx "7.16.53", // This is the latest version that supports the 'Spoof app version' patch. - "7.25.53", // This is the latest version supported by the RVX patch. + "7.25.53", // This is the last supported version for 2024. + "8.02.53", // This is the latest version supported by the RVX patch. ) ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/Fingerprints.kt index 0edb35019..58cd49634 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/Fingerprints.kt @@ -1,26 +1,33 @@ package app.revanced.patches.music.utils.videotype import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val videoTypeFingerprint = legacyFingerprint( name = "videoTypeFingerprint", returnType = "L", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, parameters = listOf("L"), - opcodes = listOf( - Opcode.IGET, - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.GOTO, - Opcode.SGET_OBJECT - ) + customFingerprint = { method, _ -> + indexOfGetEnumInstruction(method) >= 0 + } ) +internal fun indexOfGetEnumInstruction(method: Method) = + method.indexOfFirstInstruction { + val reference = getReference() + opcode == Opcode.INVOKE_STATIC && + reference?.name == "a" && + reference.parameterTypes.firstOrNull() == "I" && + reference.definingClass == reference.returnType + } + internal val videoTypeParentFingerprint = legacyFingerprint( name = "videoTypeParentFingerprint", returnType = "Z", diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt index 587048a3d..bc0ec4167 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt @@ -4,8 +4,14 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.music.utils.extension.Constants.UTILS_PATH -import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = "$UTILS_PATH/VideoTypeHookPatch;" @@ -17,22 +23,27 @@ val videoTypeHookPatch = bytecodePatch( execute { - videoTypeFingerprint.matchOrThrow(videoTypeParentFingerprint).let { - it.method.apply { - val insertIndex = it.patternMatch!!.startIndex + 3 - val referenceIndex = insertIndex + 1 - val referenceInstruction = - getInstruction(referenceIndex).reference - - addInstructionsWithLabels( - insertIndex, """ - if-nez p0, :dismiss - sget-object p0, $referenceInstruction - :dismiss - invoke-static {p0}, $EXTENSION_CLASS_DESCRIPTOR->setVideoType(Ljava/lang/Enum;)V - """ - ) + videoTypeFingerprint.methodOrThrow(videoTypeParentFingerprint).apply { + val getEnumIndex = indexOfGetEnumInstruction(this) + val enumClass = (getInstruction(getEnumIndex).reference as MethodReference).definingClass + val referenceIndex = indexOfFirstInstructionOrThrow(getEnumIndex) { + opcode == Opcode.SGET_OBJECT && + getReference()?.type == enumClass } + val referenceInstruction = + getInstruction(referenceIndex).reference + + val insertIndex = indexOfFirstInstructionOrThrow(getEnumIndex, Opcode.IF_NEZ) + val insertRegister = getInstruction(insertIndex).registerA + + addInstructionsWithLabels( + insertIndex, """ + if-nez v$insertRegister, :dismiss + sget-object v$insertRegister, $referenceInstruction + :dismiss + invoke-static {v$insertRegister}, $EXTENSION_CLASS_DESCRIPTOR->setVideoType(Ljava/lang/Enum;)V + """ + ) } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/video/information/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/video/information/Fingerprints.kt index d6a110041..d27eb8784 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/video/information/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/video/information/Fingerprints.kt @@ -26,12 +26,6 @@ internal val videoIdFingerprint = legacyFingerprint( returnType = "V", parameters = listOf("L", "Ljava/lang/String;"), accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf( - Opcode.INVOKE_INTERFACE_RANGE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE_RANGE, - Opcode.MOVE_RESULT_OBJECT, - ), strings = listOf("Null initialPlayabilityStatus") ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt index e4901ea36..275e96b4c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/video/information/VideoInformationPatch.kt @@ -191,7 +191,12 @@ val videoInformationPatch = bytecodePatch( */ videoIdFingerprint.matchOrThrow().let { it.method.apply { - val playerResponseModelIndex = it.patternMatch!!.startIndex + val playerResponseModelIndex = indexOfFirstInstructionOrThrow { + val reference = getReference() + (opcode == Opcode.INVOKE_INTERFACE_RANGE || opcode == Opcode.INVOKE_INTERFACE) && + reference?.returnType == "Ljava/lang/String;" && + reference.parameterTypes.isEmpty() + } PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR = getInstruction(playerResponseModelIndex) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/Fingerprints.kt index 0564715e1..450ce37ea 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/Fingerprints.kt @@ -2,9 +2,19 @@ package app.revanced.patches.music.video.playerresponse import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or +import app.revanced.util.parametersEqual import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +private val PLAYER_PARAMETER_STARTS_WITH_PARAMETER_LIST = listOf( + "Ljava/lang/String;", // VideoId. + "[B", + "Ljava/lang/String;", // Player parameters proto buffer. + "Ljava/lang/String;", // PlaylistId. + "I", // PlaylistIndex. + "I" +) + /** * For targets 7.03 and later. */ @@ -12,23 +22,21 @@ internal val playerParameterBuilderFingerprint = legacyFingerprint( name = "playerParameterBuilderFingerprint", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, returnType = "L", - parameters = listOf( - "Ljava/lang/String;", // VideoId. - "[B", - "Ljava/lang/String;", // Player parameters proto buffer. - "Ljava/lang/String;", // PlaylistId. - "I", // PlaylistIndex. - "I", - "L", - "Ljava/util/Set;", - "Ljava/lang/String;", - "Ljava/lang/String;", - "L", - "Z", - "Z", - "Z", // Appears to indicate if the video id is being opened or is currently playing. - ), - strings = listOf("psps") + strings = listOf("psps"), + customFingerprint = custom@{ method, _ -> + val parameterTypes = method.parameterTypes + val parameterSize = parameterTypes.size + if (parameterSize < 13) { + return@custom false + } + + val startsWithMethodParameterList = parameterTypes.slice(0..5) + + parametersEqual( + PLAYER_PARAMETER_STARTS_WITH_PARAMETER_LIST, + startsWithMethodParameterList + ) + } ) /**