From 3ca97f929276b6217d3364d222d1f948d6fe2e48 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 1 Sep 2024 21:58:32 +0900 Subject: [PATCH] fix(YouTube/Spoof streaming data) : app crashes when loading ads in Shorts --- .../streamingdata/SpoofStreamingDataPatch.kt | 61 ++++--------------- ...nt.kt => BuildBrowseRequestFingerprint.kt} | 16 ++--- .../BuildPlayerRequestURIFingerprint.kt | 26 -------- 3 files changed, 16 insertions(+), 87 deletions(-) rename src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/{BuildRequestFingerprint.kt => BuildBrowseRequestFingerprint.kt} (73%) delete mode 100644 src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildPlayerRequestURIFingerprint.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt index c16b3d7a13..3c032f5ba7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt @@ -5,19 +5,18 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstructions -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.PatchException import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.utils.compatibility.Constants +import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildBrowseRequestFingerprint import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildInitPlaybackRequestFingerprint import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildMediaDataSourceFingerprint -import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildPlayerRequestURIFingerprint -import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildRequestFingerprint import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.CreateStreamingDataFingerprint import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.NerdsStatsVideoFormatBuilderFingerprint import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.ProtobufClassParseByteBufferFingerprint import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.util.getReference import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow @@ -33,13 +32,13 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( dependencies = setOf( SettingsPatch::class, SpoofUserAgentPatch::class, + VideoIdPatch::class, ), compatiblePackages = Constants.COMPATIBLE_PACKAGE, fingerprints = setOf( + BuildBrowseRequestFingerprint, BuildInitPlaybackRequestFingerprint, BuildMediaDataSourceFingerprint, - BuildPlayerRequestURIFingerprint, - BuildRequestFingerprint, CreateStreamingDataFingerprint, ProtobufClassParseByteBufferFingerprint, @@ -49,10 +48,6 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( ) { private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$MISC_PATH/SpoofStreamingDataPatch;" - private const val REQUEST_CLASS_DESCRIPTOR = - "Lorg/chromium/net/UrlRequest;" - private const val REQUEST_BUILDER_CLASS_DESCRIPTOR = - "Lorg/chromium/net/UrlRequest\$Builder;" override fun execute(context: BytecodeContext) { @@ -76,51 +71,16 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( // endregion - // region Block /get_watch requests to fall back to /player requests. + // region Copy request headers for streaming data fetch. - BuildPlayerRequestURIFingerprint.resultOrThrow().let { - it.mutableMethod.apply { - val invokeToStringIndex = - BuildPlayerRequestURIFingerprint.indexOfToStringInstruction(this) - val uriRegister = - getInstruction(invokeToStringIndex).registerC - - addInstructions( - invokeToStringIndex, - """ - invoke-static { v$uriRegister }, $INTEGRATIONS_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri; - move-result-object v$uriRegister - """, - ) - } - } - - // endregion - - // region Fetch replacement streams. - - BuildRequestFingerprint.resultOrThrow().let { result -> + BuildBrowseRequestFingerprint.resultOrThrow().let { result -> result.mutableMethod.apply { - val buildRequestIndex = - BuildRequestFingerprint.indexOfBuildUrlRequestInstruction(this) - val requestBuilderRegister = - getInstruction(buildRequestIndex).registerC - val newRequestBuilderIndex = - BuildRequestFingerprint.indexOfNewUrlRequestBuilderInstruction(this) + BuildBrowseRequestFingerprint.indexOfNewUrlRequestBuilderInstruction(this) val urlRegister = getInstruction(newRequestBuilderIndex).registerD - // Replace "requestBuilder.build()" with integrations call. - replaceInstruction( - buildRequestIndex, - "invoke-static { v$requestBuilderRegister }, " + - "$INTEGRATIONS_CLASS_DESCRIPTOR->" + - "buildRequest($REQUEST_BUILDER_CLASS_DESCRIPTOR)" + - REQUEST_CLASS_DESCRIPTOR - ) - - val entrySetIndex = BuildRequestFingerprint.indexOfEntrySetInstruction(this) + val entrySetIndex = BuildBrowseRequestFingerprint.indexOfEntrySetInstruction(this) val mapRegister = if (entrySetIndex < 0) urlRegister + 1 else @@ -129,7 +89,7 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( var smaliInstructions = "invoke-static { v$urlRegister, v$mapRegister }, " + "$INTEGRATIONS_CLASS_DESCRIPTOR->" + - "setHeader(Ljava/lang/String;Ljava/util/Map;)V" + "setFetchHeaders(Ljava/lang/String;Ljava/util/Map;)V" if (entrySetIndex < 0) smaliInstructions = """ move-object/from16 v$mapRegister, p1 @@ -257,6 +217,9 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( // endregion + // Prefetch streaming data. + VideoIdPatch.hookPlayerResponseVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->fetchStreamingData(Ljava/lang/String;Z)V") + /** * Add settings */ diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildRequestFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildBrowseRequestFingerprint.kt similarity index 73% rename from src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildRequestFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildBrowseRequestFingerprint.kt index d9f43bfe5d..d59e468193 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildRequestFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildBrowseRequestFingerprint.kt @@ -1,23 +1,21 @@ package app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildRequestFingerprint.indexOfBuildUrlRequestInstruction -import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildRequestFingerprint.indexOfEntrySetInstruction -import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildRequestFingerprint.indexOfNewUrlRequestBuilderInstruction -import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildRequestFingerprint.indexOfRequestFinishedListenerInstruction +import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildBrowseRequestFingerprint.indexOfEntrySetInstruction +import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildBrowseRequestFingerprint.indexOfNewUrlRequestBuilderInstruction +import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildBrowseRequestFingerprint.indexOfRequestFinishedListenerInstruction import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction 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 object BuildRequestFingerprint : MethodFingerprint( +internal object BuildBrowseRequestFingerprint : MethodFingerprint( customFingerprint = { methodDef, _ -> methodDef.implementation != null && indexOfRequestFinishedListenerInstruction(methodDef) >= 0 && !methodDef.definingClass.startsWith("Lorg/") && indexOfNewUrlRequestBuilderInstruction(methodDef) >= 0 && - indexOfBuildUrlRequestInstruction(methodDef) >= 0 && // YouTube 17.34.36 ~ YouTube 18.35.36 (indexOfEntrySetInstruction(methodDef) >= 0 || // YouTube 18.36.39 ~ @@ -36,12 +34,6 @@ internal object BuildRequestFingerprint : MethodFingerprint( getReference().toString() == "Lorg/chromium/net/CronetEngine;->newUrlRequestBuilder(Ljava/lang/String;Lorg/chromium/net/UrlRequest${'$'}Callback;Ljava/util/concurrent/Executor;)Lorg/chromium/net/UrlRequest${'$'}Builder;" } - fun indexOfBuildUrlRequestInstruction(methodDef: Method) = - methodDef.indexOfFirstInstruction { - opcode == Opcode.INVOKE_VIRTUAL && - getReference().toString() == "Lorg/chromium/net/ExperimentalUrlRequest${'$'}Builder;->build()Lorg/chromium/net/ExperimentalUrlRequest;" - } - fun indexOfEntrySetInstruction(methodDef: Method) = methodDef.indexOfFirstInstruction { opcode == Opcode.INVOKE_INTERFACE && diff --git a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildPlayerRequestURIFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildPlayerRequestURIFingerprint.kt deleted file mode 100644 index 4ed9f4c7b5..0000000000 --- a/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildPlayerRequestURIFingerprint.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildPlayerRequestURIFingerprint.indexOfToStringInstruction -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -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 object BuildPlayerRequestURIFingerprint : MethodFingerprint( - returnType = "Ljava/lang/String;", - strings = listOf( - "key", - "asig", - ), - customFingerprint = { methodDef, _ -> - indexOfToStringInstruction(methodDef) >= 0 - }, -) { - fun indexOfToStringInstruction(methodDef: Method) = - methodDef.indexOfFirstInstruction { - opcode == Opcode.INVOKE_VIRTUAL && - getReference().toString() == "Landroid/net/Uri;->toString()Ljava/lang/String;" - } -}