fix(YouTube/Spoof streaming data) : app crashes when loading ads in Shorts

This commit is contained in:
inotia00 2024-09-01 21:58:32 +09:00
parent c285c6231c
commit 3ca97f9292
3 changed files with 16 additions and 87 deletions

View File

@ -5,19 +5,18 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.utils.compatibility.Constants 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.BuildInitPlaybackRequestFingerprint
import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildMediaDataSourceFingerprint 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.CreateStreamingDataFingerprint
import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.NerdsStatsVideoFormatBuilderFingerprint 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.fix.streamingdata.fingerprints.ProtobufClassParseByteBufferFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.youtube.utils.settings.SettingsPatch 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.getReference
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
@ -33,13 +32,13 @@ object SpoofStreamingDataPatch : BaseBytecodePatch(
dependencies = setOf( dependencies = setOf(
SettingsPatch::class, SettingsPatch::class,
SpoofUserAgentPatch::class, SpoofUserAgentPatch::class,
VideoIdPatch::class,
), ),
compatiblePackages = Constants.COMPATIBLE_PACKAGE, compatiblePackages = Constants.COMPATIBLE_PACKAGE,
fingerprints = setOf( fingerprints = setOf(
BuildBrowseRequestFingerprint,
BuildInitPlaybackRequestFingerprint, BuildInitPlaybackRequestFingerprint,
BuildMediaDataSourceFingerprint, BuildMediaDataSourceFingerprint,
BuildPlayerRequestURIFingerprint,
BuildRequestFingerprint,
CreateStreamingDataFingerprint, CreateStreamingDataFingerprint,
ProtobufClassParseByteBufferFingerprint, ProtobufClassParseByteBufferFingerprint,
@ -49,10 +48,6 @@ object SpoofStreamingDataPatch : BaseBytecodePatch(
) { ) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$MISC_PATH/SpoofStreamingDataPatch;" "$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) { override fun execute(context: BytecodeContext) {
@ -76,51 +71,16 @@ object SpoofStreamingDataPatch : BaseBytecodePatch(
// endregion // endregion
// region Block /get_watch requests to fall back to /player requests. // region Copy request headers for streaming data fetch.
BuildPlayerRequestURIFingerprint.resultOrThrow().let { BuildBrowseRequestFingerprint.resultOrThrow().let { result ->
it.mutableMethod.apply {
val invokeToStringIndex =
BuildPlayerRequestURIFingerprint.indexOfToStringInstruction(this)
val uriRegister =
getInstruction<FiveRegisterInstruction>(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 ->
result.mutableMethod.apply { result.mutableMethod.apply {
val buildRequestIndex =
BuildRequestFingerprint.indexOfBuildUrlRequestInstruction(this)
val requestBuilderRegister =
getInstruction<FiveRegisterInstruction>(buildRequestIndex).registerC
val newRequestBuilderIndex = val newRequestBuilderIndex =
BuildRequestFingerprint.indexOfNewUrlRequestBuilderInstruction(this) BuildBrowseRequestFingerprint.indexOfNewUrlRequestBuilderInstruction(this)
val urlRegister = val urlRegister =
getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD getInstruction<FiveRegisterInstruction>(newRequestBuilderIndex).registerD
// Replace "requestBuilder.build()" with integrations call. val entrySetIndex = BuildBrowseRequestFingerprint.indexOfEntrySetInstruction(this)
replaceInstruction(
buildRequestIndex,
"invoke-static { v$requestBuilderRegister }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->" +
"buildRequest($REQUEST_BUILDER_CLASS_DESCRIPTOR)" +
REQUEST_CLASS_DESCRIPTOR
)
val entrySetIndex = BuildRequestFingerprint.indexOfEntrySetInstruction(this)
val mapRegister = if (entrySetIndex < 0) val mapRegister = if (entrySetIndex < 0)
urlRegister + 1 urlRegister + 1
else else
@ -129,7 +89,7 @@ object SpoofStreamingDataPatch : BaseBytecodePatch(
var smaliInstructions = var smaliInstructions =
"invoke-static { v$urlRegister, v$mapRegister }, " + "invoke-static { v$urlRegister, v$mapRegister }, " +
"$INTEGRATIONS_CLASS_DESCRIPTOR->" + "$INTEGRATIONS_CLASS_DESCRIPTOR->" +
"setHeader(Ljava/lang/String;Ljava/util/Map;)V" "setFetchHeaders(Ljava/lang/String;Ljava/util/Map;)V"
if (entrySetIndex < 0) smaliInstructions = """ if (entrySetIndex < 0) smaliInstructions = """
move-object/from16 v$mapRegister, p1 move-object/from16 v$mapRegister, p1
@ -257,6 +217,9 @@ object SpoofStreamingDataPatch : BaseBytecodePatch(
// endregion // endregion
// Prefetch streaming data.
VideoIdPatch.hookPlayerResponseVideoId("$INTEGRATIONS_CLASS_DESCRIPTOR->fetchStreamingData(Ljava/lang/String;Z)V")
/** /**
* Add settings * Add settings
*/ */

View File

@ -1,23 +1,21 @@
package app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints package app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint 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.BuildBrowseRequestFingerprint.indexOfEntrySetInstruction
import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildRequestFingerprint.indexOfEntrySetInstruction import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildBrowseRequestFingerprint.indexOfNewUrlRequestBuilderInstruction
import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildRequestFingerprint.indexOfNewUrlRequestBuilderInstruction import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildBrowseRequestFingerprint.indexOfRequestFinishedListenerInstruction
import app.revanced.patches.youtube.utils.fix.streamingdata.fingerprints.BuildRequestFingerprint.indexOfRequestFinishedListenerInstruction
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal object BuildRequestFingerprint : MethodFingerprint( internal object BuildBrowseRequestFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.implementation != null && methodDef.implementation != null &&
indexOfRequestFinishedListenerInstruction(methodDef) >= 0 && indexOfRequestFinishedListenerInstruction(methodDef) >= 0 &&
!methodDef.definingClass.startsWith("Lorg/") && !methodDef.definingClass.startsWith("Lorg/") &&
indexOfNewUrlRequestBuilderInstruction(methodDef) >= 0 && indexOfNewUrlRequestBuilderInstruction(methodDef) >= 0 &&
indexOfBuildUrlRequestInstruction(methodDef) >= 0 &&
// YouTube 17.34.36 ~ YouTube 18.35.36 // YouTube 17.34.36 ~ YouTube 18.35.36
(indexOfEntrySetInstruction(methodDef) >= 0 || (indexOfEntrySetInstruction(methodDef) >= 0 ||
// YouTube 18.36.39 ~ // YouTube 18.36.39 ~
@ -36,12 +34,6 @@ internal object BuildRequestFingerprint : MethodFingerprint(
getReference<MethodReference>().toString() == "Lorg/chromium/net/CronetEngine;->newUrlRequestBuilder(Ljava/lang/String;Lorg/chromium/net/UrlRequest${'$'}Callback;Ljava/util/concurrent/Executor;)Lorg/chromium/net/UrlRequest${'$'}Builder;" getReference<MethodReference>().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<MethodReference>().toString() == "Lorg/chromium/net/ExperimentalUrlRequest${'$'}Builder;->build()Lorg/chromium/net/ExperimentalUrlRequest;"
}
fun indexOfEntrySetInstruction(methodDef: Method) = fun indexOfEntrySetInstruction(methodDef: Method) =
methodDef.indexOfFirstInstruction { methodDef.indexOfFirstInstruction {
opcode == Opcode.INVOKE_INTERFACE && opcode == Opcode.INVOKE_INTERFACE &&

View File

@ -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<MethodReference>().toString() == "Landroid/net/Uri;->toString()Ljava/lang/String;"
}
}