feat(YouTube): Support version 18.29.38

This commit is contained in:
oSumAtrIX 2023-08-02 01:35:40 +02:00
parent 134e66aa79
commit c1b9eefa28
32 changed files with 214 additions and 334 deletions

View file

@ -0,0 +1,12 @@
package app.revanced.patches.shared.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object LayoutConstructorFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = emptyList(),
strings = listOf("1.0x")
)

View file

@ -1,12 +0,0 @@
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.interaction.seekbar.patch.EnableSeekbarTappingResourcePatch
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
object AccessibilityPlayerProgressTimeFingerprint : LiteralValueFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
literal = EnableSeekbarTappingResourcePatch.accessibilityPlayerProgressTime
)

View file

@ -0,0 +1,32 @@
package app.revanced.patches.youtube.interaction.seekbar.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(3)
object OnTouchEventHandlerFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.PUBLIC,
parameters = listOf("L"),
opcodes = listOf(
Opcode.INVOKE_VIRTUAL, // oMethodReference
Opcode.RETURN,
Opcode.IGET_OBJECT,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN,
Opcode.INT_TO_FLOAT,
Opcode.INT_TO_FLOAT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.RETURN,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL, // pMethodReference
),
customFingerprint = { methodDef, _ -> methodDef.name == "onTouchEvent" }
)

View file

@ -13,13 +13,15 @@ import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility import app.revanced.patches.youtube.interaction.seekbar.annotation.SeekbarTappingCompatibility
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.AccessibilityPlayerProgressTimeFingerprint import app.revanced.patches.youtube.interaction.seekbar.fingerprints.OnTouchEventHandlerFingerprint
import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingFingerprint import app.revanced.patches.youtube.interaction.seekbar.fingerprints.SeekbarTappingFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
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.instruction.NarrowLiteralInstruction import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch @Patch
@DependsOn([IntegrationsPatch::class, EnableSeekbarTappingResourcePatch::class]) @DependsOn([IntegrationsPatch::class, EnableSeekbarTappingResourcePatch::class])
@ -27,37 +29,23 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@Description("Enables tap-to-seek on the seekbar of the video player.") @Description("Enables tap-to-seek on the seekbar of the video player.")
@SeekbarTappingCompatibility @SeekbarTappingCompatibility
class EnableSeekbarTappingPatch : BytecodePatch( class EnableSeekbarTappingPatch : BytecodePatch(
listOf(AccessibilityPlayerProgressTimeFingerprint, SeekbarTappingFingerprint) listOf(OnTouchEventHandlerFingerprint, SeekbarTappingFingerprint)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
// Find the required methods to tap the seekbar. // Find the required methods to tap the seekbar.
val seekbarTappingMethods = val seekbarTappingMethods = OnTouchEventHandlerFingerprint.result?.let {
AccessibilityPlayerProgressTimeFingerprint.result?.classDef?.methods?.let { methods -> val patternScanResult = it.scanResult.patternScanResult!!
buildMap {
// find the methods which tap the seekbar
methods.forEach { method ->
if (method.implementation == null) return@forEach
val instructions = method.implementation!!.instructions fun getReference(index: Int) = it.mutableMethod.getInstruction<ReferenceInstruction>(index)
.reference as MethodReference
// The method has more than 7 instructions. buildMap {
if (instructions.count() < 7) return@forEach put("O", getReference(patternScanResult.endIndex))
put("N", getReference(patternScanResult.startIndex))
// The 7th instruction has the opcode CONST_4.
val instruction = instructions.elementAt(6)
if (instruction.opcode != Opcode.CONST_4) return@forEach
// the literal for this instruction has to be either 1 or 2.
val literal = (instruction as NarrowLiteralInstruction).narrowLiteral
// Based on the literal, determine which method is which.
if (literal == 1) this["P"] = method
if (literal == 2) this["O"] = method
}
}
} }
}
seekbarTappingMethods ?: return AccessibilityPlayerProgressTimeFingerprint.toErrorResult() seekbarTappingMethods ?: return OnTouchEventHandlerFingerprint.toErrorResult()
SeekbarTappingFingerprint.result?.let { SeekbarTappingFingerprint.result?.let {
val insertIndex = it.scanResult.patternScanResult!!.endIndex - 1 val insertIndex = it.scanResult.patternScanResult!!.endIndex - 1
@ -68,11 +56,11 @@ class EnableSeekbarTappingPatch : BytecodePatch(
val freeRegister = 0 val freeRegister = 0
val xAxisRegister = 2 val xAxisRegister = 2
val pMethod = seekbarTappingMethods["P"]!!
val oMethod = seekbarTappingMethods["O"]!! val oMethod = seekbarTappingMethods["O"]!!
val nMethod = seekbarTappingMethods["N"]!!
fun Method.toInvokeInstructionString() = fun MethodReference.toInvokeInstructionString() =
"invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $definingClass->$name(I)V" "invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $this"
addInstructionsWithLabels( addInstructionsWithLabels(
insertIndex, insertIndex,
@ -81,7 +69,7 @@ class EnableSeekbarTappingPatch : BytecodePatch(
move-result v$freeRegister move-result v$freeRegister
if-eqz v$freeRegister, :disabled if-eqz v$freeRegister, :disabled
${oMethod.toInvokeInstructionString()} ${oMethod.toInvokeInstructionString()}
${pMethod.toInvokeInstructionString()} ${nMethod.toInvokeInstructionString()}
""", """,
ExternalLabel("disabled", getInstruction(insertIndex)) ExternalLabel("disabled", getInstruction(insertIndex))
) )

View file

@ -2,16 +2,14 @@ package app.revanced.patches.youtube.interaction.seekbar.patch
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@DependsOn([SettingsPatch::class, ResourceMappingPatch::class]) @DependsOn([SettingsPatch::class])
class EnableSeekbarTappingResourcePatch : ResourcePatch { class EnableSeekbarTappingResourcePatch : ResourcePatch {
override fun execute(context: ResourceContext): PatchResult { override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences( SettingsPatch.PreferenceScreen.INTERACTIONS.addPreferences(
@ -22,15 +20,6 @@ class EnableSeekbarTappingResourcePatch : ResourcePatch {
StringResource("revanced_seekbar_tapping_summary_off", "Seekbar tapping is disabled") StringResource("revanced_seekbar_tapping_summary_off", "Seekbar tapping is disabled")
) )
) )
accessibilityPlayerProgressTime = ResourceMappingPatch.resourceMappings.find {
it.name == "accessibility_player_progress_time"
}?.id ?: return PatchResultError("Failed to find required resource")
return PatchResultSuccess() return PatchResultSuccess()
} }
internal companion object {
var accessibilityPlayerProgressTime = -1L
}
} }

View file

@ -19,8 +19,5 @@ object SubtitleButtonControllerFingerprint : MethodFingerprint(
Opcode.CONST, Opcode.CONST,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
), )
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("SubtitleButtonController;")
}
) )

View file

@ -1,10 +0,0 @@
package app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object LayoutConstructorFingerprint : MethodFingerprint(
strings = listOf("1.0x"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
}
)

View file

@ -17,7 +17,7 @@ import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.buttons.autoplay.annotations.AutoplayButtonCompatibility import app.revanced.patches.youtube.layout.buttons.autoplay.annotations.AutoplayButtonCompatibility
import app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints.LayoutConstructorFingerprint import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction

View file

@ -38,12 +38,12 @@ class HideCaptionsButtonPatch : BytecodePatch(listOf(
val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod
// Due to previously applied patches, scanResult index cannot be used in this context // Due to previously applied patches, scanResult index cannot be used in this context
val igetBooleanIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst { val insertIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst {
it.opcode == Opcode.IGET_BOOLEAN it.opcode == Opcode.IGET_BOOLEAN
} } + 1
subtitleButtonControllerMethod.addInstruction( subtitleButtonControllerMethod.addInstruction(
igetBooleanIndex + 1, insertIndex,
""" """
invoke-static {v0}, Lapp/revanced/integrations/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V invoke-static {v0}, Lapp/revanced/integrations/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V
""" """

View file

@ -1,15 +1,10 @@
package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch
import com.android.tools.smali.dexlib2.AccessFlags import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
object HideLoadMoreButtonFingerprint : LiteralValueFingerprint( object HideLoadMoreButtonFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L", "L", "L", "L"),
opcodes = listOf( opcodes = listOf(
Opcode.CONST, Opcode.CONST,
Opcode.CONST_4, Opcode.CONST_4,

View file

@ -17,7 +17,6 @@ object CreatePlayerOverviewFingerprint : MethodFingerprint(
Opcode.CHECK_CAST Opcode.CHECK_CAST
), ),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubeControlsOverlay;") methodDef.containsConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId)
&& methodDef.containsConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId)
} }
) )

View file

@ -1,28 +1,24 @@
package app.revanced.patches.youtube.layout.hide.time.fingerprints package app.revanced.patches.youtube.layout.hide.time.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(1)
object TimeCounterFingerprint : MethodFingerprint( object TimeCounterFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
parameters = listOf(),
returnType = "V",
opcodes = listOf(
Opcode.SUB_LONG_2ADDR,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.IGET_WIDE, Opcode.IGET_WIDE,
Opcode.INVOKE_STATIC, Opcode.CONST_WIDE_16,
Opcode.MOVE_RESULT_OBJECT, Opcode.CMP_LONG,
Opcode.INVOKE_INTERFACE, Opcode.IF_LEZ,
Opcode.RETURN_VOID, Opcode.IGET_OBJECT,
), Opcode.IF_EQZ,
customFingerprint = { _, classDef -> Opcode.INVOKE_VIRTUAL,
// On older devices this fingerprint resolves very slowly. Opcode.MOVE_RESULT,
// Speed this up by checking for the number of methods. Opcode.IF_EQZ,
classDef.methods.count() == 14 Opcode.GOTO,
} )
) )

View file

@ -1,8 +0,0 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
@Target(AnnotationTarget.CLASS)
internal annotation class FullscreenPanelsCompatibility

View file

@ -1,11 +0,0 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
object FullscreenViewAdderFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.IGET_BOOLEAN
)
)

View file

@ -1,20 +0,0 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
object FullscreenViewAdderParentFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("Landroid/content/Context;", "Landroid/view/View;"),
opcodes = listOf(
Opcode.GOTO,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQ,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("FullscreenEngagementPanelOverlay;")
}
)

View file

@ -1,63 +0,0 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations.FullscreenPanelsCompatibility
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints.FullscreenViewAdderFingerprint
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints.FullscreenViewAdderParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Patch
@Name("Disable fullscreen panels")
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Description("Disables video description and comments panel in fullscreen view.")
@FullscreenPanelsCompatibility
class FullscreenPanelsRemoverPatch : BytecodePatch(
listOf(
FullscreenViewAdderParentFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_fullscreen_panels",
StringResource("revanced_hide_fullscreen_panels_title", "Hide fullscreen panels"),
StringResource("revanced_hide_fullscreen_panels_summary_on", "Fullscreen panels are hidden"),
StringResource("revanced_hide_fullscreen_panels_summary_off", "Fullscreen panels are shown")
)
)
val parentResult = FullscreenViewAdderParentFingerprint.result!!
FullscreenViewAdderFingerprint.resolve(context, parentResult.method, parentResult.classDef)
val result = FullscreenViewAdderParentFingerprint.result
?: return PatchResultError("Fingerprint not resolved!")
val method = result.mutableMethod
val ifIndex = result.scanResult.patternScanResult!!.startIndex + 2
method.removeInstruction(ifIndex)
method.addInstructions(
ifIndex,
"""
invoke-static {}, Lapp/revanced/integrations/patches/FullscreenPanelsRemoverPatch;->getFullscreenPanelsVisibility()I
move-result p1
"""
)
return PatchResultSuccess()
}
}

View file

@ -1,12 +1,12 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
object ShortsTextViewFingerprint : MethodFingerprint( object ShortsTextViewFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, // 18.29.38 method is public final visibility, but in 18.23.35 and older it's protected final.
// If 18.23.35 is dropped then accessFlags should be specified here.
returnType = "V", returnType = "V",
parameters = listOf("L", "L"), parameters = listOf("L", "L"),
opcodes = listOf( opcodes = listOf(

View file

@ -15,7 +15,7 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
opcodes = listOf( opcodes = listOf(
Opcode.MOVE_OBJECT_FROM16, // available unused register Opcode.MOVE_OBJECT_FROM16, // available unused register
Opcode.MOVE_OBJECT_FROM16, Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_OBJECT_FROM16, null, // move-object/from16 or move/from16
Opcode.MOVE_OBJECT_FROM16, Opcode.MOVE_OBJECT_FROM16,
Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,

View file

@ -19,9 +19,6 @@ object ControlsOverlayFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST, Opcode.CHECK_CAST,
Opcode.NEW_INSTANCE, Opcode.NEW_INSTANCE
), )
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/google/android/apps/youtube/app/player/overlay/YouTubeControlsOverlay;"
}
) )

View file

@ -17,6 +17,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.shared.fingerprints.SeekbarFingerprint import app.revanced.patches.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
@ -59,23 +60,16 @@ class SponsorBlockBytecodePatch : BytecodePatch(
listOf( listOf(
SeekbarFingerprint, SeekbarFingerprint,
AppendTimeFingerprint, AppendTimeFingerprint,
ControlsOverlayFingerprint, LayoutConstructorFingerprint,
AutoRepeatParentFingerprint, AutoRepeatParentFingerprint,
) )
) { ) {
private companion object {
const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;"
const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;"
const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;"
const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;"
}
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
LayoutConstructorFingerprint.result?.let {
if (!ControlsOverlayFingerprint.resolve(context, it.classDef))
throw ControlsOverlayFingerprint.toErrorResult()
} ?: return LayoutConstructorFingerprint.toErrorResult()
/* /*
* Hook the video time methods * Hook the video time methods
*/ */
@ -279,4 +273,15 @@ class SponsorBlockBytecodePatch : BytecodePatch(
return PatchResultSuccess() return PatchResultSuccess()
} }
private companion object {
const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;"
const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;"
const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;"
const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;"
}
} }

View file

@ -3,21 +3,10 @@ package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object MiniPlayerOverrideFingerprint : MethodFingerprint( object MiniPlayerOverrideFingerprint : MethodFingerprint(
"Z", AccessFlags.STATIC or AccessFlags.PUBLIC, returnType = "L",
listOf("Landroid/content/Context;"), accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
opcodes = listOf( parameters = listOf("L"),
Opcode.INVOKE_STATIC, strings = listOf("appName")
Opcode.MOVE_RESULT,
Opcode.CONST_4,
Opcode.IF_EQ,
Opcode.CONST_4,
Opcode.IF_EQ,
Opcode.CONST_4, // override this value
Opcode.RETURN,
Opcode.CONST_4, // override this value
Opcode.RETURN
),
) )

View file

@ -1,7 +0,0 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object MiniPlayerOverrideParentFingerprint : MethodFingerprint(
strings = listOf("Unset or unknown Input OneOf case for dynamic input")
)

View file

@ -4,6 +4,7 @@ import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
@ -17,7 +18,10 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.settings.preference.impl.StringResource import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.* import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorParentFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -32,7 +36,7 @@ class TabletMiniPlayerPatch : BytecodePatch(
listOf( listOf(
MiniPlayerDimensionsCalculatorParentFingerprint, MiniPlayerDimensionsCalculatorParentFingerprint,
MiniPlayerResponseModelSizeCheckFingerprint, MiniPlayerResponseModelSizeCheckFingerprint,
MiniPlayerOverrideParentFingerprint MiniPlayerOverrideFingerprint
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
@ -62,33 +66,33 @@ class TabletMiniPlayerPatch : BytecodePatch(
/** same register used to return **/ /** same register used to return **/
) )
/*
* Method with context parameter.
*/
MiniPlayerOverrideParentFingerprint.result?.let {
if (!MiniPlayerOverrideFingerprint.resolve(context, it.classDef))
throw MiniPlayerOverrideFingerprint.toErrorResult()
} ?: return MiniPlayerOverrideParentFingerprint.toErrorResult()
/* /*
* Override every return instruction with the proxy call. * Override every return instruction with the proxy call.
*/ */
MiniPlayerOverrideFingerprint.result!!.mutableMethod.apply { MiniPlayerOverrideFingerprint.result?.let { result ->
implementation!!.let { implementation -> result.mutableMethod.let { method ->
val returnIndices = implementation.instructions val appNameStringIndex = result.scanResult.stringsScanResult!!.matches.first().index + 2
.withIndex() context.toMethodWalker(method).nextMethod(appNameStringIndex, true)
.filter { (_, instruction) -> instruction.opcode == Opcode.RETURN } .getMethod() as MutableMethod
.map { (index, _) -> index } }.apply {
implementation!!.let { implementation ->
val returnIndices = implementation.instructions
.withIndex()
.filter { (_, instruction) -> instruction.opcode == Opcode.RETURN }
.map { (index, _) -> index }
if (returnIndices.isEmpty()) throw PatchResultError("No return instructions found.") if (returnIndices.isEmpty()) throw PatchResultError("No return instructions found.")
// This method clobbers register p0 to return the value, calculate to override. // This method clobbers register p0 to return the value, calculate to override.
val returnedRegister = implementation.registerCount - parameters.size val returnedRegister = implementation.registerCount - parameters.size
// Hook the returned register on every return instruction. // Hook the returned register on every return instruction.
returnIndices.forEach { index -> insertOverride(index, returnedRegister) } returnIndices.forEach { index -> insertOverride(index, returnedRegister) }
}
} }
}
return@let
} ?: return MiniPlayerOverrideFingerprint.toErrorResult()
/* /*
* Size check return value override. * Size check return value override.

View file

@ -4,22 +4,31 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint( object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("I", "L", "L"), parameters = listOf("I", "L", "L"),
opcodes = listOf( opcodes = listOf(
Opcode.IF_EQZ, Opcode.CONST_4,
Opcode.IF_NE,
Opcode.SGET_OBJECT, Opcode.SGET_OBJECT,
Opcode.IF_NE, Opcode.IF_NE,
Opcode.CONST_4,
Opcode.IPUT_BOOLEAN,
Opcode.IF_EQZ,
Opcode.IGET, Opcode.IGET,
Opcode.INVOKE_STATIC Opcode.CONST_4,
Opcode.IF_NE,
Opcode.IGET_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IF_EQ,
Opcode.GOTO,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
), ),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("MinimizedPlaybackPolicyController;") methodDef.implementation!!.instructions.any {
((it as? NarrowLiteralInstruction)?.narrowLiteral == 5)
}
} }
) )

View file

@ -1,14 +1,17 @@
package app.revanced.patches.youtube.misc.playercontrols.bytecode.patch package app.revanced.patches.youtube.misc.playercontrols.bytecode.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility import app.revanced.patches.youtube.misc.playercontrols.annotation.PlayerControlsCompatibility
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint import app.revanced.patches.youtube.misc.playercontrols.fingerprints.BottomControlsInflateFingerprint
import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint import app.revanced.patches.youtube.misc.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
@ -20,9 +23,17 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Description("Manages the code for the player controls of the YouTube player.") @Description("Manages the code for the player controls of the YouTube player.")
@PlayerControlsCompatibility @PlayerControlsCompatibility
class PlayerControlsBytecodePatch : BytecodePatch( class PlayerControlsBytecodePatch : BytecodePatch(
listOf(PlayerControlsVisibilityFingerprint, BottomControlsInflateFingerprint) listOf(
LayoutConstructorFingerprint,
BottomControlsInflateFingerprint
)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
LayoutConstructorFingerprint.result?.let {
if (!PlayerControlsVisibilityFingerprint.resolve(context, it.classDef))
throw LayoutConstructorFingerprint.toErrorResult()
} ?: return LayoutConstructorFingerprint.toErrorResult()
showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!! showPlayerControlsFingerprintResult = PlayerControlsVisibilityFingerprint.result!!
inflateFingerprintResult = BottomControlsInflateFingerprint.result!! inflateFingerprintResult = BottomControlsInflateFingerprint.result!!

View file

@ -7,8 +7,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
object PlayerControlsVisibilityFingerprint : MethodFingerprint( object PlayerControlsVisibilityFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
returnType = "V", returnType = "V",
parameters = listOf("Z", "Z"), parameters = listOf("Z", "Z")
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
}
) )

View file

@ -10,26 +10,8 @@ object PlayerTypeFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"), parameters = listOf("L"),
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IF_NE, Opcode.IF_NE,
Opcode.RETURN_VOID,
Opcode.IPUT_OBJECT,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.RETURN_VOID,
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID Opcode.RETURN_VOID
), ),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/YouTubePlayerOverlaysLayout;") }
methodDef.definingClass.endsWith("YouTubePlayerOverlaysLayout;")
}
) )

View file

@ -17,8 +17,5 @@ object VideoStateFingerprint : MethodFingerprint(
Opcode.IF_EQZ, Opcode.IF_EQZ,
Opcode.IF_EQZ, Opcode.IF_EQZ,
Opcode.IGET_OBJECT, // obfuscated parameter field name Opcode.IGET_OBJECT, // obfuscated parameter field name
), )
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
}
) )

View file

@ -12,33 +12,27 @@ import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.playertype.annotation.PlayerTypeHookCompatibility
import app.revanced.patches.youtube.misc.playertype.fingerprint.PlayerTypeFingerprint import app.revanced.patches.youtube.misc.playertype.fingerprint.PlayerTypeFingerprint
import app.revanced.patches.youtube.misc.playertype.fingerprint.VideoStateFingerprint import app.revanced.patches.youtube.misc.playertype.fingerprint.VideoStateFingerprint
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
@Name("Player type hook") @Name("Player type hook")
@Description("Hook to get the current player type and video playback state.") @Description("Hook to get the current player type and video playback state.")
@PlayerTypeHookCompatibility
@DependsOn([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class])
class PlayerTypeHookPatch : BytecodePatch( class PlayerTypeHookPatch : BytecodePatch(
listOf(PlayerTypeFingerprint, VideoStateFingerprint) listOf(PlayerTypeFingerprint, VideoStateFingerprint)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
PlayerTypeFingerprint.result?.mutableMethod?.addInstruction(
PlayerTypeFingerprint.result?.let { 0,
it.mutableMethod.apply { "invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V"
addInstruction( ) ?: return PlayerTypeFingerprint.toErrorResult()
0,
"invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->setPlayerType(Ljava/lang/Enum;)V"
)
}
} ?: return PlayerTypeFingerprint.toErrorResult()
VideoStateFingerprint.result?.let { VideoStateFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val endIndex = it.scanResult.patternScanResult!!.endIndex val endIndex = it.scanResult.patternScanResult!!.endIndex
val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference val videoStateFieldName = getInstruction<ReferenceInstruction>(endIndex).reference
addInstructions( addInstructions(
0, 0,
""" """

View file

@ -10,6 +10,7 @@ object VideoIdFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"), parameters = listOf("L"),
opcodes = listOf( opcodes = listOf(
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ, Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
@ -23,8 +24,5 @@ object VideoIdFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE, Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT Opcode.MOVE_RESULT_OBJECT
), )
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("SubtitlesOverlayPresenter;")
}
) )

View file

@ -9,8 +9,21 @@ object VideoIdFingerprintBackgroundPlay : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.DECLARED_SYNCHRONIZED or AccessFlags.FINAL or AccessFlags.PUBLIC, accessFlags = AccessFlags.DECLARED_SYNCHRONIZED or AccessFlags.FINAL or AccessFlags.PUBLIC,
parameters = listOf("L"), parameters = listOf("L"),
opcodes = listOf(Opcode.INVOKE_INTERFACE), opcodes = listOf(
customFingerprint = { methodDef, _ -> Opcode.MONITOR_EXIT,
methodDef.definingClass.endsWith("PlaybackLifecycleMonitor;") Opcode.RETURN_VOID,
} Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.NEW_ARRAY,
Opcode.SGET_OBJECT,
Opcode.APUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.IF_EQZ,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
),
) )

View file

@ -6,6 +6,7 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
@ -25,27 +26,33 @@ class VideoIdPatch : BytecodePatch(
listOf(VideoIdFingerprint, VideoIdFingerprintBackgroundPlay) listOf(VideoIdFingerprint, VideoIdFingerprintBackgroundPlay)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
VideoIdFingerprint.result?.let { result -> /**
val videoIdRegisterInstructionIndex = result.scanResult.patternScanResult!!.endIndex * Supplies the method and register index of the video id register.
*
* @param consumer Consumer that receives the method, insert index and video id register index.
*/
fun MethodFingerprint.setFields(consumer: (MutableMethod, Int, Int) -> Unit) = result?.let { result ->
val videoIdRegisterIndex = result.scanResult.patternScanResult!!.endIndex
result.mutableMethod.let {
val videoIdRegister = it.getInstruction<OneRegisterInstruction>(videoIdRegisterIndex).registerA
val insertIndex = videoIdRegisterIndex + 1
consumer(it, insertIndex, videoIdRegister)
result.mutableMethod.also {
insertMethod = it
}.apply {
videoIdRegister = getInstruction<OneRegisterInstruction>(videoIdRegisterInstructionIndex).registerA
insertIndex = videoIdRegisterInstructionIndex + 1
} }
} ?: return VideoIdFingerprint.toErrorResult() } ?: throw VideoIdFingerprint.toErrorResult()
VideoIdFingerprintBackgroundPlay.result?.let { result -> VideoIdFingerprint.setFields { method, insertIndex, videoIdRegister ->
val endIndex = result.scanResult.patternScanResult!!.endIndex insertMethod = method
VideoIdPatch.insertIndex = insertIndex
VideoIdPatch.videoIdRegister = videoIdRegister
}
result.mutableMethod.also { VideoIdFingerprintBackgroundPlay.setFields { method, insertIndex, videoIdRegister ->
backgroundPlaybackMethod = it backgroundPlaybackMethod = method
}.apply { backgroundPlaybackInsertIndex = insertIndex
backgroundPlaybackVideoIdRegister = getInstruction<OneRegisterInstruction>(endIndex + 1).registerA backgroundPlaybackVideoIdRegister = videoIdRegister
backgroundPlaybackInsertIndex = endIndex + 2 }
}
} ?: return VideoIdFingerprintBackgroundPlay.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }