mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-06-12 13:17:46 +02:00
refactor(BytecodeUtils): remove duplicate functions
This commit is contained in:
@ -2,7 +2,7 @@ package app.revanced.patches.youtube.ads.general.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal object ShowDialogCommandFingerprint : MethodFingerprint(
|
||||
@ -16,7 +16,7 @@ internal object ShowDialogCommandFingerprint : MethodFingerprint(
|
||||
// 18.43 and earlier has a different first parameter.
|
||||
// Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures.
|
||||
customFingerprint = custom@{ methodDef, _ ->
|
||||
if (!methodDef.containsWideLiteralInstructionIndex(SlidingDialogAnimation)) {
|
||||
if (!methodDef.containsWideLiteralInstructionValue(SlidingDialogAnimation)) {
|
||||
return@custom false
|
||||
}
|
||||
// 18.43 and earlier parameters are: "L", "L"
|
||||
|
@ -33,11 +33,10 @@ import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.CaptionToggleContainer
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -113,8 +112,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
|
||||
// region patch for hide caption button
|
||||
|
||||
CaptionsButtonFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(CaptionToggleContainer)
|
||||
val insertIndex = getTargetIndexReversedOrThrow(constIndex, Opcode.IF_EQZ)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(CaptionToggleContainer)
|
||||
val insertIndex = indexOfFirstInstructionReversedOrThrow(constIndex, Opcode.IF_EQZ)
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
@ -126,8 +125,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
|
||||
}
|
||||
|
||||
CaptionsButtonSyntheticFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(CaptionToggleContainer)
|
||||
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(CaptionToggleContainer)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
@ -198,7 +197,7 @@ object FeedComponentsPatch : BaseBytecodePatch(
|
||||
&& reference.returnType.startsWith("L")
|
||||
}
|
||||
|
||||
val objectIndex = getTargetIndexOrThrow(Opcode.MOVE_OBJECT)
|
||||
val objectIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_OBJECT)
|
||||
val objectRegister = getInstruction<TwoRegisterInstruction>(objectIndex).registerA
|
||||
|
||||
val jumpIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
@ -253,7 +252,9 @@ object FeedComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
ChannelTabRendererFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val iteratorIndex = getTargetIndexWithMethodReferenceName("hasNext")
|
||||
val iteratorIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "hasNext"
|
||||
}
|
||||
val iteratorRegister =
|
||||
getInstruction<FiveRegisterInstruction>(iteratorIndex).registerC
|
||||
|
||||
@ -265,7 +266,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
|
||||
&& reference.parameterTypes == channelTabBuilderMethod.parameterTypes
|
||||
}
|
||||
|
||||
val objectIndex = getTargetIndexReversedOrThrow(targetIndex, Opcode.IGET_OBJECT)
|
||||
val objectIndex =
|
||||
indexOfFirstInstructionReversedOrThrow(targetIndex, Opcode.IGET_OBJECT)
|
||||
val objectInstruction = getInstruction<TwoRegisterInstruction>(objectIndex)
|
||||
val objectReference = getInstruction<ReferenceInstruction>(objectIndex).reference
|
||||
|
||||
|
@ -7,7 +7,7 @@ import app.revanced.patches.youtube.general.audiotracks.fingerprints.StreamingMo
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexWithReferenceOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
@ -15,6 +15,7 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
object AudioTracksPatch : BaseBytecodePatch(
|
||||
@ -32,15 +33,14 @@ object AudioTracksPatch : BaseBytecodePatch(
|
||||
opcode == Opcode.CHECK_CAST
|
||||
&& (this as ReferenceInstruction).reference.toString() == "Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;"
|
||||
}
|
||||
val arrayListIndex = getTargetIndexWithReferenceOrThrow(
|
||||
formatStreamModelIndex,
|
||||
"Ljava/util/List;->add(Ljava/lang/Object;)Z"
|
||||
)
|
||||
val insertIndex =
|
||||
getTargetIndexWithReferenceOrThrow(
|
||||
arrayListIndex,
|
||||
"Ljava/util/List;->isEmpty()Z"
|
||||
) + 2
|
||||
val arrayListIndex = indexOfFirstInstructionOrThrow(formatStreamModelIndex) {
|
||||
opcode == Opcode.INVOKE_INTERFACE &&
|
||||
getReference<MethodReference>()?.toString() == "Ljava/util/List;->add(Ljava/lang/Object;)Z"
|
||||
}
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(arrayListIndex) {
|
||||
opcode == Opcode.INVOKE_INTERFACE &&
|
||||
getReference<MethodReference>()?.toString() == "Ljava/util/List;->isEmpty()Z"
|
||||
} + 2
|
||||
|
||||
val formatStreamModelRegister =
|
||||
getInstruction<OneRegisterInstruction>(formatStreamModelIndex).registerA
|
||||
|
@ -27,9 +27,9 @@ import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_D
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -37,6 +37,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
@Suppress("unused")
|
||||
@ -171,10 +172,13 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(AccountSwitcherAccessibility)
|
||||
val insertIndex = getTargetIndexOrThrow(constIndex, Opcode.IF_EQZ)
|
||||
val setVisibilityIndex =
|
||||
getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility")
|
||||
val constIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(AccountSwitcherAccessibility)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.IF_EQZ)
|
||||
val setVisibilityIndex = indexOfFirstInstructionOrThrow(insertIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setVisibility"
|
||||
}
|
||||
val visibilityRegister =
|
||||
getInstruction<FiveRegisterInstruction>(setVisibilityIndex).registerD
|
||||
|
||||
@ -209,8 +213,8 @@ object LayoutComponentsPatch : BaseBytecodePatch(
|
||||
// region patch for hide tooltip content
|
||||
|
||||
TooltipContentFullscreenFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val literalIndex = getWideLiteralInstructionIndex(45384061)
|
||||
val targetIndex = getTargetIndexOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(45384061)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
|
@ -10,8 +10,7 @@ import app.revanced.patches.youtube.general.layoutswitch.fingerprints.LayoutSwit
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -34,7 +33,7 @@ object LayoutSwitchPatch : BaseBytecodePatch(
|
||||
|
||||
GetFormFactorFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val jumpIndex = getTargetIndexReversedOrThrow(Opcode.SGET_OBJECT)
|
||||
val jumpIndex = indexOfFirstInstructionReversedOrThrow(Opcode.SGET_OBJECT)
|
||||
|
||||
addInstructionsWithLabels(
|
||||
0, """
|
||||
@ -56,7 +55,7 @@ object LayoutSwitchPatch : BaseBytecodePatch(
|
||||
|
||||
LayoutSwitchFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = getTargetIndexOrThrow(Opcode.IF_NEZ)
|
||||
val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.IF_NEZ)
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -6,7 +6,7 @@ import app.revanced.patches.youtube.general.loadingscreen.fingerprints.GradientL
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
|
||||
@Suppress("unused")
|
||||
@ -29,7 +29,7 @@ object GradientLoadingScreenPatch : BaseBytecodePatch(
|
||||
GradientLoadingScreenPrimaryFingerprint to 45412406,
|
||||
GradientLoadingScreenSecondaryFingerprint to 45418917
|
||||
).forEach { (fingerprint, literal) ->
|
||||
fingerprint.literalInstructionBooleanHook(
|
||||
fingerprint.injectLiteralInstructionBooleanCall(
|
||||
literal,
|
||||
"$GENERAL_CLASS_DESCRIPTOR->enableGradientLoadingScreen()Z"
|
||||
)
|
||||
|
@ -44,8 +44,8 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfWideLiteralInstructionOrThrow
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
@ -170,7 +170,7 @@ object MiniplayerPatch : BaseBytecodePatch(
|
||||
}
|
||||
|
||||
if (SettingsPatch.upward1925) {
|
||||
MiniplayerModernEnabledFingerprint.literalInstructionBooleanHook(
|
||||
MiniplayerModernEnabledFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45622882,
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->getModernMiniplayerOverride(Z)Z"
|
||||
)
|
||||
@ -181,11 +181,11 @@ object MiniplayerPatch : BaseBytecodePatch(
|
||||
// region Enable double tap action.
|
||||
|
||||
if (SettingsPatch.upward1925) {
|
||||
MiniplayerModernConstructorFingerprint.literalInstructionBooleanHook(
|
||||
MiniplayerModernConstructorFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45628823,
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->enableMiniplayerDoubleTapAction()Z"
|
||||
)
|
||||
MiniplayerModernConstructorFingerprint.literalInstructionBooleanHook(
|
||||
MiniplayerModernConstructorFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45630429,
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->getModernMiniplayerOverride(Z)Z"
|
||||
)
|
||||
@ -211,7 +211,8 @@ object MiniplayerPatch : BaseBytecodePatch(
|
||||
YtOutlinePictureInPictureWhite to YtOutlineXWhite,
|
||||
YtOutlineXWhite to YtOutlinePictureInPictureWhite,
|
||||
).forEach { (originalResource, replacementResource) ->
|
||||
val imageResourceIndex = indexOfWideLiteralInstructionOrThrow(originalResource)
|
||||
val imageResourceIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(originalResource)
|
||||
val register =
|
||||
getInstruction<OneRegisterInstruction>(imageResourceIndex).registerA
|
||||
|
||||
@ -321,7 +322,7 @@ object MiniplayerPatch : BaseBytecodePatch(
|
||||
// region Enable drag and drop.
|
||||
|
||||
if (SettingsPatch.upward1923) {
|
||||
MiniplayerModernDragAndDropFingerprint.literalInstructionBooleanHook(
|
||||
MiniplayerModernDragAndDropFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45628752,
|
||||
"$INTEGRATIONS_CLASS_DESCRIPTOR->enableMiniplayerDragAndDrop()Z"
|
||||
)
|
||||
@ -388,7 +389,7 @@ object MiniplayerPatch : BaseBytecodePatch(
|
||||
) {
|
||||
resultOrThrow().mutableMethod.apply {
|
||||
val imageViewIndex = indexOfFirstInstructionOrThrow(
|
||||
indexOfWideLiteralInstructionOrThrow(literalValue)
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(literalValue)
|
||||
) {
|
||||
opcode == Opcode.CHECK_CAST && getReference<TypeReference>()?.type == hookedClassType
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.general.miniplayer.fingerprints.MiniplayerModernConstructorFingerprint.constructorMethodCount
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
@ -13,7 +13,7 @@ internal object MiniplayerModernConstructorFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
parameters = listOf("L"),
|
||||
customFingerprint = custom@{ methodDef, classDef ->
|
||||
if (!methodDef.containsWideLiteralInstructionIndex(45623000)) // Magic number found in the constructor.
|
||||
if (!methodDef.containsWideLiteralInstructionValue(45623000)) // Magic number found in the constructor.
|
||||
return@custom false
|
||||
|
||||
classDef.methods.forEach {
|
||||
@ -24,8 +24,8 @@ internal object MiniplayerModernConstructorFingerprint : MethodFingerprint(
|
||||
return@custom true
|
||||
|
||||
// Double tap action (Used in YouTube 19.25.39+).
|
||||
methodDef.containsWideLiteralInstructionIndex(45628823)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(45630429)
|
||||
methodDef.containsWideLiteralInstructionValue(45628823)
|
||||
&& methodDef.containsWideLiteralInstructionValue(45630429)
|
||||
}
|
||||
) {
|
||||
private var constructorMethodCount = 0
|
||||
|
@ -13,13 +13,16 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PAC
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.navigation.NavigationBarHookPatch
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getStringInstructionIndex
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
object NavigationBarComponentsPatch : BaseBytecodePatch(
|
||||
@ -48,7 +51,7 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
|
||||
// region patch for enable translucent navigation bar
|
||||
|
||||
if (SettingsPatch.upward1923) {
|
||||
TranslucentNavigationBarFingerprint.literalInstructionBooleanHook(
|
||||
TranslucentNavigationBarFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45630927,
|
||||
"$GENERAL_CLASS_DESCRIPTOR->enableTranslucentNavigationBar()Z"
|
||||
)
|
||||
@ -85,7 +88,7 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
AutoMotiveFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = getStringInstructionIndex("Android Automotive") - 1
|
||||
val insertIndex = indexOfFirstStringInstructionOrThrow("Android Automotive") - 1
|
||||
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
@ -103,7 +106,10 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
PivotBarSetTextFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getTargetIndexWithMethodReferenceNameOrThrow("setText")
|
||||
val targetIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setText"
|
||||
}
|
||||
val targetRegister = getInstruction<FiveRegisterInstruction>(targetIndex).registerC
|
||||
|
||||
addInstruction(
|
||||
|
@ -2,13 +2,13 @@ package app.revanced.patches.youtube.general.splashanimation.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkSplashAnimation
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
|
||||
internal object SplashAnimationFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = listOf("Landroid/os/Bundle;"),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.name == "onCreate"
|
||||
&& methodDef.containsWideLiteralInstructionIndex(DarkSplashAnimation)
|
||||
&& methodDef.containsWideLiteralInstructionValue(DarkSplashAnimation)
|
||||
}
|
||||
)
|
@ -2,7 +2,7 @@ package app.revanced.patches.youtube.general.splashanimation.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object StartUpResourceIdFingerprint : MethodFingerprint(
|
||||
@ -10,7 +10,7 @@ internal object StartUpResourceIdFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||
parameters = listOf("I"),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(3)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(4)
|
||||
methodDef.containsWideLiteralInstructionValue(3)
|
||||
&& methodDef.containsWideLiteralInstructionValue(4)
|
||||
}
|
||||
)
|
@ -39,16 +39,16 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
|
||||
import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch
|
||||
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.doRecursively
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getTargetIndexWithReferenceOrThrow
|
||||
import app.revanced.util.getTargetIndexWithReferenceReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.literalInstructionHook
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.replaceLiteralInstructionCall
|
||||
import app.revanced.util.resultOrThrow
|
||||
import app.revanced.util.updatePatchStatus
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -106,7 +106,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
YtPremiumWordMarkHeader,
|
||||
YtWordMarkHeader
|
||||
).forEach { literal ->
|
||||
context.literalInstructionHook(literal, smaliInstruction)
|
||||
context.replaceLiteralInstructionCall(literal, smaliInstruction)
|
||||
}
|
||||
|
||||
// YouTube's headers have the form of AttributeSet, which is decoded from YouTube's built-in classes.
|
||||
@ -125,13 +125,11 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
)
|
||||
|
||||
// The sidebar's header is lithoView. Add a listener to change it.
|
||||
DrawerContentViewFingerprint.resolve(
|
||||
context,
|
||||
DrawerContentViewConstructorFingerprint.resultOrThrow().classDef
|
||||
)
|
||||
DrawerContentViewFingerprint.resultOrThrow().let {
|
||||
DrawerContentViewFingerprint.alsoResolve(
|
||||
context, DrawerContentViewConstructorFingerprint
|
||||
).let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = getTargetIndexWithMethodReferenceNameOrThrow("addView")
|
||||
val insertIndex = DrawerContentViewFingerprint.indexOfAddViewInstruction(this)
|
||||
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||
|
||||
addInstruction(
|
||||
@ -147,7 +145,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
setActionBarRingoMutableClass.methods.first { method ->
|
||||
MethodUtil.isConstructor(method)
|
||||
}.apply {
|
||||
val insertIndex = getTargetIndexOrThrow(Opcode.IPUT_BOOLEAN)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.IPUT_BOOLEAN)
|
||||
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
@ -172,7 +170,8 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
ActionBarRingoBackgroundFingerprint.resultOrThrow().let {
|
||||
ActionBarRingoTextFingerprint.resolve(context, it.classDef)
|
||||
it.mutableMethod.apply {
|
||||
val viewIndex = getWideLiteralInstructionIndex(ActionBarRingoBackground) + 2
|
||||
val viewIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(ActionBarRingoBackground) + 2
|
||||
val viewRegister = getInstruction<OneRegisterInstruction>(viewIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
@ -281,16 +280,16 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
CreateSearchSuggestionsFingerprint.resultOrThrow().let { result ->
|
||||
result.mutableMethod.apply {
|
||||
val relativeIndex = getWideLiteralInstructionIndex(40)
|
||||
val replaceIndex = getTargetIndexWithReferenceReversedOrThrow(
|
||||
relativeIndex,
|
||||
"Landroid/widget/ImageView;->setVisibility(I)V"
|
||||
) - 1
|
||||
val relativeIndex = indexOfFirstWideLiteralInstructionValueOrThrow(40)
|
||||
val replaceIndex = indexOfFirstInstructionReversedOrThrow(relativeIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.toString() == "Landroid/widget/ImageView;->setVisibility(I)V"
|
||||
} - 1
|
||||
|
||||
val jumpIndex = getTargetIndexWithReferenceOrThrow(
|
||||
relativeIndex,
|
||||
"Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"
|
||||
) + 4
|
||||
val jumpIndex = indexOfFirstInstructionOrThrow(relativeIndex) {
|
||||
opcode == Opcode.INVOKE_STATIC &&
|
||||
getReference<MethodReference>()?.toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"
|
||||
} + 4
|
||||
|
||||
val replaceIndexInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex)
|
||||
val replaceIndexReference =
|
||||
@ -313,7 +312,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
// region patch for hide voice search button
|
||||
|
||||
if (SettingsPatch.upward1928) {
|
||||
ImageSearchButtonConfigFingerprint.literalInstructionBooleanHook(
|
||||
ImageSearchButtonConfigFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45617544,
|
||||
"$GENERAL_CLASS_DESCRIPTOR->hideImageSearchButton(Z)Z"
|
||||
)
|
||||
@ -327,15 +326,15 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
// region patch for hide voice search button
|
||||
|
||||
SearchBarFingerprint.resolve(
|
||||
context,
|
||||
SearchBarParentFingerprint.resultOrThrow().classDef
|
||||
)
|
||||
SearchBarFingerprint.resultOrThrow().let {
|
||||
SearchBarFingerprint.alsoResolve(
|
||||
context, SearchBarParentFingerprint
|
||||
).let {
|
||||
it.mutableMethod.apply {
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
val setVisibilityIndex =
|
||||
getTargetIndexWithMethodReferenceNameOrThrow(startIndex, "setVisibility")
|
||||
val setVisibilityIndex = indexOfFirstInstructionOrThrow(startIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setVisibility"
|
||||
}
|
||||
val setVisibilityInstruction =
|
||||
getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
|
||||
|
||||
@ -349,12 +348,11 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
SearchResultFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val startIndex = getWideLiteralInstructionIndex(VoiceSearch)
|
||||
val setOnClickListenerIndex =
|
||||
getTargetIndexWithMethodReferenceNameOrThrow(
|
||||
startIndex,
|
||||
"setOnClickListener"
|
||||
)
|
||||
val startIndex = indexOfFirstWideLiteralInstructionValueOrThrow(VoiceSearch)
|
||||
val setOnClickListenerIndex = indexOfFirstInstructionOrThrow(startIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setOnClickListener"
|
||||
}
|
||||
val viewRegister =
|
||||
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
||||
|
||||
@ -370,7 +368,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
||||
// region patch for replace create button
|
||||
|
||||
CreateButtonDrawableFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val index = getWideLiteralInstructionIndex(YtOutlineVideoCamera)
|
||||
val index = indexOfFirstWideLiteralInstructionValueOrThrow(YtOutlineVideoCamera)
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -3,7 +3,7 @@ package app.revanced.patches.youtube.general.toolbar.fingerprints
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.general.toolbar.fingerprints.ActionBarRingoBackgroundFingerprint.indexOfStaticInstruction
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ActionBarRingoBackground
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -13,7 +13,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
internal object ActionBarRingoBackgroundFingerprint : MethodFingerprint(
|
||||
returnType = "Landroid/view/View;",
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(ActionBarRingoBackground) &&
|
||||
methodDef.containsWideLiteralInstructionValue(ActionBarRingoBackground) &&
|
||||
indexOfStaticInstruction(methodDef) >= 0
|
||||
}
|
||||
) {
|
||||
|
@ -1,9 +1,14 @@
|
||||
package app.revanced.patches.youtube.general.toolbar.fingerprints
|
||||
|
||||
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.general.toolbar.fingerprints.DrawerContentViewFingerprint.indexOfAddViewInstruction
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionReversed
|
||||
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 DrawerContentViewFingerprint : MethodReferenceNameFingerprint(
|
||||
internal object DrawerContentViewFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = listOf("L"),
|
||||
opcodes = listOf(
|
||||
@ -12,5 +17,13 @@ internal object DrawerContentViewFingerprint : MethodReferenceNameFingerprint(
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
),
|
||||
reference = { "addView" }
|
||||
)
|
||||
customFingerprint = { methodDef, _ ->
|
||||
indexOfAddViewInstruction(methodDef) >= 0
|
||||
}
|
||||
) {
|
||||
fun indexOfAddViewInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstructionReversed {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "addView"
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
package app.revanced.patches.youtube.general.toolbar.fingerprints
|
||||
|
||||
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionReversed
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
object SearchBarFingerprint : MethodReferenceNameFingerprint(
|
||||
object SearchBarFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = listOf("Ljava/lang/String;"),
|
||||
opcodes = listOf(
|
||||
@ -12,5 +15,9 @@ object SearchBarFingerprint : MethodReferenceNameFingerprint(
|
||||
Opcode.IGET_BOOLEAN,
|
||||
Opcode.IF_EQZ
|
||||
),
|
||||
reference = { "isEmpty" }
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.indexOfFirstInstructionReversed {
|
||||
getReference<MethodReference>()?.name == "isEmpty"
|
||||
} >= 0
|
||||
}
|
||||
)
|
@ -17,8 +17,24 @@ object TranslationsPatch : BaseResourcePatch(
|
||||
) {
|
||||
// Array of supported translations, each represented by its language code.
|
||||
private val TRANSLATIONS = arrayOf(
|
||||
"ar", "bg-rBG", "de-rDE", "el-rGR", "es-rES", "fr-rFR", "hu-rHU", "it-rIT", "ja-rJP", "ko-rKR",
|
||||
"pl-rPL", "pt-rBR", "ru-rRU", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW"
|
||||
"ar",
|
||||
"bg-rBG",
|
||||
"de-rDE",
|
||||
"el-rGR",
|
||||
"es-rES",
|
||||
"fr-rFR",
|
||||
"hu-rHU",
|
||||
"it-rIT",
|
||||
"ja-rJP",
|
||||
"ko-rKR",
|
||||
"pl-rPL",
|
||||
"pt-rBR",
|
||||
"ru-rRU",
|
||||
"tr-rTR",
|
||||
"uk-rUA",
|
||||
"vi-rVN",
|
||||
"zh-rCN",
|
||||
"zh-rTW"
|
||||
)
|
||||
|
||||
private var CustomTranslations by stringPatchOption(
|
||||
|
@ -144,7 +144,8 @@ object VisualPreferencesIconsPatch : BaseResourcePatch(
|
||||
else -> null
|
||||
}
|
||||
if (drawableName == EMPTY_ICON &&
|
||||
ApplyToAll == false) return@loop
|
||||
ApplyToAll == false
|
||||
) return@loop
|
||||
|
||||
drawableName?.let {
|
||||
node.setAttribute("android:icon", "@drawable/$it")
|
||||
|
@ -8,10 +8,13 @@ import app.revanced.patches.youtube.misc.openlinksdirectly.fingerprints.OpenLink
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
object OpenLinksDirectlyPatch : BaseBytecodePatch(
|
||||
@ -32,7 +35,10 @@ object OpenLinksDirectlyPatch : BaseBytecodePatch(
|
||||
).forEach { fingerprint ->
|
||||
fingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = getTargetIndexWithMethodReferenceNameOrThrow("parse")
|
||||
val insertIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_STATIC &&
|
||||
getReference<MethodReference>()?.name == "parse"
|
||||
}
|
||||
val insertRegister =
|
||||
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||
|
||||
|
@ -13,8 +13,8 @@ import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BottomSheetRecyclerView
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -46,8 +46,8 @@ object ShareSheetPatch : BaseBytecodePatch(
|
||||
|
||||
// Detects that the Share sheet panel has been invoked.
|
||||
BottomSheetRecyclerViewFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(BottomSheetRecyclerView)
|
||||
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(BottomSheetRecyclerView)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
|
@ -10,10 +10,10 @@ import app.revanced.patches.youtube.player.ambientmode.fingerprints.PowerSaveMod
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getStringInstructionIndex
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -46,12 +46,12 @@ object AmbientModeSwitchPatch : BaseBytecodePatch(
|
||||
).forEach { (fingerprint, reversed) ->
|
||||
fingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val stringIndex =
|
||||
getStringInstructionIndex("android.os.action.POWER_SAVE_MODE_CHANGED")
|
||||
indexOfFirstStringInstructionOrThrow("android.os.action.POWER_SAVE_MODE_CHANGED")
|
||||
val targetIndex =
|
||||
if (reversed)
|
||||
getTargetIndexReversedOrThrow(stringIndex, Opcode.INVOKE_DIRECT)
|
||||
indexOfFirstInstructionReversedOrThrow(stringIndex, Opcode.INVOKE_DIRECT)
|
||||
else
|
||||
getTargetIndexOrThrow(stringIndex, Opcode.INVOKE_DIRECT)
|
||||
indexOfFirstInstructionOrThrow(stringIndex, Opcode.INVOKE_DIRECT)
|
||||
val targetClass =
|
||||
(getInstruction<ReferenceInstruction>(targetIndex).reference as MethodReference).definingClass
|
||||
|
||||
@ -87,7 +87,7 @@ object AmbientModeSwitchPatch : BaseBytecodePatch(
|
||||
|
||||
// region patch for disable ambient mode in fullscreen
|
||||
|
||||
AmbientModeInFullscreenFingerprint.literalInstructionBooleanHook(
|
||||
AmbientModeInFullscreenFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45389368,
|
||||
"$PLAYER_CLASS_DESCRIPTOR->disableAmbientModeInFullscreen()Z"
|
||||
)
|
||||
|
@ -24,8 +24,8 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullS
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.PlayerCollapseButton
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TitleAnchor
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -63,9 +63,10 @@ object PlayerButtonsPatch : BaseBytecodePatch(
|
||||
|
||||
LayoutConstructorFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(AutoNavToggle)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(AutoNavToggle)
|
||||
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
|
||||
val jumpIndex = getTargetIndexOrThrow(constIndex + 2, Opcode.INVOKE_VIRTUAL) + 1
|
||||
val jumpIndex =
|
||||
indexOfFirstInstructionOrThrow(constIndex + 2, Opcode.INVOKE_VIRTUAL) + 1
|
||||
|
||||
addInstructionsWithLabels(
|
||||
constIndex, """
|
||||
@ -124,9 +125,9 @@ object PlayerButtonsPatch : BaseBytecodePatch(
|
||||
// region patch for hide collapse button
|
||||
|
||||
TitleAnchorFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val titleAnchorConstIndex = getWideLiteralInstructionIndex(TitleAnchor)
|
||||
val titleAnchorConstIndex = indexOfFirstWideLiteralInstructionValueOrThrow(TitleAnchor)
|
||||
val titleAnchorIndex =
|
||||
getTargetIndexOrThrow(titleAnchorConstIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||
indexOfFirstInstructionOrThrow(titleAnchorConstIndex, Opcode.MOVE_RESULT_OBJECT)
|
||||
val titleAnchorRegister =
|
||||
getInstruction<OneRegisterInstruction>(titleAnchorIndex).registerA
|
||||
|
||||
@ -136,9 +137,9 @@ object PlayerButtonsPatch : BaseBytecodePatch(
|
||||
)
|
||||
|
||||
val playerCollapseButtonConstIndex =
|
||||
getWideLiteralInstructionIndex(PlayerCollapseButton)
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(PlayerCollapseButton)
|
||||
val playerCollapseButtonIndex =
|
||||
getTargetIndexOrThrow(playerCollapseButtonConstIndex, Opcode.CHECK_CAST)
|
||||
indexOfFirstInstructionOrThrow(playerCollapseButtonConstIndex, Opcode.CHECK_CAST)
|
||||
val playerCollapseButtonRegister =
|
||||
getInstruction<OneRegisterInstruction>(playerCollapseButtonIndex).registerA
|
||||
|
||||
@ -159,7 +160,7 @@ object PlayerButtonsPatch : BaseBytecodePatch(
|
||||
(instruction.value as? WideLiteralInstruction)?.wideLiteral == FullScreenButton
|
||||
}
|
||||
val constIndex = buttonCalls.elementAt(buttonCalls.size - 1).index
|
||||
val castIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val castIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val insertIndex = castIndex + 1
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(castIndex).registerA
|
||||
|
||||
@ -180,7 +181,7 @@ object PlayerButtonsPatch : BaseBytecodePatch(
|
||||
|
||||
PlayerControlsVisibilityModelFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val callIndex = getTargetIndexOrThrow(Opcode.INVOKE_DIRECT_RANGE)
|
||||
val callIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT_RANGE)
|
||||
val callInstruction = getInstruction<Instruction3rc>(callIndex)
|
||||
|
||||
val hasNextParameterRegister = callInstruction.startRegister + HAS_NEXT
|
||||
|
@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.CfFullscreenButton
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FadeDurationFast
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullScreenButton
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object FullScreenButtonFingerprint : MethodFingerprint(
|
||||
@ -13,10 +13,10 @@ internal object FullScreenButtonFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Landroid/view/View;"),
|
||||
customFingerprint = handler@{ methodDef, _ ->
|
||||
if (!methodDef.containsWideLiteralInstructionIndex(FullScreenButton))
|
||||
if (!methodDef.containsWideLiteralInstructionValue(FullScreenButton))
|
||||
return@handler false
|
||||
|
||||
methodDef.containsWideLiteralInstructionIndex(FadeDurationFast) // YouTube 18.29.38 ~ YouTube 19.18.41
|
||||
|| methodDef.containsWideLiteralInstructionIndex(CfFullscreenButton) // YouTube 19.19.39 ~
|
||||
methodDef.containsWideLiteralInstructionValue(FadeDurationFast) // YouTube 18.29.38 ~ YouTube 19.18.41
|
||||
|| methodDef.containsWideLiteralInstructionValue(CfFullscreenButton) // YouTube 19.19.39 ~
|
||||
},
|
||||
)
|
@ -3,12 +3,12 @@ package app.revanced.patches.youtube.player.buttons.fingerprints
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.PlayerCollapseButton
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TitleAnchor
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
|
||||
internal object TitleAnchorFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(PlayerCollapseButton)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(TitleAnchor)
|
||||
methodDef.containsWideLiteralInstructionValue(PlayerCollapseButton)
|
||||
&& methodDef.containsWideLiteralInstructionValue(TitleAnchor)
|
||||
}
|
||||
)
|
@ -12,9 +12,9 @@ import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -56,14 +56,15 @@ object CommentsComponentPatch : BaseBytecodePatch(
|
||||
|
||||
ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val emojiPickerEndpointIndex = getWideLiteralInstructionIndex(126326492)
|
||||
val emojiPickerEndpointIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(126326492)
|
||||
val emojiPickerOnClickListenerIndex =
|
||||
getTargetIndexOrThrow(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT)
|
||||
indexOfFirstInstructionOrThrow(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT)
|
||||
val emojiPickerOnClickListenerMethod =
|
||||
getWalkerMethod(context, emojiPickerOnClickListenerIndex)
|
||||
|
||||
emojiPickerOnClickListenerMethod.apply {
|
||||
val insertIndex = getTargetIndexOrThrow(Opcode.IF_EQZ)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.IF_EQZ)
|
||||
val insertRegister =
|
||||
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
|
@ -48,11 +48,11 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TapBl
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.literalInstructionViewHook
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionViewCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -61,6 +61,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
object PlayerComponentsPatch : BaseBytecodePatch(
|
||||
@ -107,8 +108,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
YouTubeControlsOverlayFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(ScrimOverlay)
|
||||
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(ScrimOverlay)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val targetParameter = getInstruction<ReferenceInstruction>(targetIndex).reference
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
@ -144,7 +145,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
||||
if (fingerprint == StartVideoInformerFingerprint) {
|
||||
hookInitVideoPanel(1)
|
||||
} else {
|
||||
val syntheticIndex = getTargetIndexOrThrow(Opcode.NEW_INSTANCE)
|
||||
val syntheticIndex =
|
||||
indexOfFirstInstructionOrThrow(opcode = Opcode.NEW_INSTANCE)
|
||||
val syntheticReference =
|
||||
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
|
||||
val syntheticClass =
|
||||
@ -228,7 +230,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
||||
DarkBackground,
|
||||
TapBloomView
|
||||
).forEach { literal ->
|
||||
QuickSeekOverlayFingerprint.literalInstructionViewHook(
|
||||
QuickSeekOverlayFingerprint.injectLiteralInstructionViewCall(
|
||||
literal,
|
||||
smaliInstruction
|
||||
)
|
||||
@ -273,10 +275,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
YouTubeControlsOverlayFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(FadeDurationFast)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(FadeDurationFast)
|
||||
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
|
||||
val insertIndex =
|
||||
getTargetIndexReversedOrThrow(constIndex, Opcode.INVOKE_VIRTUAL) + 1
|
||||
indexOfFirstInstructionReversedOrThrow(constIndex, Opcode.INVOKE_VIRTUAL) + 1
|
||||
val jumpIndex = implementation!!.instructions.let { instruction ->
|
||||
insertIndex + instruction.subList(insertIndex, instruction.size - 1)
|
||||
.indexOfFirst { instructions ->
|
||||
@ -341,11 +343,14 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
YouTubeControlsOverlayFingerprint.resultOrThrow().let { result ->
|
||||
result.mutableMethod.apply {
|
||||
val insertIndex = getWideLiteralInstructionIndex(SeekUndoEduOverlayStub)
|
||||
val insertIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(SeekUndoEduOverlayStub)
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
val onClickListenerIndex =
|
||||
getTargetIndexWithMethodReferenceNameOrThrow(insertIndex, "setOnClickListener")
|
||||
val onClickListenerIndex = indexOfFirstInstructionOrThrow(insertIndex) {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setOnClickListener"
|
||||
}
|
||||
val constComponent = getConstComponent(insertIndex, onClickListenerIndex - 1)
|
||||
|
||||
if (constComponent.isNotEmpty()) {
|
||||
@ -390,8 +395,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
|
||||
it.mutableClass.methods.find { method ->
|
||||
method.parameters == listOf("Landroid/view/View${'$'}OnClickListener;")
|
||||
}?.apply {
|
||||
val setOnClickListenerIndex =
|
||||
getTargetIndexWithMethodReferenceNameOrThrow("setOnClickListener")
|
||||
val setOnClickListenerIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setOnClickListener"
|
||||
}
|
||||
val setOnClickListenerRegister =
|
||||
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
|
||||
|
||||
|
@ -3,13 +3,13 @@ package app.revanced.patches.youtube.player.components.fingerprints
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkBackground
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TapBloomView
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
|
||||
internal object QuickSeekOverlayFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = emptyList(),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(DarkBackground)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(TapBloomView)
|
||||
methodDef.containsWideLiteralInstructionValue(DarkBackground)
|
||||
&& methodDef.containsWideLiteralInstructionValue(TapBloomView)
|
||||
},
|
||||
)
|
@ -20,10 +20,14 @@ import app.revanced.patches.youtube.utils.playertype.PlayerTypeHookPatch
|
||||
import app.revanced.patches.youtube.utils.recyclerview.BottomSheetRecyclerViewPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
object DescriptionComponentsPatch : BaseBytecodePatch(
|
||||
@ -54,23 +58,23 @@ object DescriptionComponentsPatch : BaseBytecodePatch(
|
||||
// In order to maintain compatibility with YouTube v18.48.39 or previous versions,
|
||||
// This patch is applied only to the version after YouTube v18.49.37.
|
||||
if (SettingsPatch.upward1849) {
|
||||
RollingNumberTextViewAnimationUpdateFingerprint.resolve(
|
||||
context,
|
||||
RollingNumberTextViewFingerprint.resultOrThrow().classDef
|
||||
)
|
||||
RollingNumberTextViewAnimationUpdateFingerprint.resultOrThrow().let {
|
||||
RollingNumberTextViewAnimationUpdateFingerprint.alsoResolve(
|
||||
context, RollingNumberTextViewFingerprint
|
||||
).let {
|
||||
it.mutableMethod.apply {
|
||||
val freeRegister = implementation!!.registerCount - parameters.size - 2
|
||||
val imageSpanIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
val setTextIndex = getTargetIndexWithMethodReferenceNameOrThrow("setText")
|
||||
|
||||
val setTextIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setText"
|
||||
}
|
||||
addInstruction(setTextIndex, "nop")
|
||||
addInstructionsWithLabels(
|
||||
imageSpanIndex, """
|
||||
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->disableRollingNumberAnimations()Z
|
||||
move-result v$freeRegister
|
||||
if-nez v$freeRegister, :disable_animations
|
||||
""", ExternalLabel("disable_animations", getInstruction(setTextIndex))
|
||||
invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->disableRollingNumberAnimations()Z
|
||||
move-result v$freeRegister
|
||||
if-nez v$freeRegister, :disable_animations
|
||||
""", ExternalLabel("disable_animations", getInstruction(setTextIndex))
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -106,13 +110,11 @@ object DescriptionComponentsPatch : BaseBytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
EngagementPanelTitleFingerprint.resolve(
|
||||
context,
|
||||
EngagementPanelTitleParentFingerprint.resultOrThrow().classDef
|
||||
)
|
||||
EngagementPanelTitleFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val contentDescriptionIndex =
|
||||
getTargetIndexWithMethodReferenceNameOrThrow("setContentDescription")
|
||||
EngagementPanelTitleFingerprint.alsoResolve(
|
||||
context, EngagementPanelTitleParentFingerprint
|
||||
).mutableMethod.apply {
|
||||
val contentDescriptionIndex = EngagementPanelTitleFingerprint
|
||||
.indexOfContentDescriptionInstruction(this)
|
||||
val contentDescriptionRegister =
|
||||
getInstruction<FiveRegisterInstruction>(contentDescriptionIndex).registerD
|
||||
|
||||
|
@ -1,8 +1,22 @@
|
||||
package app.revanced.patches.youtube.player.descriptions.fingerprints
|
||||
|
||||
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.player.descriptions.fingerprints.EngagementPanelTitleFingerprint.indexOfContentDescriptionInstruction
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionReversed
|
||||
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 EngagementPanelTitleFingerprint : MethodReferenceNameFingerprint(
|
||||
internal object EngagementPanelTitleFingerprint : MethodFingerprint(
|
||||
strings = listOf(". "),
|
||||
reference = { "setContentDescription" }
|
||||
)
|
||||
customFingerprint = { methodDef, _ ->
|
||||
indexOfContentDescriptionInstruction(methodDef) >= 0
|
||||
}
|
||||
) {
|
||||
fun indexOfContentDescriptionInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstructionReversed {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setContentDescription"
|
||||
}
|
||||
}
|
@ -16,12 +16,15 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BottomSheetFooterText
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.literalInstructionViewHook
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.injectLiteralInstructionViewCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
object PlayerFlyoutMenuPatch : BaseBytecodePatch(
|
||||
@ -56,7 +59,7 @@ object PlayerFlyoutMenuPatch : BaseBytecodePatch(
|
||||
val smaliInstruction = """
|
||||
invoke-static {v$REGISTER_TEMPLATE_REPLACEMENT}, $PLAYER_CLASS_DESCRIPTOR->$name(Landroid/view/View;)V
|
||||
"""
|
||||
fingerprint.literalInstructionViewHook(BottomSheetFooterText, smaliInstruction)
|
||||
fingerprint.injectLiteralInstructionViewCall(BottomSheetFooterText, smaliInstruction)
|
||||
}
|
||||
|
||||
arrayOf(
|
||||
@ -64,15 +67,17 @@ object PlayerFlyoutMenuPatch : BaseBytecodePatch(
|
||||
QualityMenuViewInflateFingerprint
|
||||
).forEach { fingerprint ->
|
||||
fingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val insertIndex = getTargetIndexWithMethodReferenceNameOrThrow("addHeaderView")
|
||||
val insertIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "addHeaderView"
|
||||
}
|
||||
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hidePlayerFlyoutMenuQualityHeader(Landroid/view/View;)Landroid/view/View;
|
||||
move-result-object v$insertRegister
|
||||
"""
|
||||
insertIndex, """
|
||||
invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hidePlayerFlyoutMenuQualityHeader(Landroid/view/View;)Landroid/view/View;
|
||||
move-result-object v$insertRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -95,7 +100,7 @@ object PlayerFlyoutMenuPatch : BaseBytecodePatch(
|
||||
SettingsPatch.updatePatchStatus(this)
|
||||
|
||||
if (SettingsPatch.upward1839) {
|
||||
PiPModeConfigFingerprint.literalInstructionBooleanHook(
|
||||
PiPModeConfigFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45427407,
|
||||
"$PLAYER_CLASS_DESCRIPTOR->hidePiPModeMenu(Z)Z"
|
||||
)
|
||||
|
@ -4,13 +4,13 @@ import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BottomSheetFooterText
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SubtitleMenuSettingsFooterInfo
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object CaptionsBottomSheetFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(BottomSheetFooterText)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(SubtitleMenuSettingsFooterInfo)
|
||||
methodDef.containsWideLiteralInstructionValue(BottomSheetFooterText)
|
||||
&& methodDef.containsWideLiteralInstructionValue(SubtitleMenuSettingsFooterInfo)
|
||||
}
|
||||
)
|
@ -17,11 +17,10 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PAC
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getStringInstructionIndex
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -139,13 +138,15 @@ object ChangeTogglePatch : BaseBytecodePatch(
|
||||
}
|
||||
val classRegister = getInstruction<TwoRegisterInstruction>(iGetIndex).registerB
|
||||
|
||||
val stringIndex = getStringInstructionIndex("menu_item_cinematic_lighting")
|
||||
val stringIndex =
|
||||
indexOfFirstStringInstructionOrThrow("menu_item_cinematic_lighting")
|
||||
|
||||
val checkCastIndex = getTargetIndexReversedOrThrow(stringIndex, Opcode.CHECK_CAST)
|
||||
val checkCastIndex =
|
||||
indexOfFirstInstructionReversedOrThrow(stringIndex, Opcode.CHECK_CAST)
|
||||
val iGetObjectPrimaryIndex =
|
||||
getTargetIndexReversedOrThrow(checkCastIndex, Opcode.IGET_OBJECT)
|
||||
indexOfFirstInstructionReversedOrThrow(checkCastIndex, Opcode.IGET_OBJECT)
|
||||
val iGetObjectSecondaryIndex =
|
||||
getTargetIndexOrThrow(checkCastIndex, Opcode.IGET_OBJECT)
|
||||
indexOfFirstInstructionOrThrow(checkCastIndex, Opcode.IGET_OBJECT)
|
||||
|
||||
val checkCastReference =
|
||||
getInstruction<ReferenceInstruction>(checkCastIndex).reference
|
||||
@ -154,14 +155,15 @@ object ChangeTogglePatch : BaseBytecodePatch(
|
||||
val iGetObjectSecondaryReference =
|
||||
getInstruction<ReferenceInstruction>(iGetObjectSecondaryIndex).reference
|
||||
|
||||
val invokeVirtualIndex = getTargetIndexOrThrow(stringIndex, Opcode.INVOKE_VIRTUAL)
|
||||
val invokeVirtualIndex =
|
||||
indexOfFirstInstructionOrThrow(stringIndex, Opcode.INVOKE_VIRTUAL)
|
||||
val invokeVirtualInstruction =
|
||||
getInstruction<FiveRegisterInstruction>(invokeVirtualIndex)
|
||||
val freeRegisterC = invokeVirtualInstruction.registerC
|
||||
val freeRegisterD = invokeVirtualInstruction.registerD
|
||||
val freeRegisterE = invokeVirtualInstruction.registerE
|
||||
|
||||
val insertIndex = getTargetIndexOrThrow(stringIndex, Opcode.RETURN_VOID)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(stringIndex, Opcode.RETURN_VOID)
|
||||
|
||||
addInstructionsWithLabels(
|
||||
insertIndex, """
|
||||
|
@ -30,12 +30,10 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullS
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.QuickActionsElementContainer
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getStringInstructionIndex
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import app.revanced.util.updatePatchStatus
|
||||
@ -80,8 +78,9 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
EngagementPanelFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val literalIndex = getWideLiteralInstructionIndex(FullScreenEngagementPanel)
|
||||
val targetIndex = getTargetIndexOrThrow(literalIndex, Opcode.CHECK_CAST)
|
||||
val literalIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(FullScreenEngagementPanel)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.CHECK_CAST)
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
@ -94,7 +93,10 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
PlayerTitleViewFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = getTargetIndexWithMethodReferenceNameOrThrow("addView")
|
||||
val insertIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "addView"
|
||||
}
|
||||
val insertReference =
|
||||
getInstruction<ReferenceInstruction>(insertIndex).reference.toString()
|
||||
if (!insertReference.startsWith("Landroid/widget/FrameLayout;"))
|
||||
@ -115,9 +117,10 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
LayoutConstructorFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(AutoNavPreviewStub)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(AutoNavPreviewStub)
|
||||
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
|
||||
val jumpIndex = getTargetIndexOrThrow(constIndex + 2, Opcode.INVOKE_VIRTUAL) + 1
|
||||
val jumpIndex =
|
||||
indexOfFirstInstructionOrThrow(constIndex + 2, Opcode.INVOKE_VIRTUAL) + 1
|
||||
|
||||
addInstructionsWithLabels(
|
||||
constIndex, """
|
||||
@ -159,7 +162,7 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
}
|
||||
val constIndex = containerCalls.elementAt(containerCalls.size - 1).index
|
||||
|
||||
val checkCastIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val checkCastIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val insertRegister =
|
||||
getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
||||
|
||||
@ -183,9 +186,11 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
YouTubeControlsOverlayFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex =
|
||||
getTargetIndexWithMethodReferenceNameOrThrow("setFocusableInTouchMode")
|
||||
val walkerIndex = getTargetIndexOrThrow(targetIndex, Opcode.INVOKE_STATIC)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
getReference<MethodReference>()?.name == "setFocusableInTouchMode"
|
||||
}
|
||||
val walkerIndex = indexOfFirstInstructionOrThrow(targetIndex, Opcode.INVOKE_STATIC)
|
||||
|
||||
val walkerMethod = getWalkerMethod(context, walkerIndex)
|
||||
walkerMethod.apply {
|
||||
@ -209,14 +214,14 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
ClientSettingEndpointFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val getActivityIndex = getStringInstructionIndex("watch") + 2
|
||||
val getActivityIndex = indexOfFirstStringInstructionOrThrow("watch") + 2
|
||||
val getActivityReference =
|
||||
getInstruction<ReferenceInstruction>(getActivityIndex).reference
|
||||
val classRegister =
|
||||
getInstruction<TwoRegisterInstruction>(getActivityIndex).registerB
|
||||
|
||||
val watchDescriptorMethodIndex =
|
||||
getStringInstructionIndex("start_watch_minimized") - 1
|
||||
indexOfFirstStringInstructionOrThrow("start_watch_minimized") - 1
|
||||
val watchDescriptorRegister =
|
||||
getInstruction<FiveRegisterInstruction>(watchDescriptorMethodIndex).registerD
|
||||
|
||||
@ -228,7 +233,7 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
)
|
||||
|
||||
// hooks Activity.
|
||||
val insertIndex = getStringInstructionIndex("force_fullscreen")
|
||||
val insertIndex = indexOfFirstStringInstructionOrThrow("force_fullscreen")
|
||||
val freeRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
@ -244,9 +249,10 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
VideoPortraitParentFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val stringIndex =
|
||||
getStringInstructionIndex("Acquiring NetLatencyActionLogger failed. taskId=")
|
||||
val invokeIndex = getTargetIndexOrThrow(stringIndex, Opcode.INVOKE_INTERFACE)
|
||||
val targetIndex = getTargetIndexOrThrow(invokeIndex, Opcode.CHECK_CAST)
|
||||
indexOfFirstStringInstructionOrThrow("Acquiring NetLatencyActionLogger failed. taskId=")
|
||||
val invokeIndex =
|
||||
indexOfFirstInstructionOrThrow(stringIndex, Opcode.INVOKE_INTERFACE)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(invokeIndex, Opcode.CHECK_CAST)
|
||||
val targetClass = context
|
||||
.findClass(getInstruction<ReferenceInstruction>(targetIndex).reference.toString())!!
|
||||
.mutableClass
|
||||
@ -328,8 +334,9 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
|
||||
BroadcastReceiverFingerprint.resultOrThrow().let { result ->
|
||||
result.mutableMethod.apply {
|
||||
val stringIndex =
|
||||
getStringInstructionIndex("android.intent.action.SCREEN_ON")
|
||||
val insertIndex = getTargetIndexOrThrow(stringIndex, Opcode.IF_EQZ) + 1
|
||||
indexOfFirstStringInstructionOrThrow("android.intent.action.SCREEN_ON")
|
||||
val insertIndex =
|
||||
indexOfFirstInstructionOrThrow(stringIndex, Opcode.IF_EQZ) + 1
|
||||
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
|
@ -13,7 +13,7 @@ import app.revanced.patches.youtube.player.hapticfeedback.fingerprints.ZoomHapti
|
||||
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -65,7 +65,7 @@ object HapticFeedBackPatch : BaseBytecodePatch(
|
||||
var register = 0
|
||||
|
||||
if (name == "run") {
|
||||
index = getTargetIndexOrThrow(Opcode.SGET)
|
||||
index = indexOfFirstInstructionOrThrow(Opcode.SGET)
|
||||
register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
}
|
||||
|
||||
|
@ -30,11 +30,11 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelT
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
|
||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -44,6 +44,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import org.w3c.dom.Element
|
||||
|
||||
@Suppress("DEPRECATION", "unused")
|
||||
@ -139,11 +140,14 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
||||
|
||||
TotalTimeFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val charSequenceIndex =
|
||||
getTargetIndexWithMethodReferenceNameOrThrow("getString") + 1
|
||||
val charSequenceIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "getString"
|
||||
} + 1
|
||||
val charSequenceRegister =
|
||||
getInstruction<OneRegisterInstruction>(charSequenceIndex).registerA
|
||||
val textViewIndex = getTargetIndexWithMethodReferenceNameOrThrow("getText")
|
||||
val textViewIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "getText"
|
||||
}
|
||||
val textViewRegister =
|
||||
getInstruction<FiveRegisterInstruction>(textViewIndex).registerC
|
||||
|
||||
@ -162,12 +166,12 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
||||
// region patch for seekbar color
|
||||
|
||||
PlayerSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
hook(getWideLiteralInstructionIndex(InlineTimeBarColorizedBarPlayedColorDark) + 2)
|
||||
hook(getWideLiteralInstructionIndex(InlineTimeBarPlayedNotHighlightedColor) + 2)
|
||||
hook(InlineTimeBarColorizedBarPlayedColorDark)
|
||||
hook(InlineTimeBarPlayedNotHighlightedColor)
|
||||
}
|
||||
|
||||
ShortsSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
hook(getWideLiteralInstructionIndex(ReelTimeBarPlayedColor) + 2)
|
||||
hook(ReelTimeBarPlayedColor)
|
||||
}
|
||||
|
||||
ControlsOverlayStyleFingerprint.resultOrThrow().let {
|
||||
@ -212,7 +216,7 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
||||
PlayerButtonsVisibilityFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val freeRegister = implementation!!.registerCount - parameters.size - 2
|
||||
val viewIndex = getTargetIndexOrThrow(Opcode.INVOKE_INTERFACE)
|
||||
val viewIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_INTERFACE)
|
||||
val viewRegister = getInstruction<FiveRegisterInstruction>(viewIndex).registerD
|
||||
|
||||
addInstructionsWithLabels(
|
||||
@ -271,7 +275,7 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
||||
// region patch for restore old seekbar thumbnails
|
||||
|
||||
ThumbnailPreviewConfigFingerprint.result?.let {
|
||||
ThumbnailPreviewConfigFingerprint.literalInstructionBooleanHook(
|
||||
ThumbnailPreviewConfigFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45398577,
|
||||
"$PLAYER_CLASS_DESCRIPTOR->restoreOldSeekbarThumbnails()Z"
|
||||
)
|
||||
@ -285,7 +289,7 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
||||
// region patch for enable cairo seekbar
|
||||
|
||||
if (SettingsPatch.upward1923) {
|
||||
CairoSeekbarConfigFingerprint.literalInstructionBooleanHook(
|
||||
CairoSeekbarConfigFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45617850,
|
||||
"$PLAYER_CLASS_DESCRIPTOR->enableCairoSeekbar()Z"
|
||||
)
|
||||
@ -303,7 +307,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
|
||||
SettingsPatch.updatePatchStatus(this)
|
||||
}
|
||||
|
||||
private fun MutableMethod.hook(insertIndex: Int) {
|
||||
private fun MutableMethod.hook(literal: Long) {
|
||||
val insertIndex = indexOfFirstWideLiteralInstructionValueOrThrow(literal) + 2
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -15,18 +15,15 @@ import app.revanced.patches.youtube.player.speedoverlay.fingerprints.NextGenWatc
|
||||
import app.revanced.patches.youtube.player.speedoverlay.fingerprints.RestoreSlideToSeekBehaviorFingerprint
|
||||
import app.revanced.patches.youtube.player.speedoverlay.fingerprints.SlideToSeekMotionEventFingerprint
|
||||
import app.revanced.patches.youtube.player.speedoverlay.fingerprints.SpeedOverlayFingerprint
|
||||
import app.revanced.patches.youtube.player.speedoverlay.fingerprints.SpeedOverlayFloatValueFingerprint
|
||||
import app.revanced.patches.youtube.player.speedoverlay.fingerprints.SpeedOverlayTextValueFingerprint
|
||||
import app.revanced.patches.youtube.player.speedoverlay.fingerprints.SpeedOverlayValueFingerprint
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameReversedOrThrow
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
@ -35,6 +32,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
@Patch(dependencies = [SharedResourceIdPatch::class])
|
||||
object SpeedOverlayPatch : BytecodePatch(
|
||||
@ -43,8 +42,8 @@ object SpeedOverlayPatch : BytecodePatch(
|
||||
NextGenWatchLayoutFingerprint,
|
||||
RestoreSlideToSeekBehaviorFingerprint,
|
||||
SpeedOverlayFingerprint,
|
||||
SpeedOverlayFloatValueFingerprint,
|
||||
SpeedOverlayTextValueFingerprint,
|
||||
SpeedOverlayValueFingerprint,
|
||||
)
|
||||
) {
|
||||
override fun execute(context: BytecodeContext) {
|
||||
@ -52,36 +51,33 @@ object SpeedOverlayPatch : BytecodePatch(
|
||||
val restoreSlideToSeekBehaviorFingerprintResult =
|
||||
RestoreSlideToSeekBehaviorFingerprint.result
|
||||
val speedOverlayFingerprintResult = SpeedOverlayFingerprint.result
|
||||
val speedOverlayValueFingerprintResult = SpeedOverlayValueFingerprint.result
|
||||
val speedOverlayFloatValueFingerprintResult = SpeedOverlayFloatValueFingerprint.result
|
||||
|
||||
val resolvable =
|
||||
restoreSlideToSeekBehaviorFingerprintResult != null
|
||||
&& speedOverlayFingerprintResult != null
|
||||
&& speedOverlayValueFingerprintResult != null
|
||||
&& speedOverlayFloatValueFingerprintResult != null
|
||||
|
||||
if (resolvable) {
|
||||
// Legacy method.
|
||||
// Used on YouTube 18.29.38 ~ YouTube 19.17.41
|
||||
|
||||
// region patch for disable speed overlay
|
||||
// region patch for Disable speed overlay (Enable slide to seek)
|
||||
|
||||
mapOf(
|
||||
RestoreSlideToSeekBehaviorFingerprint to 45411329,
|
||||
SpeedOverlayFingerprint to 45411330
|
||||
).forEach { (fingerprint, literal) ->
|
||||
fingerprint.result!!.let {
|
||||
fingerprint.literalInstructionBooleanHook(
|
||||
literal,
|
||||
"$PLAYER_CLASS_DESCRIPTOR->disableSpeedOverlay(Z)Z"
|
||||
)
|
||||
}
|
||||
fingerprint.injectLiteralInstructionBooleanCall(
|
||||
literal,
|
||||
"$PLAYER_CLASS_DESCRIPTOR->disableSpeedOverlay(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region patch for custom speed overlay value
|
||||
// region patch for Custom speed overlay float value
|
||||
|
||||
speedOverlayValueFingerprintResult!!.let {
|
||||
speedOverlayFloatValueFingerprintResult!!.let {
|
||||
it.mutableMethod.apply {
|
||||
val index = it.scanResult.patternScanResult!!.startIndex
|
||||
val register = getInstruction<TwoRegisterInstruction>(index).registerA
|
||||
@ -98,13 +94,18 @@ object SpeedOverlayPatch : BytecodePatch(
|
||||
// endregion
|
||||
|
||||
} else {
|
||||
// New method.
|
||||
// Used on YouTube 19.18.41~
|
||||
|
||||
NextGenWatchLayoutFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val booleanValueIndex = getTargetIndexWithMethodReferenceNameOrThrow("booleanValue")
|
||||
// region patch for Disable speed overlay (Enable slide to seek)
|
||||
|
||||
val insertIndex = findIGetIndex(booleanValueIndex - 10, booleanValueIndex)
|
||||
NextGenWatchLayoutFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val booleanValueIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "booleanValue"
|
||||
}
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(booleanValueIndex - 10) {
|
||||
opcode == Opcode.IGET_OBJECT
|
||||
&& getReference<FieldReference>()?.definingClass == definingClass
|
||||
}
|
||||
val insertInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
|
||||
val insertReference = getInstruction<ReferenceInstruction>(insertIndex).reference
|
||||
|
||||
@ -113,77 +114,107 @@ object SpeedOverlayPatch : BytecodePatch(
|
||||
"iget-object v${insertInstruction.registerA}, v${insertInstruction.registerB}, $insertReference"
|
||||
)
|
||||
|
||||
val jumpIndex = findIGetIndex(booleanValueIndex, booleanValueIndex + 10)
|
||||
val jumpIndex = indexOfFirstInstructionOrThrow(booleanValueIndex) {
|
||||
opcode == Opcode.IGET_OBJECT
|
||||
&& getReference<FieldReference>()?.definingClass == definingClass
|
||||
}
|
||||
|
||||
hook(insertIndex + 1, insertInstruction.registerA, jumpIndex)
|
||||
}
|
||||
|
||||
SlideToSeekMotionEventFingerprint.resolve(
|
||||
context,
|
||||
HorizontalTouchOffsetConstructorFingerprint.resultOrThrow().classDef
|
||||
)
|
||||
SlideToSeekMotionEventFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val scanResult = it.scanResult.patternScanResult!!
|
||||
val (slideToSeekBooleanMethod, slideToSeekSyntheticMethod) =
|
||||
SlideToSeekMotionEventFingerprint.alsoResolve(
|
||||
context, HorizontalTouchOffsetConstructorFingerprint
|
||||
).let {
|
||||
with(it.mutableMethod) {
|
||||
val scanResult = it.scanResult.patternScanResult!!
|
||||
val jumpIndex = scanResult.endIndex + 1
|
||||
val insertIndex = scanResult.endIndex - 1
|
||||
val insertRegister =
|
||||
getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
val slideToSeekBooleanIndex = scanResult.startIndex + 1
|
||||
slideToSeekBooleanMethod = getWalkerMethod(context, slideToSeekBooleanIndex)
|
||||
|
||||
val jumpIndex = scanResult.endIndex + 1
|
||||
val insertIndex = scanResult.endIndex - 1
|
||||
val insertRegister =
|
||||
getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
hook(insertIndex, insertRegister, jumpIndex)
|
||||
}
|
||||
}
|
||||
|
||||
slideToSeekBooleanMethod.apply {
|
||||
var insertIndex = getTargetIndexOrThrow(Opcode.IGET_OBJECT)
|
||||
var insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
var jumpIndex = getTargetIndexReversedOrThrow(Opcode.INVOKE_VIRTUAL)
|
||||
|
||||
hook(insertIndex, insertRegister, jumpIndex)
|
||||
|
||||
val constructorMethod =
|
||||
context.findClass(definingClass)?.mutableClass
|
||||
?.methods?.find { method -> method.name == "<init>" }
|
||||
?: throw PatchException("Could not find constructor method")
|
||||
|
||||
constructorMethod.apply {
|
||||
val syntheticIndex = getTargetIndexReversedOrThrow(Opcode.NEW_INSTANCE)
|
||||
val syntheticClass =
|
||||
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
|
||||
|
||||
val syntheticMethod =
|
||||
context.findClass(syntheticClass)?.mutableClass
|
||||
?.methods?.find { method -> method.name == "run" }
|
||||
?: throw PatchException("Could not find synthetic method")
|
||||
|
||||
syntheticMethod.apply {
|
||||
val speedOverlayValueIndex =
|
||||
indexOfFirstInstructionOrThrow { (this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() }
|
||||
val speedOverlayValueRegister =
|
||||
getInstruction<OneRegisterInstruction>(speedOverlayValueIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
speedOverlayValueIndex + 1, """
|
||||
invoke-static {v$speedOverlayValueRegister}, $PLAYER_CLASS_DESCRIPTOR->speedOverlayValue(F)F
|
||||
move-result v$speedOverlayValueRegister
|
||||
"""
|
||||
)
|
||||
|
||||
insertIndex = getTargetIndexWithMethodReferenceNameReversedOrThrow(
|
||||
speedOverlayValueIndex,
|
||||
"removeCallbacks"
|
||||
) + 1
|
||||
insertRegister =
|
||||
getInstruction<FiveRegisterInstruction>(insertIndex - 1).registerC
|
||||
jumpIndex =
|
||||
getTargetIndexOrThrow(speedOverlayValueIndex, Opcode.RETURN_VOID) + 1
|
||||
hook(insertIndex, insertRegister, jumpIndex)
|
||||
|
||||
val slideToSeekBooleanMethod = context.toMethodWalker(it.mutableMethod)
|
||||
.nextMethod(scanResult.startIndex + 1, true)
|
||||
.getMethod() as MutableMethod
|
||||
|
||||
val slideToSeekConstructorMethod =
|
||||
context.findClass { classDef -> classDef.type == slideToSeekBooleanMethod.definingClass }
|
||||
?.mutableClass
|
||||
?.methods
|
||||
?.find { method -> MethodUtil.isConstructor(method) }
|
||||
?: throw PatchException("Could not find constructor method")
|
||||
|
||||
val slideToSeekSyntheticIndex = slideToSeekConstructorMethod
|
||||
.indexOfFirstInstructionReversedOrThrow {
|
||||
opcode == Opcode.NEW_INSTANCE
|
||||
}
|
||||
|
||||
val slideToSeekSyntheticClass = slideToSeekConstructorMethod
|
||||
.getInstruction<ReferenceInstruction>(slideToSeekSyntheticIndex)
|
||||
.reference
|
||||
.toString()
|
||||
|
||||
val slideToSeekSyntheticMethod =
|
||||
context.findClass { classDef -> classDef.type == slideToSeekSyntheticClass }
|
||||
?.mutableClass
|
||||
?.methods
|
||||
?.find { method -> method.name == "run" }
|
||||
?: throw PatchException("Could not find synthetic method")
|
||||
|
||||
Pair(slideToSeekBooleanMethod, slideToSeekSyntheticMethod)
|
||||
}
|
||||
}
|
||||
|
||||
slideToSeekBooleanMethod.apply {
|
||||
val insertIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.IGET_OBJECT
|
||||
}
|
||||
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
val jumpIndex = indexOfFirstInstructionReversedOrThrow {
|
||||
opcode == Opcode.INVOKE_VIRTUAL
|
||||
}
|
||||
|
||||
hook(insertIndex, insertRegister, jumpIndex)
|
||||
}
|
||||
|
||||
slideToSeekSyntheticMethod.apply {
|
||||
val speedOverlayFloatValueIndex = indexOfFirstInstructionOrThrow {
|
||||
(this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits()
|
||||
}
|
||||
val insertIndex =
|
||||
indexOfFirstInstructionReversedOrThrow(speedOverlayFloatValueIndex) {
|
||||
getReference<MethodReference>()?.name == "removeCallbacks"
|
||||
} + 1
|
||||
val insertRegister =
|
||||
getInstruction<FiveRegisterInstruction>(insertIndex - 1).registerC
|
||||
val jumpIndex =
|
||||
indexOfFirstInstructionOrThrow(
|
||||
speedOverlayFloatValueIndex,
|
||||
Opcode.RETURN_VOID
|
||||
) + 1
|
||||
|
||||
hook(insertIndex, insertRegister, jumpIndex)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region patch for Custom speed overlay float value
|
||||
|
||||
slideToSeekSyntheticMethod.apply {
|
||||
val speedOverlayFloatValueIndex = indexOfFirstInstructionOrThrow {
|
||||
(this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits()
|
||||
}
|
||||
val speedOverlayFloatValueRegister =
|
||||
getInstruction<OneRegisterInstruction>(speedOverlayFloatValueIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
speedOverlayFloatValueIndex + 1, """
|
||||
invoke-static {v$speedOverlayFloatValueRegister}, $PLAYER_CLASS_DESCRIPTOR->speedOverlayValue(F)F
|
||||
move-result v$speedOverlayFloatValueRegister
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
SpeedOverlayTextValueFingerprint.resultOrThrow().let {
|
||||
@ -200,11 +231,12 @@ object SpeedOverlayPatch : BytecodePatch(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var slideToSeekBooleanMethod: MutableMethod
|
||||
|
||||
// restore slide to seek
|
||||
private fun MutableMethod.hook(
|
||||
insertIndex: Int,
|
||||
@ -220,14 +252,4 @@ object SpeedOverlayPatch : BytecodePatch(
|
||||
""", ExternalLabel("disable", getInstruction(jumpIndex))
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableMethod.findIGetIndex(
|
||||
startIndex: Int,
|
||||
endIndex: Int
|
||||
): Int = implementation!!.instructions.let { instruction ->
|
||||
startIndex + instruction.subList(startIndex, endIndex).indexOfFirst {
|
||||
it.opcode == Opcode.IGET_OBJECT
|
||||
&& it.getReference<FieldReference>()?.definingClass == definingClass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ package app.revanced.patches.youtube.player.speedoverlay.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.containsMethodReferenceNameInstructionIndex
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal object NextGenWatchLayoutFingerprint : MethodFingerprint(
|
||||
returnType = "Z",
|
||||
@ -13,6 +15,8 @@ internal object NextGenWatchLayoutFingerprint : MethodFingerprint(
|
||||
if (methodDef.definingClass != "Lcom/google/android/apps/youtube/app/watch/nextgenwatch/ui/NextGenWatchLayout;")
|
||||
return@handler false
|
||||
|
||||
methodDef.containsMethodReferenceNameInstructionIndex("booleanValue")
|
||||
methodDef.indexOfFirstInstruction {
|
||||
getReference<MethodReference>()?.name == "booleanValue"
|
||||
} >= 0
|
||||
}
|
||||
)
|
@ -5,6 +5,7 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
/**
|
||||
* This value restores the 'Slide to seek' behavior.
|
||||
* Deprecated in YouTube v19.18.41+.
|
||||
*/
|
||||
internal object RestoreSlideToSeekBehaviorFingerprint : LiteralValueFingerprint(
|
||||
returnType = "Z",
|
||||
|
@ -5,6 +5,7 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
/**
|
||||
* This value disables 'Playing at 2x speed' while holding down.
|
||||
* Deprecated in YouTube v19.18.41+.
|
||||
*/
|
||||
internal object SpeedOverlayFingerprint : LiteralValueFingerprint(
|
||||
returnType = "Z",
|
||||
|
@ -7,8 +7,9 @@ import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
/**
|
||||
* This value is the key for the playback speed overlay value.
|
||||
* Deprecated in YouTube v19.18.41+.
|
||||
*/
|
||||
internal object SpeedOverlayValueFingerprint : LiteralValueFingerprint(
|
||||
internal object SpeedOverlayFloatValueFingerprint : LiteralValueFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
opcodes = listOf(Opcode.DOUBLE_TO_FLOAT),
|
@ -1,14 +1,21 @@
|
||||
package app.revanced.patches.youtube.player.speedoverlay.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.util.fingerprint.ReferenceFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal object SpeedOverlayTextValueFingerprint : ReferenceFingerprint(
|
||||
internal object SpeedOverlayTextValueFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
opcodes = listOf(Opcode.CONST_WIDE_HIGH16),
|
||||
reference = { "Ljava/math/BigDecimal;->signum()I" }
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.indexOfFirstInstruction {
|
||||
getReference<MethodReference>()?.toString() == "Ljava/math/BigDecimal;->signum()I"
|
||||
} >= 0
|
||||
}
|
||||
)
|
@ -15,8 +15,8 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelF
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
@ -38,7 +38,7 @@ object ShortsAnimationPatch : BytecodePatch(
|
||||
ReelFeedbackPause to "setShortsPauseFeedback",
|
||||
ReelFeedbackPlay to "setShortsPlayFeedback",
|
||||
).forEach { (literal, methodName) ->
|
||||
val literalIndex = getWideLiteralInstructionIndex(literal)
|
||||
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(literal)
|
||||
val viewIndex = indexOfFirstInstructionOrThrow(literalIndex) {
|
||||
opcode == Opcode.CHECK_CAST
|
||||
&& (this as? ReferenceInstruction)?.reference?.toString() == LOTTIE_ANIMATION_VIEW_CLASS_DESCRIPTOR
|
||||
|
@ -35,12 +35,12 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Right
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.getTargetIndexWithReferenceOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.literalInstructionHook
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.replaceLiteralInstructionCall
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
@ -48,6 +48,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
object ShortsComponentPatch : BaseBytecodePatch(
|
||||
@ -106,10 +107,11 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
||||
|
||||
ShortsButtonFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(ReelRightDislikeIcon)
|
||||
val constIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(ReelRightDislikeIcon)
|
||||
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
|
||||
|
||||
val jumpIndex = getTargetIndexOrThrow(constIndex, Opcode.CONST_CLASS) + 2
|
||||
val jumpIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CONST_CLASS) + 2
|
||||
|
||||
addInstructionsWithLabels(
|
||||
constIndex + 1, """
|
||||
@ -128,9 +130,9 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
||||
|
||||
ShortsButtonFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = getWideLiteralInstructionIndex(ReelRightLikeIcon)
|
||||
val insertIndex = indexOfFirstWideLiteralInstructionValueOrThrow(ReelRightLikeIcon)
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
val jumpIndex = getTargetIndexOrThrow(insertIndex, Opcode.CONST_CLASS) + 2
|
||||
val jumpIndex = indexOfFirstInstructionOrThrow(insertIndex, Opcode.CONST_CLASS) + 2
|
||||
|
||||
addInstructionsWithLabels(
|
||||
insertIndex + 1, """
|
||||
@ -152,11 +154,12 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
||||
if (shortsPivotLegacyFingerprintResult != null) {
|
||||
// Legacy method.
|
||||
shortsPivotLegacyFingerprintResult.mutableMethod.apply {
|
||||
val targetIndex = getWideLiteralInstructionIndex(ReelForcedMuteButton)
|
||||
val targetIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(ReelForcedMuteButton)
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
val insertIndex = getTargetIndexReversedOrThrow(targetIndex, Opcode.IF_EQZ)
|
||||
val jumpIndex = getTargetIndexOrThrow(targetIndex, Opcode.GOTO)
|
||||
val insertIndex = indexOfFirstInstructionReversedOrThrow(targetIndex, Opcode.IF_EQZ)
|
||||
val jumpIndex = indexOfFirstInstructionOrThrow(targetIndex, Opcode.GOTO)
|
||||
|
||||
addInstructionsWithLabels(
|
||||
insertIndex, """
|
||||
@ -173,7 +176,7 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
||||
move-result v$REGISTER_TEMPLATE_REPLACEMENT
|
||||
"""
|
||||
|
||||
context.literalInstructionHook(
|
||||
context.replaceLiteralInstructionCall(
|
||||
ReelPlayerRightPivotV2Size,
|
||||
smaliInstruction
|
||||
)
|
||||
@ -242,7 +245,8 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
||||
lateinit var subscriptionFieldReference: FieldReference
|
||||
|
||||
parentResult.mutableMethod.apply {
|
||||
val targetIndex = getWideLiteralInstructionIndex(ReelPlayerFooter) - 1
|
||||
val targetIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(ReelPlayerFooter) - 1
|
||||
subscriptionFieldReference =
|
||||
(getInstruction<ReferenceInstruction>(targetIndex)).reference as FieldReference
|
||||
}
|
||||
@ -297,9 +301,9 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
||||
|
||||
TextComponentSpecFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex =
|
||||
getTargetIndexWithReferenceOrThrow("Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;")
|
||||
|
||||
val insertIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.toString() == "Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;"
|
||||
}
|
||||
val charSequenceRegister =
|
||||
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||
val conversionContextRegister =
|
||||
@ -342,11 +346,11 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
||||
) {
|
||||
resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(id)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(id)
|
||||
val insertIndex = if (reversed)
|
||||
getTargetIndexReversedOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
indexOfFirstInstructionReversedOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
else
|
||||
getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
@ -363,8 +367,8 @@ object ShortsComponentPatch : BaseBytecodePatch(
|
||||
) {
|
||||
resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val constIndex = getWideLiteralInstructionIndex(id)
|
||||
val insertIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(id)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
|
||||
|
||||
hideButtons(insertIndex, descriptor)
|
||||
}
|
||||
|
@ -10,10 +10,12 @@ import app.revanced.patches.youtube.shorts.components.fingerprints.RenderBottomN
|
||||
import app.revanced.patches.youtube.shorts.components.fingerprints.SetPivotBarFingerprint
|
||||
import app.revanced.patches.youtube.utils.fingerprints.InitializeButtonsFingerprint
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
object ShortsNavigationBarPatch : BytecodePatch(
|
||||
setOf(
|
||||
@ -51,7 +53,9 @@ object ShortsNavigationBarPatch : BytecodePatch(
|
||||
|
||||
BottomNavigationBarFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getTargetIndexWithMethodReferenceNameOrThrow("findViewById") + 1
|
||||
val targetIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "findViewById"
|
||||
} + 1
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -9,14 +9,18 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.shorts.components.fingerprints.ReelEnumConstructorFingerprint
|
||||
import app.revanced.patches.youtube.shorts.components.fingerprints.ReelEnumStaticFingerprint
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR
|
||||
import app.revanced.util.containsReferenceInstructionIndex
|
||||
import app.revanced.util.findMutableMethodOf
|
||||
import app.revanced.util.getStringInstructionIndex
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
|
||||
object ShortsRepeatPatch : BytecodePatch(
|
||||
setOf(ReelEnumConstructorFingerprint)
|
||||
@ -36,16 +40,15 @@ object ShortsRepeatPatch : BytecodePatch(
|
||||
}
|
||||
|
||||
val endScreenStringIndex =
|
||||
getStringInstructionIndex("REEL_LOOP_BEHAVIOR_END_SCREEN")
|
||||
indexOfFirstStringInstructionOrThrow("REEL_LOOP_BEHAVIOR_END_SCREEN")
|
||||
val endScreenReferenceIndex =
|
||||
getTargetIndexOrThrow(endScreenStringIndex, Opcode.SPUT_OBJECT)
|
||||
indexOfFirstInstructionOrThrow(endScreenStringIndex, Opcode.SPUT_OBJECT)
|
||||
val endScreenReference =
|
||||
getInstruction<ReferenceInstruction>(endScreenReferenceIndex).reference.toString()
|
||||
|
||||
val enumMethodName = ReelEnumStaticFingerprint.resultOrThrow().mutableMethod.name
|
||||
val enumMethodCall = "$definingClass->$enumMethodName(I)$definingClass"
|
||||
val enumMethod = ReelEnumStaticFingerprint.resultOrThrow().mutableMethod
|
||||
|
||||
context.injectHook(endScreenReference, enumMethodCall)
|
||||
context.injectHook(endScreenReference, enumMethod)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,8 +57,8 @@ object ShortsRepeatPatch : BytecodePatch(
|
||||
enumName: String,
|
||||
fieldName: String
|
||||
) {
|
||||
val stringIndex = getStringInstructionIndex(enumName)
|
||||
val insertIndex = getTargetIndexOrThrow(stringIndex, Opcode.SPUT_OBJECT)
|
||||
val stringIndex = indexOfFirstStringInstructionOrThrow(enumName)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(stringIndex, Opcode.SPUT_OBJECT)
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
@ -66,35 +69,41 @@ object ShortsRepeatPatch : BytecodePatch(
|
||||
|
||||
private fun BytecodeContext.injectHook(
|
||||
endScreenReference: String,
|
||||
enumMethodCall: String
|
||||
enumMethod: MutableMethod
|
||||
) {
|
||||
classes.forEach { classDef ->
|
||||
classDef.methods.filter { method ->
|
||||
method.parameters.size == 1
|
||||
&& method.parameters[0].startsWith("L")
|
||||
&& method.returnType == "V"
|
||||
&& method.containsReferenceInstructionIndex(endScreenReference)
|
||||
&& method.indexOfFirstInstruction {
|
||||
getReference<FieldReference>()?.toString() == endScreenReference
|
||||
} >= 0
|
||||
}.forEach { targetMethod ->
|
||||
proxy(classDef)
|
||||
.mutableClass
|
||||
.findMutableMethodOf(targetMethod)
|
||||
.apply {
|
||||
for ((index, instruction) in implementation!!.instructions.withIndex()) {
|
||||
if (instruction.opcode != Opcode.INVOKE_STATIC)
|
||||
continue
|
||||
if ((instruction as ReferenceInstruction).reference.toString() != enumMethodCall)
|
||||
continue
|
||||
implementation!!.instructions
|
||||
.withIndex()
|
||||
.filter { (_, instruction) ->
|
||||
val reference = (instruction as? ReferenceInstruction)?.reference
|
||||
reference is MethodReference &&
|
||||
MethodUtil.methodSignaturesMatch(enumMethod, reference)
|
||||
}
|
||||
.map { (index, _) -> index }
|
||||
.reversed()
|
||||
.forEach { index ->
|
||||
val register =
|
||||
getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||
|
||||
val register =
|
||||
getInstruction<OneRegisterInstruction>(index + 1).registerA
|
||||
|
||||
addInstructions(
|
||||
index + 2, """
|
||||
invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->changeShortsRepeatState(Ljava/lang/Enum;)Ljava/lang/Enum;
|
||||
move-result-object v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
addInstructions(
|
||||
index + 2, """
|
||||
invoke-static {v$register}, $SHORTS_CLASS_DESCRIPTOR->changeShortsRepeatState(Ljava/lang/Enum;)Ljava/lang/Enum;
|
||||
move-result-object v$register
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.MetaP
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelVodTimeStampsContainer
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.literalInstructionViewHook
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.injectLiteralInstructionViewCall
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@ -38,14 +38,14 @@ object ShortsTimeStampPatch : BytecodePatch(
|
||||
ShortsTimeStampPrimaryFingerprint to 45638282,
|
||||
ShortsTimeStampSecondaryFingerprint to 45638187
|
||||
).forEach { (fingerprint, literal) ->
|
||||
fingerprint.literalInstructionBooleanHook(
|
||||
fingerprint.injectLiteralInstructionBooleanCall(
|
||||
literal,
|
||||
"$SHORTS_CLASS_DESCRIPTOR->enableShortsTimeStamp(Z)Z"
|
||||
)
|
||||
}
|
||||
|
||||
ShortsTimeStampPrimaryFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val literalIndex = getWideLiteralInstructionIndex(10002)
|
||||
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(10002)
|
||||
val literalRegister = getInstruction<OneRegisterInstruction>(literalIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
@ -81,7 +81,7 @@ object ShortsTimeStampPatch : BytecodePatch(
|
||||
invoke-static {v$REGISTER_TEMPLATE_REPLACEMENT}, $SHORTS_CLASS_DESCRIPTOR->$methodName(Landroid/view/View;)V
|
||||
"""
|
||||
|
||||
fingerprint.literalInstructionViewHook(literalValue, smaliInstruction)
|
||||
fingerprint.injectLiteralInstructionViewCall(literalValue, smaliInstruction)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
@ -4,13 +4,13 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelFeedbackLike
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelFeedbackPause
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelFeedbackPlay
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
|
||||
internal object ReelFeedbackFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(ReelFeedbackLike)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(ReelFeedbackPause)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(ReelFeedbackPlay)
|
||||
methodDef.containsWideLiteralInstructionValue(ReelFeedbackLike)
|
||||
&& methodDef.containsWideLiteralInstructionValue(ReelFeedbackPause)
|
||||
&& methodDef.containsWideLiteralInstructionValue(ReelFeedbackPlay)
|
||||
},
|
||||
)
|
@ -6,15 +6,15 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelD
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelRightDislikeIcon
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ReelRightLikeIcon
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.RightComment
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
|
||||
internal object ShortsButtonFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(ReelDynRemix)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(ReelDynShare)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(ReelRightDislikeIcon)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(ReelRightLikeIcon)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(RightComment)
|
||||
methodDef.containsWideLiteralInstructionValue(ReelDynRemix)
|
||||
&& methodDef.containsWideLiteralInstructionValue(ReelDynShare)
|
||||
&& methodDef.containsWideLiteralInstructionValue(ReelRightDislikeIcon)
|
||||
&& methodDef.containsWideLiteralInstructionValue(ReelRightLikeIcon)
|
||||
&& methodDef.containsWideLiteralInstructionValue(RightComment)
|
||||
},
|
||||
)
|
@ -2,7 +2,7 @@ package app.revanced.patches.youtube.shorts.components.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object ShortsTimeStampPrimaryFingerprint : MethodFingerprint(
|
||||
@ -10,8 +10,8 @@ internal object ShortsTimeStampPrimaryFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("I"),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(45627350)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(45638282)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(10002)
|
||||
methodDef.containsWideLiteralInstructionValue(45627350)
|
||||
&& methodDef.containsWideLiteralInstructionValue(45638282)
|
||||
&& methodDef.containsWideLiteralInstructionValue(10002)
|
||||
},
|
||||
)
|
@ -23,8 +23,8 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.literalInstructionBooleanHook
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import app.revanced.util.transformMethods
|
||||
@ -90,7 +90,8 @@ object SwipeControlsPatch : BaseBytecodePatch(
|
||||
|
||||
FullScreenEngagementOverlayFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val viewIndex = getWideLiteralInstructionIndex(FullScreenEngagementOverlay) + 3
|
||||
val viewIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(FullScreenEngagementOverlay) + 3
|
||||
val viewRegister = getInstruction<OneRegisterInstruction>(viewIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
@ -131,7 +132,7 @@ object SwipeControlsPatch : BaseBytecodePatch(
|
||||
// Since it does not support all versions,
|
||||
// add settings only if the patch is successful.
|
||||
SwipeToSwitchVideoFingerprint.result?.let {
|
||||
SwipeToSwitchVideoFingerprint.literalInstructionBooleanHook(
|
||||
SwipeToSwitchVideoFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45631116,
|
||||
"$INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->enableSwipeToSwitchVideo()Z"
|
||||
)
|
||||
@ -147,7 +148,7 @@ object SwipeControlsPatch : BaseBytecodePatch(
|
||||
// Since it does not support all versions,
|
||||
// add settings only if the patch is successful.
|
||||
WatchPanelGesturesFingerprint.result?.let {
|
||||
WatchPanelGesturesFingerprint.literalInstructionBooleanHook(
|
||||
WatchPanelGesturesFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45372793,
|
||||
"$INTEGRATIONS_SWIPE_CONTROLS_PATCH_CLASS_DESCRIPTOR->enableWatchPanelGestures()Z"
|
||||
)
|
||||
|
@ -17,11 +17,14 @@ import app.revanced.patches.youtube.utils.integrations.Constants.PATCH_STATUS_CL
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import app.revanced.util.updatePatchStatus
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(dependencies = [SharedResourceIdPatch::class])
|
||||
object CastButtonPatch : BytecodePatch(
|
||||
@ -39,12 +42,11 @@ object CastButtonPatch : BytecodePatch(
|
||||
|
||||
override fun execute(context: BytecodeContext) {
|
||||
|
||||
val toolbarMenuItemInitializeResult = MenuItemInitializeFingerprint.resultOrThrow()
|
||||
MenuItemVisibilityFingerprint.resolve(context, toolbarMenuItemInitializeResult.classDef)
|
||||
|
||||
toolbarMenuItemInitializeMethod = toolbarMenuItemInitializeResult.mutableMethod
|
||||
toolbarMenuItemVisibilityMethod =
|
||||
MenuItemVisibilityFingerprint.resultOrThrow().mutableMethod
|
||||
toolbarMenuItemInitializeMethod = MenuItemInitializeFingerprint.resultOrThrow()
|
||||
.mutableMethod
|
||||
toolbarMenuItemVisibilityMethod = MenuItemVisibilityFingerprint.alsoResolve(
|
||||
context, MenuItemInitializeFingerprint
|
||||
).mutableMethod
|
||||
|
||||
playerButtonMethod = PlayerButtonFingerprint.resultOrThrow().mutableMethod
|
||||
|
||||
@ -64,7 +66,9 @@ object CastButtonPatch : BytecodePatch(
|
||||
|
||||
internal fun hookPlayerButton(context: BytecodeContext) {
|
||||
playerButtonMethod.apply {
|
||||
val index = getTargetIndexWithMethodReferenceNameOrThrow("setVisibility")
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "setVisibility"
|
||||
}
|
||||
val instruction = getInstruction<FiveRegisterInstruction>(index)
|
||||
val viewRegister = instruction.registerC
|
||||
val visibilityRegister = instruction.registerD
|
||||
@ -84,8 +88,9 @@ object CastButtonPatch : BytecodePatch(
|
||||
|
||||
internal fun hookToolBarButton(context: BytecodeContext) {
|
||||
toolbarMenuItemInitializeMethod.apply {
|
||||
val index = getTargetIndexWithMethodReferenceNameOrThrow("setShowAsAction") + 1
|
||||
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "setShowAsAction"
|
||||
} + 1
|
||||
addInstruction(
|
||||
index,
|
||||
"invoke-static {p1}, $GENERAL_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/MenuItem;)V"
|
||||
|
@ -1,12 +1,19 @@
|
||||
package app.revanced.patches.youtube.utils.castbutton.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal object MenuItemVisibilityFingerprint : MethodReferenceNameFingerprint(
|
||||
internal object MenuItemVisibilityFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = listOf("Z"),
|
||||
reference = { "setVisible" }
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.indexOfFirstInstruction {
|
||||
getReference<MethodReference>()?.name == "setVisible"
|
||||
} >= 0
|
||||
}
|
||||
)
|
@ -4,15 +4,15 @@ import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InlineTimeBarColorizedBarPlayedColorDark
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.InlineTimeBarPlayedNotHighlightedColor
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object PlayerSeekbarColorFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(InlineTimeBarColorizedBarPlayedColorDark)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(
|
||||
methodDef.containsWideLiteralInstructionValue(InlineTimeBarColorizedBarPlayedColorDark)
|
||||
&& methodDef.containsWideLiteralInstructionValue(
|
||||
InlineTimeBarPlayedNotHighlightedColor
|
||||
)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Inset
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ScrimOverlay
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SeekUndoEduOverlayStub
|
||||
import app.revanced.patches.youtube.utils.sponsorblock.SponsorBlockBytecodePatch
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
@ -26,9 +26,9 @@ internal object YouTubeControlsOverlayFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(FadeDurationFast)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(InsetOverlayViewLayout)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(ScrimOverlay)
|
||||
&& methodDef.containsWideLiteralInstructionIndex(SeekUndoEduOverlayStub)
|
||||
methodDef.containsWideLiteralInstructionValue(FadeDurationFast)
|
||||
&& methodDef.containsWideLiteralInstructionValue(InsetOverlayViewLayout)
|
||||
&& methodDef.containsWideLiteralInstructionValue(ScrimOverlay)
|
||||
&& methodDef.containsWideLiteralInstructionValue(SeekUndoEduOverlayStub)
|
||||
}
|
||||
)
|
@ -1,16 +1,11 @@
|
||||
package app.revanced.patches.youtube.utils.fix.bottomui
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.youtube.utils.fix.bottomui.fingerprints.FullscreenButtonPositionFingerprint
|
||||
import app.revanced.patches.youtube.utils.fix.bottomui.fingerprints.FullscreenButtonViewStubFingerprint
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
|
||||
@Patch(
|
||||
description = "Fixes an issue where overlay button patches were broken by the new layout."
|
||||
@ -32,19 +27,10 @@ object CfBottomUIPatch : BytecodePatch(
|
||||
FullscreenButtonPositionFingerprint to 45627640
|
||||
).forEach { (fingerprint, literalValue) ->
|
||||
fingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getTargetIndexOrThrow(
|
||||
getWideLiteralInstructionIndex(literalValue.toLong()),
|
||||
Opcode.MOVE_RESULT
|
||||
)
|
||||
val targetRegister =
|
||||
getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
targetIndex + 1,
|
||||
"const/4 v$targetRegister, 0x0"
|
||||
)
|
||||
}
|
||||
fingerprint.injectLiteralInstructionBooleanCall(
|
||||
literalValue,
|
||||
"0x0"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,11 @@
|
||||
package app.revanced.patches.youtube.utils.fix.cairo
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.youtube.misc.backgroundplayback.BackgroundPlaybackPatch
|
||||
import app.revanced.patches.youtube.utils.fix.cairo.fingerprints.CarioFragmentConfigFingerprint
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
|
||||
@Patch(
|
||||
description = "Fixes issues where Cairo Fragment is applied."
|
||||
@ -31,19 +26,10 @@ object CairoSettingsPatch : BytecodePatch(
|
||||
* for screenshots of the Cairo Fragment.
|
||||
*/
|
||||
CarioFragmentConfigFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex =
|
||||
getTargetIndexOrThrow(
|
||||
getWideLiteralInstructionIndex(45532100),
|
||||
Opcode.MOVE_RESULT
|
||||
)
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
targetIndex + 1,
|
||||
"const/4 v$targetRegister, 0x0"
|
||||
)
|
||||
}
|
||||
CarioFragmentConfigFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45532100,
|
||||
"0x0"
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,10 @@
|
||||
package app.revanced.patches.youtube.utils.fix.shortsplayback
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.youtube.utils.fix.shortsplayback.fingerprints.ShortsPlaybackFingerprint
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
|
||||
@Patch(
|
||||
description = "Fix issue with looping at the start of the video when applying default video quality to Shorts."
|
||||
@ -26,19 +21,10 @@ object ShortsPlaybackPatch : BytecodePatch(
|
||||
* RVX applies default video quality to Shorts as well, so this patch is required.
|
||||
*/
|
||||
ShortsPlaybackFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex =
|
||||
getTargetIndexOrThrow(
|
||||
getWideLiteralInstructionIndex(45387052),
|
||||
Opcode.MOVE_RESULT
|
||||
)
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
targetIndex + 1,
|
||||
"const/4 v$targetRegister, 0x0"
|
||||
)
|
||||
}
|
||||
ShortsPlaybackFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45387052,
|
||||
"0x0"
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints.RemoveOnLayoutChangeListenerFingerprint
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
@ -36,9 +36,10 @@ object SuggestedVideoEndScreenPatch : BytecodePatch(
|
||||
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.endIndex)
|
||||
|
||||
walkerIndex.apply {
|
||||
val invokeInterfaceIndex = getTargetIndexOrThrow(Opcode.INVOKE_INTERFACE)
|
||||
val invokeInterfaceIndex =
|
||||
indexOfFirstInstructionOrThrow(opcode = Opcode.INVOKE_INTERFACE)
|
||||
val iGetObjectIndex =
|
||||
getTargetIndexReversedOrThrow(invokeInterfaceIndex, Opcode.IGET_OBJECT)
|
||||
indexOfFirstInstructionReversedOrThrow(invokeInterfaceIndex, Opcode.IGET_OBJECT)
|
||||
|
||||
val invokeInterfaceReference =
|
||||
getInstruction<ReferenceInstruction>(invokeInterfaceIndex).reference
|
||||
|
@ -1,15 +1,18 @@
|
||||
package app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.util.fingerprint.ReferenceFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
/**
|
||||
* This fingerprint is also compatible with very old YouTube versions.
|
||||
* Tested on YouTube v16.40.36, v18.29.38, v19.12.41.
|
||||
* Tested on YouTube v16.40.36, v18.29.38, v19.16.39.
|
||||
*/
|
||||
internal object RemoveOnLayoutChangeListenerFingerprint : ReferenceFingerprint(
|
||||
internal object RemoveOnLayoutChangeListenerFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
parameters = emptyList(),
|
||||
@ -18,5 +21,10 @@ internal object RemoveOnLayoutChangeListenerFingerprint : ReferenceFingerprint(
|
||||
Opcode.INVOKE_VIRTUAL
|
||||
),
|
||||
// This is the only reference present in the entire smali.
|
||||
reference = { "YouTubePlayerOverlaysLayout;->removeOnLayoutChangeListener(Landroid/view/View${'$'}OnLayoutChangeListener;)V" }
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.indexOfFirstInstruction {
|
||||
getReference<MethodReference>()?.toString()
|
||||
?.endsWith("YouTubePlayerOverlaysLayout;->removeOnLayoutChangeListener(Landroid/view/View${'$'}OnLayoutChangeListener;)V") == true
|
||||
} >= 0
|
||||
}
|
||||
)
|
@ -16,8 +16,8 @@ import app.revanced.patches.youtube.utils.playercontrols.fingerprints.MotionEven
|
||||
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityEntityModelFingerprint
|
||||
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
@ -50,13 +50,11 @@ object PlayerControlsPatch : BytecodePatch(
|
||||
|
||||
// region patch for hook visibility of play control buttons (e.g. pause, play button, etc)
|
||||
|
||||
PlayerButtonsVisibilityFingerprint.resolve(
|
||||
context,
|
||||
PlayerButtonsResourcesFingerprint.resultOrThrow().mutableClass
|
||||
)
|
||||
PlayerButtonsVisibilityFingerprint.resultOrThrow().let {
|
||||
PlayerButtonsVisibilityFingerprint.alsoResolve(
|
||||
context, PlayerButtonsResourcesFingerprint
|
||||
).let {
|
||||
it.mutableMethod.apply {
|
||||
val viewIndex = getTargetIndexOrThrow(Opcode.INVOKE_INTERFACE)
|
||||
val viewIndex = indexOfFirstInstructionOrThrow(opcode = Opcode.INVOKE_INTERFACE)
|
||||
val viewRegister = getInstruction<FiveRegisterInstruction>(viewIndex).registerD
|
||||
|
||||
addInstruction(
|
||||
@ -70,11 +68,9 @@ object PlayerControlsPatch : BytecodePatch(
|
||||
|
||||
// region patch for hook visibility of play controls layout
|
||||
|
||||
PlayerControlsVisibilityFingerprint.resolve(
|
||||
context,
|
||||
YouTubeControlsOverlayFingerprint.resultOrThrow().mutableClass
|
||||
)
|
||||
PlayerControlsVisibilityFingerprint.resultOrThrow().mutableMethod.addInstruction(
|
||||
PlayerControlsVisibilityFingerprint.alsoResolve(
|
||||
context, YouTubeControlsOverlayFingerprint
|
||||
).mutableMethod.addInstruction(
|
||||
0,
|
||||
"invoke-static {p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->changeVisibility(Z)V"
|
||||
)
|
||||
@ -83,12 +79,10 @@ object PlayerControlsPatch : BytecodePatch(
|
||||
|
||||
// region patch for detecting motion events in play controls layout
|
||||
|
||||
MotionEventFingerprint.resolve(
|
||||
context,
|
||||
YouTubeControlsOverlayFingerprint.resultOrThrow().mutableClass
|
||||
)
|
||||
MotionEventFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val insertIndex = getTargetIndexWithMethodReferenceNameOrThrow("setTranslationY") + 1
|
||||
MotionEventFingerprint.alsoResolve(
|
||||
context, YouTubeControlsOverlayFingerprint
|
||||
).mutableMethod.apply {
|
||||
val insertIndex = MotionEventFingerprint.indexOfTranslationInstruction(this) + 1
|
||||
|
||||
addInstruction(
|
||||
insertIndex,
|
||||
|
@ -9,7 +9,7 @@ import app.revanced.patcher.patch.annotation.Patch
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
|
||||
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.PlayerControlsVisibilityEntityModelFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
@ -31,7 +31,7 @@ object PlayerControlsVisibilityHookPatch : BytecodePatch(
|
||||
val staticReference = getInstruction<ReferenceInstruction>(startIndex + 1).reference
|
||||
|
||||
it.mutableClass.methods.find { method -> method.name == "<init>" }?.apply {
|
||||
val targetIndex = getTargetIndexOrThrow(Opcode.IPUT_OBJECT)
|
||||
val targetIndex = indexOfFirstInstructionOrThrow(Opcode.IPUT_OBJECT)
|
||||
val targetRegister =
|
||||
getInstruction<TwoRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
|
@ -1,9 +1,21 @@
|
||||
package app.revanced.patches.youtube.utils.playercontrols.fingerprints
|
||||
|
||||
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.playercontrols.fingerprints.MotionEventFingerprint.indexOfTranslationInstruction
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionReversed
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal object MotionEventFingerprint : MethodReferenceNameFingerprint(
|
||||
internal object MotionEventFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = listOf("Landroid/view/MotionEvent;"),
|
||||
reference = { "setTranslationY" }
|
||||
)
|
||||
customFingerprint = { methodDef, _ ->
|
||||
indexOfTranslationInstruction(methodDef) >= 0
|
||||
}
|
||||
) {
|
||||
fun indexOfTranslationInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstructionReversed {
|
||||
getReference<MethodReference>()?.name == "setTranslationY"
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ import app.revanced.patches.youtube.utils.playertype.fingerprint.PlayerTypeFinge
|
||||
import app.revanced.patches.youtube.utils.playertype.fingerprint.VideoStateFingerprint
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||
import app.revanced.util.addFieldAndInstructions
|
||||
import app.revanced.util.getStringInstructionIndex
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
@ -82,14 +82,14 @@ object PlayerTypeHookPatch : BytecodePatch(
|
||||
|
||||
BrowseIdClassFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getStringInstructionIndex("VL") - 1
|
||||
val targetIndex = indexOfFirstStringInstructionOrThrow("VL") - 1
|
||||
val targetReference = getInstruction<ReferenceInstruction>(targetIndex).reference
|
||||
val targetClass =
|
||||
context.findClass((targetReference as FieldReference).definingClass)!!.mutableClass
|
||||
|
||||
targetClass.methods.find { method -> method.name == "<init>" }
|
||||
?.apply {
|
||||
val browseIdFieldIndex = getTargetIndexOrThrow(Opcode.IPUT_OBJECT)
|
||||
val browseIdFieldIndex = indexOfFirstInstructionOrThrow(Opcode.IPUT_OBJECT)
|
||||
val browseIdFieldName =
|
||||
(getInstruction<ReferenceInstruction>(browseIdFieldIndex).reference as FieldReference).name
|
||||
|
||||
|
@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.playertype.fingerprint.ActionBarSearchResultsFingerprint.indexOfLayoutDirectionInstruction
|
||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ActionBarSearchResultsViewMic
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
@ -16,7 +16,7 @@ internal object ActionBarSearchResultsFingerprint : MethodFingerprint(
|
||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||
returnType = "Landroid/view/View;",
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.containsWideLiteralInstructionIndex(ActionBarSearchResultsViewMic) &&
|
||||
methodDef.containsWideLiteralInstructionValue(ActionBarSearchResultsViewMic) &&
|
||||
indexOfLayoutDirectionInstruction(methodDef) >= 0
|
||||
}
|
||||
) {
|
||||
|
@ -2,18 +2,16 @@ package app.revanced.patches.youtube.utils.recyclerview
|
||||
|
||||
import app.revanced.patcher.data.BytecodeContext
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.utils.recyclerview.fingerprints.BottomSheetRecyclerViewBuilderFingerprint
|
||||
import app.revanced.patches.youtube.utils.recyclerview.fingerprints.RecyclerViewTreeObserverFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.injectLiteralInstructionBooleanCall
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
object BottomSheetRecyclerViewPatch : BytecodePatch(
|
||||
@ -35,15 +33,10 @@ object BottomSheetRecyclerViewPatch : BytecodePatch(
|
||||
* Therefore, we need to force this to be true.
|
||||
*/
|
||||
BottomSheetRecyclerViewBuilderFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getWideLiteralInstructionIndex(45382015) + 2
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
targetIndex + 1,
|
||||
"const/4 v$targetRegister, 0x1"
|
||||
)
|
||||
}
|
||||
BottomSheetRecyclerViewBuilderFingerprint.injectLiteralInstructionBooleanCall(
|
||||
45382015,
|
||||
"0x1"
|
||||
)
|
||||
}
|
||||
|
||||
RecyclerViewTreeObserverFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
@ -54,7 +47,7 @@ object BottomSheetRecyclerViewPatch : BytecodePatch(
|
||||
&& getReference<FieldReference>()?.type == "Landroid/view/ViewTreeObserver${'$'}OnDrawListener;"
|
||||
}
|
||||
recyclerViewTreeObserverInsertIndex =
|
||||
getTargetIndexReversedOrThrow(onDrawListenerIndex, Opcode.CHECK_CAST) + 1
|
||||
indexOfFirstInstructionReversedOrThrow(onDrawListenerIndex, Opcode.CHECK_CAST) + 1
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,16 +20,15 @@ import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexWithFieldReferenceType
|
||||
import app.revanced.util.getTargetIndexWithFieldReferenceTypeOrThrow
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused")
|
||||
@ -78,13 +77,15 @@ object ReturnYouTubeDislikePatch : BaseBytecodePatch(
|
||||
|
||||
TextComponentContextFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val conversionContextFieldIndex =
|
||||
getTargetIndexWithFieldReferenceTypeOrThrow("Ljava/util/Map;") - 1
|
||||
val conversionContextFieldIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<FieldReference>()?.type == "Ljava/util/Map;"
|
||||
} - 1
|
||||
val conversionContextFieldReference =
|
||||
getInstruction<ReferenceInstruction>(conversionContextFieldIndex).reference
|
||||
|
||||
val charSequenceIndex1932 =
|
||||
getTargetIndexWithFieldReferenceType("Ljava/util/BitSet;") - 1
|
||||
val charSequenceIndex1932 = indexOfFirstInstruction {
|
||||
getReference<FieldReference>()?.type == "Ljava/util/BitSet;"
|
||||
} - 1
|
||||
val charSequenceIndex1933 = indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>()
|
||||
opcode == Opcode.INVOKE_VIRTUAL &&
|
||||
@ -108,7 +109,7 @@ object ReturnYouTubeDislikePatch : BaseBytecodePatch(
|
||||
}
|
||||
|
||||
val freeRegister = getInstruction<TwoRegisterInstruction>(
|
||||
getTargetIndexOrThrow(insertIndex, Opcode.IGET_OBJECT)
|
||||
indexOfFirstInstructionOrThrow(insertIndex, Opcode.IGET_OBJECT)
|
||||
).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -17,14 +17,15 @@ import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fin
|
||||
import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberMeasureTextParentFingerprint
|
||||
import app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints.RollingNumberSetterFingerprint
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
||||
|
||||
@Patch(dependencies = [SettingsPatch::class])
|
||||
@ -60,7 +61,8 @@ object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
|
||||
|
||||
rollingNumberClass.methods.find { method -> method.name == "<init>" }
|
||||
?.apply {
|
||||
val rollingNumberFieldIndex = getTargetIndexOrThrow(Opcode.IPUT_OBJECT)
|
||||
val rollingNumberFieldIndex =
|
||||
indexOfFirstInstructionOrThrow(opcode = Opcode.IPUT_OBJECT)
|
||||
charSequenceFieldReference =
|
||||
getInstruction<ReferenceInstruction>(rollingNumberFieldIndex).reference
|
||||
} ?: throw PatchException("RollingNumberClass not found!")
|
||||
@ -103,7 +105,7 @@ object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
|
||||
"""
|
||||
)
|
||||
|
||||
val ifGeIndex = getTargetIndexOrThrow(Opcode.IF_GE)
|
||||
val ifGeIndex = indexOfFirstInstructionOrThrow(opcode = Opcode.IF_GE)
|
||||
val ifGeInstruction = getInstruction<TwoRegisterInstruction>(ifGeIndex)
|
||||
|
||||
removeInstruction(ifGeIndex)
|
||||
@ -153,7 +155,9 @@ object ReturnYouTubeDislikeRollingNumberPatch : BytecodePatch(
|
||||
realTimeUpdateTextViewMethod
|
||||
).forEach { insertMethod ->
|
||||
insertMethod.apply {
|
||||
val setTextIndex = getTargetIndexWithMethodReferenceNameOrThrow("setText")
|
||||
val setTextIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "setText"
|
||||
}
|
||||
val textViewRegister =
|
||||
getInstruction<FiveRegisterInstruction>(setTextIndex).registerC
|
||||
val textSpanRegister =
|
||||
|
@ -1,12 +1,15 @@
|
||||
package app.revanced.patches.youtube.utils.returnyoutubedislike.rollingnumber.fingerprints
|
||||
|
||||
import app.revanced.util.fingerprint.ReferenceFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
/**
|
||||
* This fingerprint is compatible with YouTube v18.30.xx+
|
||||
*/
|
||||
internal object RollingNumberMeasureAnimatedTextFingerprint : ReferenceFingerprint(
|
||||
internal object RollingNumberMeasureAnimatedTextFingerprint : MethodFingerprint(
|
||||
opcodes = listOf(
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
@ -14,5 +17,9 @@ internal object RollingNumberMeasureAnimatedTextFingerprint : ReferenceFingerpri
|
||||
Opcode.ADD_INT_LIT8,
|
||||
Opcode.GOTO
|
||||
),
|
||||
reference = { "Landroid/text/TextPaint;->measureText([CII)F" }
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.indexOfFirstInstruction {
|
||||
getReference<MethodReference>()?.toString() == "Landroid/text/TextPaint;->measureText([CII)F"
|
||||
} >= 0
|
||||
}
|
||||
)
|
@ -12,14 +12,15 @@ import app.revanced.patches.youtube.utils.fingerprints.TextComponentSpecFingerpr
|
||||
import app.revanced.patches.youtube.utils.integrations.Constants.UTILS_PATH
|
||||
import app.revanced.patches.youtube.utils.returnyoutubedislike.shorts.fingerprints.ShortsTextViewFingerprint
|
||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.getTargetIndexWithReferenceOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(dependencies = [SettingsPatch::class])
|
||||
object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
|
||||
@ -37,9 +38,9 @@ object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
|
||||
val startIndex = it.scanResult.patternScanResult!!.startIndex
|
||||
|
||||
val isDisLikesBooleanIndex =
|
||||
getTargetIndexReversedOrThrow(startIndex, Opcode.IGET_BOOLEAN)
|
||||
indexOfFirstInstructionReversedOrThrow(startIndex, Opcode.IGET_BOOLEAN)
|
||||
val textViewFieldIndex =
|
||||
getTargetIndexReversedOrThrow(startIndex, Opcode.IGET_OBJECT)
|
||||
indexOfFirstInstructionReversedOrThrow(startIndex, Opcode.IGET_OBJECT)
|
||||
|
||||
// If the field is true, the TextView is for a dislike button.
|
||||
val isDisLikesBooleanReference =
|
||||
@ -51,7 +52,7 @@ object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
|
||||
// Check if the hooked TextView object is that of the dislike button.
|
||||
// If RYD is disabled, or the TextView object is not that of the dislike button, the execution flow is not interrupted.
|
||||
// Otherwise, the TextView object is modified, and the execution flow is interrupted to prevent it from being changed afterward.
|
||||
val insertIndex = getTargetIndexOrThrow(Opcode.CHECK_CAST) + 1
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.CHECK_CAST) + 1
|
||||
|
||||
addInstructionsWithLabels(
|
||||
insertIndex, """
|
||||
@ -73,14 +74,13 @@ object ReturnYouTubeDislikeShortsPatch : BytecodePatch(
|
||||
if (SettingsPatch.upward1834) {
|
||||
TextComponentSpecFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex =
|
||||
getTargetIndexWithReferenceOrThrow("Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;")
|
||||
|
||||
val insertIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.toString() == "Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;"
|
||||
}
|
||||
val charSequenceRegister =
|
||||
getInstruction<FiveRegisterInstruction>(insertIndex).registerC
|
||||
val conversionContextRegister =
|
||||
getInstruction<TwoRegisterInstruction>(0).registerA
|
||||
|
||||
val replaceReference =
|
||||
getInstruction<ReferenceInstruction>(insertIndex).reference
|
||||
|
||||
|
@ -19,11 +19,11 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.Inset
|
||||
import app.revanced.patches.youtube.utils.sponsorblock.fingerprints.RectangleFieldInvalidatorFingerprint
|
||||
import app.revanced.patches.youtube.utils.sponsorblock.fingerprints.SegmentPlaybackControllerFingerprint
|
||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexWithFieldReferenceTypeReversedOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameReversedOrThrow
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import app.revanced.util.updatePatchStatus
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -31,6 +31,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Patch(
|
||||
dependencies = [
|
||||
@ -74,13 +75,11 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
val seekBarClass = SeekbarFingerprint.resultOrThrow().mutableClass
|
||||
SeekbarOnDrawFingerprint.resolve(context, seekBarClass)
|
||||
RectangleFieldInvalidatorFingerprint.resolve(context, seekBarClass)
|
||||
|
||||
SeekbarOnDrawFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
SeekbarOnDrawFingerprint.alsoResolve(
|
||||
context, SeekbarFingerprint
|
||||
).mutableMethod.apply {
|
||||
// Get left and right of seekbar rectangle
|
||||
val moveObjectIndex = getTargetIndexOrThrow(Opcode.MOVE_OBJECT_FROM16)
|
||||
val moveObjectIndex = indexOfFirstInstructionOrThrow(opcode = Opcode.MOVE_OBJECT_FROM16)
|
||||
|
||||
addInstruction(
|
||||
moveObjectIndex + 1,
|
||||
@ -89,7 +88,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
)
|
||||
|
||||
// Set seekbar thickness
|
||||
val roundIndex = getTargetIndexWithMethodReferenceNameOrThrow("round") + 1
|
||||
val roundIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "round"
|
||||
} + 1
|
||||
val roundRegister = getInstruction<OneRegisterInstruction>(roundIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
@ -99,7 +100,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
)
|
||||
|
||||
// Draw segment
|
||||
val drawCircleIndex = getTargetIndexWithMethodReferenceNameReversedOrThrow("drawCircle")
|
||||
val drawCircleIndex = indexOfFirstInstructionReversedOrThrow {
|
||||
getReference<MethodReference>()?.name == "drawCircle"
|
||||
}
|
||||
val drawCircleInstruction = getInstruction<FiveRegisterInstruction>(drawCircleIndex)
|
||||
addInstruction(
|
||||
drawCircleIndex,
|
||||
@ -116,7 +119,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
// Append timestamp
|
||||
TotalTimeFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getTargetIndexWithMethodReferenceNameOrThrow("getString") + 1
|
||||
val targetIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "getString"
|
||||
} + 1
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
@ -131,8 +136,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
// Initialize the SponsorBlock view
|
||||
YouTubeControlsOverlayFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val targetIndex = getWideLiteralInstructionIndex(InsetOverlayViewLayout)
|
||||
val checkCastIndex = getTargetIndexOrThrow(targetIndex, Opcode.CHECK_CAST)
|
||||
val targetIndex =
|
||||
indexOfFirstWideLiteralInstructionValueOrThrow(InsetOverlayViewLayout)
|
||||
val checkCastIndex = indexOfFirstInstructionOrThrow(targetIndex, Opcode.CHECK_CAST)
|
||||
val targetRegister =
|
||||
getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
|
||||
|
||||
@ -144,14 +150,15 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
||||
}
|
||||
|
||||
// Replace strings
|
||||
RectangleFieldInvalidatorFingerprint.resultOrThrow().let { result ->
|
||||
RectangleFieldInvalidatorFingerprint.alsoResolve(
|
||||
context, SeekbarFingerprint
|
||||
).let { result ->
|
||||
result.mutableMethod.apply {
|
||||
val invalidateIndex =
|
||||
getTargetIndexWithMethodReferenceNameReversedOrThrow("invalidate")
|
||||
val rectangleIndex = getTargetIndexWithFieldReferenceTypeReversedOrThrow(
|
||||
invalidateIndex + 1,
|
||||
"Landroid/graphics/Rect;"
|
||||
)
|
||||
RectangleFieldInvalidatorFingerprint.indexOfInvalidateInstruction(this)
|
||||
val rectangleIndex = indexOfFirstInstructionReversedOrThrow(invalidateIndex + 1) {
|
||||
getReference<FieldReference>()?.type == "Landroid/graphics/Rect;"
|
||||
}
|
||||
val rectangleFieldName =
|
||||
(getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name
|
||||
|
||||
|
@ -1,9 +1,21 @@
|
||||
package app.revanced.patches.youtube.utils.sponsorblock.fingerprints
|
||||
|
||||
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.sponsorblock.fingerprints.RectangleFieldInvalidatorFingerprint.indexOfInvalidateInstruction
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionReversed
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
internal object RectangleFieldInvalidatorFingerprint : MethodReferenceNameFingerprint(
|
||||
internal object RectangleFieldInvalidatorFingerprint : MethodFingerprint(
|
||||
returnType = "V",
|
||||
parameters = emptyList(),
|
||||
reference = { "invalidate" }
|
||||
)
|
||||
customFingerprint = { methodDef, _ ->
|
||||
indexOfInvalidateInstruction(methodDef) >= 0
|
||||
}
|
||||
) {
|
||||
fun indexOfInvalidateInstruction(methodDef: Method) =
|
||||
methodDef.indexOfFirstInstructionReversed {
|
||||
getReference<MethodReference>()?.name == "invalidate"
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,12 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatch
|
||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||
import app.revanced.patches.youtube.utils.trackingurlhook.fingerprints.TrackingUrlModelFingerprint
|
||||
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
object TrackingUrlHookPatch : BytecodePatch(
|
||||
setOf(TrackingUrlModelFingerprint)
|
||||
@ -22,7 +25,10 @@ object TrackingUrlHookPatch : BytecodePatch(
|
||||
internal fun hookTrackingUrl(
|
||||
descriptor: String
|
||||
) = trackingUrlMethod.apply {
|
||||
val targetIndex = getTargetIndexWithMethodReferenceNameOrThrow("parse") + 1
|
||||
val targetIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.INVOKE_STATIC &&
|
||||
getReference<MethodReference>()?.name == "parse"
|
||||
} + 1
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
var smaliInstruction = "invoke-static {v$targetRegister}, $descriptor"
|
||||
|
@ -40,11 +40,10 @@ import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||
import app.revanced.util.addFieldAndInstructions
|
||||
import app.revanced.util.alsoResolve
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getTargetIndexReversedOrThrow
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.getWideLiteralInstructionIndex
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
|
||||
import app.revanced.util.resultOrThrow
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
@ -232,9 +231,12 @@ object VideoInformationPatch : BytecodePatch(
|
||||
"videoInformationClass"
|
||||
)
|
||||
|
||||
val literalIndex = getWideLiteralInstructionIndex(45368273)
|
||||
val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(45368273)
|
||||
val walkerIndex =
|
||||
getTargetIndexReversedOrThrow(literalIndex, Opcode.INVOKE_VIRTUAL_RANGE)
|
||||
indexOfFirstInstructionReversedOrThrow(
|
||||
literalIndex,
|
||||
Opcode.INVOKE_VIRTUAL_RANGE
|
||||
)
|
||||
|
||||
videoEndMethod =
|
||||
getWalkerMethod(context, walkerIndex)
|
||||
@ -364,10 +366,11 @@ object VideoInformationPatch : BytecodePatch(
|
||||
OnPlaybackSpeedItemClickFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
speedSelectionInsertMethod = this
|
||||
val speedSelectionValueInstructionIndex = getTargetIndexOrThrow(Opcode.IGET)
|
||||
val speedSelectionValueInstructionIndex =
|
||||
indexOfFirstInstructionOrThrow(Opcode.IGET)
|
||||
|
||||
val setPlaybackSpeedContainerClassFieldIndex =
|
||||
getTargetIndexReversedOrThrow(
|
||||
indexOfFirstInstructionReversedOrThrow(
|
||||
speedSelectionValueInstructionIndex,
|
||||
Opcode.IGET_OBJECT
|
||||
)
|
||||
|
@ -2,9 +2,11 @@ package app.revanced.patches.youtube.video.information.fingerprints
|
||||
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.patches.youtube.utils.PlayerResponseModelUtils.PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.getTargetIndexWithFieldReferenceName
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
/**
|
||||
* This fingerprint is compatible with all versions of YouTube starting from v18.29.38 to supported versions.
|
||||
@ -19,9 +21,11 @@ internal object VideoIdFingerprintShorts : MethodFingerprint(
|
||||
Opcode.MOVE_RESULT_OBJECT
|
||||
),
|
||||
customFingerprint = custom@{ methodDef, _ ->
|
||||
if (methodDef.containsWideLiteralInstructionIndex(45365621))
|
||||
if (methodDef.containsWideLiteralInstructionValue(45365621))
|
||||
return@custom true
|
||||
|
||||
methodDef.getTargetIndexWithFieldReferenceName("reelWatchEndpoint") >= 0
|
||||
methodDef.indexOfFirstInstruction {
|
||||
getReference<FieldReference>()?.name == "reelWatchEndpoint"
|
||||
} >= 0
|
||||
}
|
||||
)
|
@ -33,10 +33,9 @@ import app.revanced.patches.youtube.video.playback.fingerprints.QualitySetterFin
|
||||
import app.revanced.patches.youtube.video.playback.fingerprints.VP9CapabilityFingerprint
|
||||
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.getStringInstructionIndex
|
||||
import app.revanced.util.getTargetIndexOrThrow
|
||||
import app.revanced.util.getWalkerMethod
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||
import app.revanced.util.patch.BaseBytecodePatch
|
||||
import app.revanced.util.resultOrThrow
|
||||
import app.revanced.util.updatePatchStatus
|
||||
@ -112,7 +111,8 @@ object VideoPlaybackPatch : BaseBytecodePatch(
|
||||
// region patch for disable HDR video
|
||||
|
||||
HDRCapabilityFingerprint.resultOrThrow().mutableMethod.apply {
|
||||
val stringIndex = getStringInstructionIndex("av1_profile_main_10_hdr_10_plus_supported")
|
||||
val stringIndex =
|
||||
indexOfFirstStringInstructionOrThrow("av1_profile_main_10_hdr_10_plus_supported")
|
||||
val walkerIndex = indexOfFirstInstructionOrThrow(stringIndex) {
|
||||
val reference = getReference<MethodReference>()
|
||||
reference?.parameterTypes == listOf("I", "Landroid/view/Display;")
|
||||
@ -149,7 +149,8 @@ object VideoPlaybackPatch : BaseBytecodePatch(
|
||||
speedSelectionInsertMethod
|
||||
).forEach {
|
||||
it.apply {
|
||||
val speedSelectionValueInstructionIndex = getTargetIndexOrThrow(Opcode.IGET)
|
||||
val speedSelectionValueInstructionIndex =
|
||||
indexOfFirstInstructionOrThrow(Opcode.IGET)
|
||||
val speedSelectionValueRegister =
|
||||
getInstruction<TwoRegisterInstruction>(speedSelectionValueInstructionIndex).registerA
|
||||
|
||||
@ -227,7 +228,7 @@ object VideoPlaybackPatch : BaseBytecodePatch(
|
||||
|
||||
QualityMenuViewInflateFingerprint.resultOrThrow().let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = getTargetIndexOrThrow(Opcode.CHECK_CAST)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.CHECK_CAST)
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstruction(
|
||||
@ -240,7 +241,7 @@ object VideoPlaybackPatch : BaseBytecodePatch(
|
||||
it.mutableClass.methods.find { method -> method.name == "onItemClick" }
|
||||
|
||||
onItemClickMethod?.apply {
|
||||
val insertIndex = getTargetIndexOrThrow(Opcode.IGET_OBJECT)
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.IGET_OBJECT)
|
||||
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
val jumpIndex = indexOfFirstInstructionOrThrow {
|
||||
@ -291,7 +292,7 @@ object VideoPlaybackPatch : BaseBytecodePatch(
|
||||
|
||||
AV1CodecFingerprint.result?.let {
|
||||
it.mutableMethod.apply {
|
||||
val insertIndex = getStringInstructionIndex("video/av01")
|
||||
val insertIndex = indexOfFirstStringInstructionOrThrow("video/av01")
|
||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -2,7 +2,7 @@ package app.revanced.patches.youtube.video.playback.fingerprints
|
||||
|
||||
import app.revanced.patcher.extensions.or
|
||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||
import app.revanced.util.containsWideLiteralInstructionIndex
|
||||
import app.revanced.util.containsWideLiteralInstructionValue
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal object AV1CodecFingerprint : MethodFingerprint(
|
||||
@ -13,6 +13,6 @@ internal object AV1CodecFingerprint : MethodFingerprint(
|
||||
if (methodDef.returnType == "Ljava/util/List;")
|
||||
return@handler false
|
||||
|
||||
methodDef.containsWideLiteralInstructionIndex(1987076931)
|
||||
methodDef.containsWideLiteralInstructionValue(1987076931)
|
||||
}
|
||||
)
|
||||
|
Reference in New Issue
Block a user