diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt index 3811b761fd..d90018d18d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt @@ -18,29 +18,37 @@ object PlayerResponseMethodHookPatch : BytecodePatch(setOf(PlayerParameterBuilderFingerprint)), Closeable, MutableSet by mutableSetOf() { - private const val VIDEO_ID_PARAMETER = 1 - private const val IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER = 11 - private const val PROTO_BUFFER_PARAMETER_PARAMETER = 3 + private const val VIDEO_ID_PARAMETER = 1 // temp v0 + private const val PROTO_BUFFER_PARAMETER = 3 // temp v1 + private const val IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER = 11 // temp v2 private lateinit var playerResponseMethod: MutableMethod + private var numberOfInstructionsAdded = 0 + override fun execute(context: BytecodeContext) { playerResponseMethod = PlayerParameterBuilderFingerprint.result?.mutableMethod ?: throw PlayerParameterBuilderFingerprint.exception } override fun close() { - fun hookVideoId(hook: Hook) = playerResponseMethod.addInstruction( - 0, "invoke-static {p$VIDEO_ID_PARAMETER, p$IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER}, $hook" - ) + fun hookVideoId(hook: Hook) { + playerResponseMethod.addInstruction( + 0, "invoke-static {v0, v2}, $hook" + ) + numberOfInstructionsAdded++ + } - fun hookProtoBufferParameter(hook: Hook) = playerResponseMethod.addInstructions( - 0, + fun hookProtoBufferParameter(hook: Hook) { + playerResponseMethod.addInstructions( + 0, + """ + invoke-static {v1, v2}, $hook + move-result-object v1 """ - invoke-static {p$PROTO_BUFFER_PARAMETER_PARAMETER, p$IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER}, $hook - move-result-object p$PROTO_BUFFER_PARAMETER_PARAMETER - """ - ) + ) + numberOfInstructionsAdded += 2 + } // Reverse the order in order to preserve insertion order of the hooks. val beforeVideoIdHooks = filterIsInstance().asReversed() @@ -51,6 +59,23 @@ object PlayerResponseMethodHookPatch : afterVideoIdHooks.forEach(::hookProtoBufferParameter) videoIdHooks.forEach(::hookVideoId) beforeVideoIdHooks.forEach(::hookProtoBufferParameter) + + // On some app targets the method has too many registers pushing the parameters past v15. + // Move the parameters to lower registers so they can be passed to integrations. + playerResponseMethod.addInstructions( + 0, """ + move-object/from16 v0, p$VIDEO_ID_PARAMETER + move-object/from16 v1, p$PROTO_BUFFER_PARAMETER + move/from16 v2, p$IS_SHORT_AND_OPENING_OR_PLAYING_PARAMETER + """, + ) + numberOfInstructionsAdded += 3 + + // Move the modified register back. + playerResponseMethod.addInstruction( + numberOfInstructionsAdded, + "move-object/from16 p$PROTO_BUFFER_PARAMETER, v1" + ) } internal abstract class Hook(private val methodDescriptor: String) {