From 1ef8639a7a39a36d3aa49b8d94674422a01e58c4 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 15 Sep 2024 18:38:19 +0900 Subject: [PATCH] feat(YouTube/Spoof streaming data): match with ReVanced --- .../streamingdata/SpoofStreamingDataPatch.kt | 50 ++++++++++++------- .../BuildPlayerRequestURIFingerprint.kt | 26 ++++++++++ 2 files changed, 59 insertions(+), 17 deletions(-) create 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 3c032f5ba7..33e00dc9ad 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 @@ -11,12 +11,13 @@ 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.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.findOpcodeIndicesReversed import app.revanced.util.getReference import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.resultOrThrow @@ -32,13 +33,13 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( dependencies = setOf( SettingsPatch::class, SpoofUserAgentPatch::class, - VideoIdPatch::class, ), compatiblePackages = Constants.COMPATIBLE_PACKAGE, fingerprints = setOf( BuildBrowseRequestFingerprint, BuildInitPlaybackRequestFingerprint, BuildMediaDataSourceFingerprint, + BuildPlayerRequestURIFingerprint, CreateStreamingDataFingerprint, ProtobufClassParseByteBufferFingerprint, @@ -51,6 +52,27 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( override fun execute(context: BytecodeContext) { + // region Block /get_watch requests to fall back to /player requests. + + 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 Block /initplayback requests to fall back to /get_watch requests. BuildInitPlaybackRequestFingerprint.resultOrThrow().let { @@ -71,7 +93,7 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( // endregion - // region Copy request headers for streaming data fetch. + // region Fetch replacement streams. BuildBrowseRequestFingerprint.resultOrThrow().let { result -> result.mutableMethod.apply { @@ -89,7 +111,7 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( var smaliInstructions = "invoke-static { v$urlRegister, v$mapRegister }, " + "$INTEGRATIONS_CLASS_DESCRIPTOR->" + - "setFetchHeaders(Ljava/lang/String;Ljava/util/Map;)V" + "fetchStreams(Ljava/lang/String;Ljava/util/Map;)V" if (entrySetIndex < 0) smaliInstructions = """ move-object/from16 v$mapRegister, p1 @@ -160,6 +182,7 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( iget-object v$freeRegister, v$freeRegister, $getStreamingDataField if-eqz v0, :disabled iput-object v$freeRegister, p0, $setStreamingDataField + """, ExternalLabel("disabled", getInstruction(insertIndex)) ) @@ -189,7 +212,7 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( invoke-static { v1, v2, v3 }, $INTEGRATIONS_CLASS_DESCRIPTOR->removeVideoPlaybackPostBody(Landroid/net/Uri;I[B)[B move-result-object v1 iput-object v1, v0, $definingClass->d:[B - """, + """, ) } } @@ -199,27 +222,20 @@ object SpoofStreamingDataPatch : BaseBytecodePatch( // region Append spoof info. NerdsStatsVideoFormatBuilderFingerprint.resultOrThrow().mutableMethod.apply { - for (index in implementation!!.instructions.size - 1 downTo 0) { - val instruction = getInstruction(index) - if (instruction.opcode != Opcode.RETURN_OBJECT) - continue - - val register = (instruction as OneRegisterInstruction).registerA + findOpcodeIndicesReversed(Opcode.RETURN_OBJECT).forEach{ index -> + val register = getInstruction(index).registerA addInstructions( index, """ - invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->appendSpoofedClient(Ljava/lang/String;)Ljava/lang/String; - move-result-object v$register - """ + invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->appendSpoofedClient(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$register + """ ) } } // 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/BuildPlayerRequestURIFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildPlayerRequestURIFingerprint.kt new file mode 100644 index 0000000000..b2601154e4 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/fingerprints/BuildPlayerRequestURIFingerprint.kt @@ -0,0 +1,26 @@ +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;" + } +} \ No newline at end of file