refactor(BytecodeUtils): remove duplicate functions

This commit is contained in:
inotia00 2024-09-17 18:40:11 +09:00
parent 5e4b56cfbe
commit afd19dead4
135 changed files with 1349 additions and 1453 deletions

View File

@ -14,12 +14,14 @@ import app.revanced.patches.music.utils.integrations.Constants.ACCOUNT_CLASS_DES
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithReferenceOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object AccountComponentsPatch : BaseBytecodePatch( object AccountComponentsPatch : BaseBytecodePatch(
@ -43,8 +45,14 @@ object AccountComponentsPatch : BaseBytecodePatch(
MenuEntryFingerprint.resultOrThrow().let { MenuEntryFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val textIndex = getTargetIndexWithMethodReferenceNameOrThrow("setText") val textIndex = indexOfFirstInstructionOrThrow {
val viewIndex = getTargetIndexWithMethodReferenceNameOrThrow("addView") opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setText"
}
val viewIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "addView"
}
val textRegister = getInstruction<FiveRegisterInstruction>(textIndex).registerD val textRegister = getInstruction<FiveRegisterInstruction>(textIndex).registerD
val viewRegister = getInstruction<FiveRegisterInstruction>(viewIndex).registerD val viewRegister = getInstruction<FiveRegisterInstruction>(viewIndex).registerD
@ -64,9 +72,14 @@ object AccountComponentsPatch : BaseBytecodePatch(
AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { result -> AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
val textColorIndex = getTargetIndexWithMethodReferenceNameOrThrow("setTextColor") val textColorIndex = indexOfFirstInstructionOrThrow {
val setVisibilityIndex = opcode == Opcode.INVOKE_VIRTUAL &&
getTargetIndexWithMethodReferenceNameOrThrow(textColorIndex, "setVisibility") getReference<MethodReference>()?.name == "setTextColor"
}
val setVisibilityIndex = indexOfFirstInstructionOrThrow(textColorIndex) {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setVisibility"
}
val textViewInstruction = val textViewInstruction =
getInstruction<FiveRegisterInstruction>(setVisibilityIndex) getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
@ -98,8 +111,12 @@ object AccountComponentsPatch : BaseBytecodePatch(
TermsOfServiceFingerprint.resultOrThrow().let { TermsOfServiceFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = val insertIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithReferenceOrThrow("/PrivacyTosFooter;->setVisibility(I)V") val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_VIRTUAL &&
reference?.name == "setVisibility" &&
reference.definingClass.endsWith("/PrivacyTosFooter;")
}
val visibilityRegister = val visibilityRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerD getInstruction<FiveRegisterInstruction>(insertIndex).registerD

View File

@ -15,10 +15,9 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.LikeDis
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.video.information.VideoInformationPatch import app.revanced.patches.music.video.information.VideoInformationPatch
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithReferenceOrThrow
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -26,6 +25,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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction 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.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import kotlin.math.min import kotlin.math.min
@Suppress("unused") @Suppress("unused")
@ -48,7 +48,10 @@ object ActionBarComponentsPatch : BaseBytecodePatch(
it.mutableMethod.apply { it.mutableMethod.apply {
// hook download button // hook download button
val addViewIndex = getTargetIndexWithMethodReferenceNameOrThrow("addView") val addViewIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "addView"
}
val addViewRegister = val addViewRegister =
getInstruction<FiveRegisterInstruction>(addViewIndex).registerD getInstruction<FiveRegisterInstruction>(addViewIndex).registerD
@ -83,10 +86,15 @@ object ActionBarComponentsPatch : BaseBytecodePatch(
removeInstruction(replaceIndex) removeInstruction(replaceIndex)
// hide action button // hide action button
val hasNextIndex = getTargetIndexWithMethodReferenceNameOrThrow("hasNext") val hasNextIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_INTERFACE &&
getReference<MethodReference>()?.name == "hasNext"
}
val freeRegister = min(implementation!!.registerCount - parameters.size - 2, 15) val freeRegister = min(implementation!!.registerCount - parameters.size - 2, 15)
val spannedIndex = getTargetIndexWithReferenceOrThrow(")Landroid/text/Spanned;") val spannedIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.returnType == "Landroid/text/Spanned;"
}
val spannedRegister = val spannedRegister =
getInstruction<FiveRegisterInstruction>(spannedIndex).registerC getInstruction<FiveRegisterInstruction>(spannedIndex).registerC
val spannedReference = getInstruction<ReferenceInstruction>(spannedIndex).reference val spannedReference = getInstruction<ReferenceInstruction>(spannedIndex).reference
@ -124,7 +132,8 @@ object ActionBarComponentsPatch : BaseBytecodePatch(
LikeDislikeContainerFingerprint.resultOrThrow().let { LikeDislikeContainerFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = getWideLiteralInstructionIndex(LikeDislikeContainer) + 2 val insertIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(LikeDislikeContainer) + 2
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstruction( addInstruction(

View File

@ -22,19 +22,21 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ButtonContainer import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ButtonContainer
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.FloatingLayout import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.FloatingLayout
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.InterstitialsContainer
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PrivacyTosFooter
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithReferenceOrThrow
import app.revanced.util.getWalkerMethod 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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction 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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
@Suppress("unused") @Suppress("unused")
object AdsPatch : BaseBytecodePatch( object AdsPatch : BaseBytecodePatch(
@ -87,7 +89,7 @@ object AdsPatch : BaseBytecodePatch(
FloatingLayoutFingerprint.resultOrThrow().let { FloatingLayoutFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(FloatingLayout) + 2 val targetIndex = indexOfFirstWideLiteralInstructionValueOrThrow(FloatingLayout) + 2
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(
@ -103,7 +105,8 @@ object AdsPatch : BaseBytecodePatch(
NotifierShelfFingerprint.resultOrThrow().let { NotifierShelfFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val linearLayoutIndex = getWideLiteralInstructionIndex(ButtonContainer) + 3 val linearLayoutIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(ButtonContainer) + 3
val linearLayoutRegister = val linearLayoutRegister =
getInstruction<OneRegisterInstruction>(linearLayoutIndex).registerA getInstruction<OneRegisterInstruction>(linearLayoutIndex).registerA
@ -135,16 +138,20 @@ object AdsPatch : BaseBytecodePatch(
AccountMenuFooterFingerprint.resultOrThrow().let { AccountMenuFooterFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = val constIndex =
getWideLiteralInstructionIndex(SharedResourceIdPatch.PrivacyTosFooter) indexOfFirstWideLiteralInstructionValueOrThrow(PrivacyTosFooter)
val walkerIndex = getTargetIndexOrThrow(constIndex + 2, Opcode.INVOKE_VIRTUAL) val walkerIndex =
val viewIndex = getTargetIndexOrThrow(constIndex, Opcode.IGET_OBJECT) indexOfFirstInstructionOrThrow(constIndex + 2, Opcode.INVOKE_VIRTUAL)
val viewIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.IGET_OBJECT)
val viewReference = val viewReference =
getInstruction<ReferenceInstruction>(viewIndex).reference.toString() getInstruction<ReferenceInstruction>(viewIndex).reference.toString()
val walkerMethod = getWalkerMethod(context, walkerIndex) val walkerMethod = getWalkerMethod(context, walkerIndex)
walkerMethod.apply { walkerMethod.apply {
val insertIndex = getTargetIndexWithReferenceOrThrow(viewReference) val insertIndex = indexOfFirstInstructionOrThrow {
val nullCheckIndex = getTargetIndexOrThrow(insertIndex - 1, Opcode.IF_NEZ) getReference<FieldReference>()?.toString() == viewReference
}
val nullCheckIndex =
indexOfFirstInstructionOrThrow(insertIndex - 1, Opcode.IF_NEZ)
val nullCheckRegister = val nullCheckRegister =
getInstruction<OneRegisterInstruction>(nullCheckIndex).registerA getInstruction<OneRegisterInstruction>(nullCheckIndex).registerA

View File

@ -4,14 +4,14 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ButtonContainer import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ButtonContainer
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicNotifierShelf import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicNotifierShelf
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object NotifierShelfFingerprint : MethodFingerprint( internal object NotifierShelfFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(MusicNotifierShelf) methodDef.containsWideLiteralInstructionValue(MusicNotifierShelf)
&& methodDef.containsWideLiteralInstructionIndex(ButtonContainer) && methodDef.containsWideLiteralInstructionValue(ButtonContainer)
} }
) )

View File

@ -2,7 +2,7 @@ package app.revanced.patches.music.ads.general.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
internal object ShowDialogCommandFingerprint : MethodFingerprint( internal object ShowDialogCommandFingerprint : MethodFingerprint(
@ -16,7 +16,7 @@ internal object ShowDialogCommandFingerprint : MethodFingerprint(
// 6.26 and earlier has a different first parameter. // 6.26 and earlier has a different first parameter.
// Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures. // Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures.
customFingerprint = custom@{ methodDef, _ -> customFingerprint = custom@{ methodDef, _ ->
if (!methodDef.containsWideLiteralInstructionIndex(SlidingDialogAnimation)) { if (!methodDef.containsWideLiteralInstructionValue(SlidingDialogAnimation)) {
return@custom false return@custom false
} }
// 6.26 and earlier parameters are: "L", "L" // 6.26 and earlier parameters are: "L", "L"

View File

@ -25,12 +25,11 @@ import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch
import app.revanced.patches.music.video.information.VideoInformationPatch import app.revanced.patches.music.video.information.VideoInformationPatch
import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -88,7 +87,7 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
// region patch for enable trim silence // region patch for enable trim silence
TrimSilenceConfigFingerprint.result?.let { TrimSilenceConfigFingerprint.result?.let {
TrimSilenceConfigFingerprint.literalInstructionBooleanHook( TrimSilenceConfigFingerprint.injectLiteralInstructionBooleanCall(
45619123, 45619123,
"$FLYOUT_CLASS_DESCRIPTOR->enableTrimSilence(Z)Z" "$FLYOUT_CLASS_DESCRIPTOR->enableTrimSilence(Z)Z"
) )
@ -96,9 +95,9 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
TrimSilenceSwitchFingerprint.resultOrThrow().let { TrimSilenceSwitchFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = val constIndex =
getWideLiteralInstructionIndex(SharedResourceIdPatch.TrimSilenceSwitch) indexOfFirstWideLiteralInstructionValueOrThrow(SharedResourceIdPatch.TrimSilenceSwitch)
val onCheckedChangedListenerIndex = val onCheckedChangedListenerIndex =
getTargetIndexOrThrow(constIndex, Opcode.INVOKE_DIRECT) indexOfFirstInstructionOrThrow(constIndex, Opcode.INVOKE_DIRECT)
val onCheckedChangedListenerReference = val onCheckedChangedListenerReference =
getInstruction<ReferenceInstruction>(onCheckedChangedListenerIndex).reference getInstruction<ReferenceInstruction>(onCheckedChangedListenerIndex).reference
val onCheckedChangedListenerDefiningClass = val onCheckedChangedListenerDefiningClass =
@ -118,7 +117,7 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
&& reference.parameterTypes[0] == "Z" && reference.parameterTypes[0] == "Z"
} }
getWalkerMethod(context, walkerIndex).apply { getWalkerMethod(context, walkerIndex).apply {
val insertIndex = getTargetIndexOrThrow(Opcode.MOVE_RESULT) val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT)
val insertRegister = val insertRegister =
getInstruction<OneRegisterInstruction>(insertIndex).registerA getInstruction<OneRegisterInstruction>(insertIndex).registerA
@ -142,7 +141,7 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
MenuItemFingerprint.resultOrThrow().let { MenuItemFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val freeIndex = getTargetIndexOrThrow(Opcode.OR_INT_LIT16) val freeIndex = indexOfFirstInstructionOrThrow(Opcode.OR_INT_LIT16)
val textViewIndex = it.scanResult.patternScanResult!!.startIndex val textViewIndex = it.scanResult.patternScanResult!!.startIndex
val imageViewIndex = it.scanResult.patternScanResult!!.endIndex val imageViewIndex = it.scanResult.patternScanResult!!.endIndex
@ -175,8 +174,10 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
TouchOutsideFingerprint.resultOrThrow().let { TouchOutsideFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val setOnClickListenerIndex = val setOnClickListenerIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithMethodReferenceNameOrThrow("setOnClickListener") opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setOnClickListener"
}
val setOnClickListenerRegister = val setOnClickListenerRegister =
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
@ -189,8 +190,10 @@ object FlyoutMenuComponentsPatch : BaseBytecodePatch(
EndButtonsContainerFingerprint.resultOrThrow().let { EndButtonsContainerFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val startIndex = getWideLiteralInstructionIndex(EndButtonsContainer) val startIndex =
val targetIndex = getTargetIndexOrThrow(startIndex, Opcode.MOVE_RESULT_OBJECT) indexOfFirstWideLiteralInstructionValueOrThrow(EndButtonsContainer)
val targetIndex =
indexOfFirstInstructionOrThrow(startIndex, Opcode.MOVE_RESULT_OBJECT)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(

View File

@ -27,15 +27,17 @@ import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKA
import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.music.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTasteBuilderShelf
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerOverlayChip
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopBarMenuItemImageView import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopBarMenuItemImageView
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.patches.shared.settingmenu.SettingsMenuPatch import app.revanced.patches.shared.settingmenu.SettingsMenuPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.alsoResolve
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -99,7 +101,7 @@ object LayoutComponentsPatch : BaseBytecodePatch(
PlayerOverlayChipFingerprint.resultOrThrow().let { PlayerOverlayChipFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = val targetIndex =
getWideLiteralInstructionIndex(SharedResourceIdPatch.PlayerOverlayChip) + 2 indexOfFirstWideLiteralInstructionValueOrThrow(PlayerOverlayChip) + 2
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(
@ -176,8 +178,10 @@ object LayoutComponentsPatch : BaseBytecodePatch(
if (SettingsPatch.upward0642) { if (SettingsPatch.upward0642) {
TopBarMenuItemImageViewFingerprint.resultOrThrow().mutableMethod.apply { TopBarMenuItemImageViewFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(TopBarMenuItemImageView) val constIndex =
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT) indexOfFirstWideLiteralInstructionValueOrThrow(TopBarMenuItemImageView)
val targetIndex =
indexOfFirstInstructionOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(
@ -193,7 +197,7 @@ object LayoutComponentsPatch : BaseBytecodePatch(
// region patch for hide sound search button // region patch for hide sound search button
SoundSearchFingerprint.result?.let { SoundSearchFingerprint.result?.let {
SoundSearchFingerprint.literalInstructionBooleanHook( SoundSearchFingerprint.injectLiteralInstructionBooleanCall(
45625491, 45625491,
"$GENERAL_CLASS_DESCRIPTOR->hideSoundSearchButton(Z)Z" "$GENERAL_CLASS_DESCRIPTOR->hideSoundSearchButton(Z)Z"
) )
@ -227,8 +231,9 @@ object LayoutComponentsPatch : BaseBytecodePatch(
parentResult.mutableMethod.apply { parentResult.mutableMethod.apply {
val constIndex = val constIndex =
getWideLiteralInstructionIndex(SharedResourceIdPatch.MusicTasteBuilderShelf) indexOfFirstWideLiteralInstructionValueOrThrow(MusicTasteBuilderShelf)
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT) val targetIndex =
indexOfFirstInstructionOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(
@ -263,14 +268,11 @@ object LayoutComponentsPatch : BaseBytecodePatch(
// region patch for hide voice search button // region patch for hide voice search button
SearchBarFingerprint.resolve( SearchBarFingerprint.alsoResolve(
context, context, SearchBarParentFingerprint
SearchBarParentFingerprint.resultOrThrow().classDef ).let {
)
SearchBarFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val setVisibilityIndex = val setVisibilityIndex = SearchBarFingerprint.indexOfVisibilityInstruction(this)
getTargetIndexWithMethodReferenceNameOrThrow("setVisibility")
val setVisibilityInstruction = val setVisibilityInstruction =
getInstruction<FiveRegisterInstruction>(setVisibilityIndex) getInstruction<FiveRegisterInstruction>(setVisibilityIndex)

View File

@ -3,7 +3,7 @@ package app.revanced.patches.music.general.components.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.HistoryMenuItem import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.HistoryMenuItem
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -16,7 +16,7 @@ internal object HistoryMenuItemFingerprint : MethodFingerprint(
Opcode.RETURN_VOID Opcode.RETURN_VOID
), ),
customFingerprint = { methodDef, classDef -> customFingerprint = { methodDef, classDef ->
methodDef.containsWideLiteralInstructionIndex(HistoryMenuItem) methodDef.containsWideLiteralInstructionValue(HistoryMenuItem)
&& classDef.methods.count() == 5 && classDef.methods.count() == 5
} }
) )

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.HistoryMenuItem import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.HistoryMenuItem
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.OfflineSettingsMenuItem import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.OfflineSettingsMenuItem
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -17,7 +17,7 @@ internal object HistoryMenuItemOfflineTabFingerprint : MethodFingerprint(
Opcode.RETURN_VOID Opcode.RETURN_VOID
), ),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(HistoryMenuItem) methodDef.containsWideLiteralInstructionValue(HistoryMenuItem)
&& methodDef.containsWideLiteralInstructionIndex(OfflineSettingsMenuItem) && methodDef.containsWideLiteralInstructionValue(OfflineSettingsMenuItem)
} }
) )

View File

@ -1,8 +1,22 @@
package app.revanced.patches.music.general.components.fingerprints package app.revanced.patches.music.general.components.fingerprints
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.general.components.fingerprints.SearchBarFingerprint.indexOfVisibilityInstruction
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
object SearchBarFingerprint : MethodReferenceNameFingerprint( object SearchBarFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
reference = { "setVisibility" } customFingerprint = { methodDef, _ ->
) indexOfVisibilityInstruction(methodDef) >= 0
}
) {
fun indexOfVisibilityInstruction(methodDef: Method) =
methodDef.indexOfFirstInstructionReversed {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setVisibility"
}
}

View File

@ -8,8 +8,8 @@ import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKA
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.getStringInstructionIndex import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.getTargetIndexReversedOrThrow import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -27,8 +27,9 @@ object OldStyleLibraryShelfPatch : BaseBytecodePatch(
BrowseIdFingerprint.resultOrThrow().let { BrowseIdFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val stringIndex = getStringInstructionIndex("FEmusic_offline") val stringIndex = indexOfFirstStringInstructionOrThrow("FEmusic_offline")
val targetIndex = getTargetIndexReversedOrThrow(stringIndex, Opcode.IGET_OBJECT) val targetIndex =
indexOfFirstInstructionReversedOrThrow(stringIndex, Opcode.IGET_OBJECT)
val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
addInstructions( addInstructions(

View File

@ -11,11 +11,11 @@ import app.revanced.patches.music.utils.fingerprints.PendingIntentReceiverFinger
import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.getStringInstructionIndex import app.revanced.util.getReference
import app.revanced.util.getTargetIndexReversedOrThrow
import app.revanced.util.getTargetIndexWithReferenceOrThrow
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow 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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -41,13 +41,14 @@ object DislikeRedirectionPatch : BaseBytecodePatch(
PendingIntentReceiverFingerprint.resultOrThrow().let { PendingIntentReceiverFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val startIndex = getStringInstructionIndex("YTM Dislike") val startIndex = indexOfFirstStringInstructionOrThrow("YTM Dislike")
val onClickRelayIndex = val onClickRelayIndex =
getTargetIndexReversedOrThrow(startIndex, Opcode.INVOKE_VIRTUAL) indexOfFirstInstructionReversedOrThrow(startIndex, Opcode.INVOKE_VIRTUAL)
val onClickRelayMethod = getWalkerMethod(context, onClickRelayIndex) val onClickRelayMethod = getWalkerMethod(context, onClickRelayIndex)
onClickRelayMethod.apply { onClickRelayMethod.apply {
val onClickMethodIndex = getTargetIndexReversedOrThrow(Opcode.INVOKE_DIRECT) val onClickMethodIndex =
indexOfFirstInstructionReversedOrThrow(Opcode.INVOKE_DIRECT)
val onClickMethod = getWalkerMethod(context, onClickMethodIndex) val onClickMethod = getWalkerMethod(context, onClickMethodIndex)
onClickMethod.apply { onClickMethod.apply {
@ -70,7 +71,9 @@ object DislikeRedirectionPatch : BaseBytecodePatch(
DislikeButtonOnClickListenerFingerprint.resultOrThrow().let { DislikeButtonOnClickListenerFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val onClickIndex = getTargetIndexWithReferenceOrThrow(onClickReference.toString()) val onClickIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.toString() == onClickReference.toString()
}
injectCall(onClickIndex) injectCall(onClickIndex)
} }
} }
@ -84,7 +87,7 @@ object DislikeRedirectionPatch : BaseBytecodePatch(
} }
private fun MutableMethod.injectCall(onClickIndex: Int) { private fun MutableMethod.injectCall(onClickIndex: Int) {
val targetIndex = getTargetIndexReversedOrThrow(onClickIndex, Opcode.IF_EQZ) val targetIndex = indexOfFirstInstructionReversedOrThrow(onClickIndex, Opcode.IF_EQZ)
val insertRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructionsWithLabels( addInstructionsWithLabels(

View File

@ -2,7 +2,7 @@ package app.revanced.patches.music.general.redirection.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object DislikeButtonOnClickListenerFingerprint : MethodFingerprint( internal object DislikeButtonOnClickListenerFingerprint : MethodFingerprint(
@ -10,7 +10,7 @@ internal object DislikeButtonOnClickListenerFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/view/View;"), parameters = listOf("Landroid/view/View;"),
customFingerprint = handler@{ methodDef, _ -> customFingerprint = handler@{ methodDef, _ ->
if (!methodDef.containsWideLiteralInstructionIndex(53465)) if (!methodDef.containsWideLiteralInstructionValue(53465))
return@handler false return@handler false
methodDef.name == "onClick" methodDef.name == "onClick"

View File

@ -10,15 +10,16 @@ import app.revanced.patches.music.misc.backgroundplayback.fingerprints.KidsBackg
import app.revanced.patches.music.misc.backgroundplayback.fingerprints.MusicBrowserServiceFingerprint import app.revanced.patches.music.misc.backgroundplayback.fingerprints.MusicBrowserServiceFingerprint
import app.revanced.patches.music.misc.backgroundplayback.fingerprints.PodCastConfigFingerprint import app.revanced.patches.music.misc.backgroundplayback.fingerprints.PodCastConfigFingerprint
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.util.getStartsWithStringInstructionIndex import app.revanced.util.getReference
import app.revanced.util.getStringInstructionIndex
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction 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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object BackgroundPlaybackPatch : BaseBytecodePatch( object BackgroundPlaybackPatch : BaseBytecodePatch(
@ -51,26 +52,20 @@ object BackgroundPlaybackPatch : BaseBytecodePatch(
// don't play music video // don't play music video
MusicBrowserServiceFingerprint.resultOrThrow().let { MusicBrowserServiceFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = val stringIndex = MusicBrowserServiceFingerprint.indexOfMBSInstruction(this)
getStartsWithStringInstructionIndex("MBS: Return empty root for client: %s") val targetIndex = indexOfFirstInstructionReversedOrThrow(stringIndex) {
val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_VIRTUAL &&
reference?.returnType == "Z" &&
reference.parameterTypes.size == 0
}
for (index in targetIndex downTo 0) { getWalkerMethod(context, targetIndex).addInstructions(
if (getInstruction(index).opcode != Opcode.INVOKE_VIRTUAL) continue
val targetReference = getInstruction<ReferenceInstruction>(index).reference
if (!targetReference.toString().endsWith("()Z")) continue
val walkerMethod = getWalkerMethod(context, index)
walkerMethod.addInstructions(
0, """ 0, """
const/4 v0, 0x1 const/4 v0, 0x1
return v0 return v0
""" """
) )
break
}
} }
} }
@ -97,7 +92,8 @@ object BackgroundPlaybackPatch : BaseBytecodePatch(
} }
dataSavingSettingsFragmentFingerprintResult!!.mutableMethod.apply { dataSavingSettingsFragmentFingerprintResult!!.mutableMethod.apply {
val insertIndex = getStringInstructionIndex("pref_key_dont_play_nma_video") + 4 val insertIndex =
indexOfFirstStringInstructionOrThrow("pref_key_dont_play_nma_video") + 4
val targetRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD val targetRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
addInstruction( addInstruction(

View File

@ -2,8 +2,13 @@ package app.revanced.patches.music.misc.backgroundplayback.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.getStartsWithStringInstructionIndex import app.revanced.patches.music.misc.backgroundplayback.fingerprints.MusicBrowserServiceFingerprint.indexOfMBSInstruction
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.StringReference
internal object MusicBrowserServiceFingerprint : MethodFingerprint( internal object MusicBrowserServiceFingerprint : MethodFingerprint(
returnType = "L", returnType = "L",
@ -13,6 +18,12 @@ internal object MusicBrowserServiceFingerprint : MethodFingerprint(
if (!methodDef.definingClass.endsWith("/MusicBrowserService;")) if (!methodDef.definingClass.endsWith("/MusicBrowserService;"))
return@custom false return@custom false
methodDef.getStartsWithStringInstructionIndex("MBS: Return empty root for client: %s") > 0 indexOfMBSInstruction(methodDef) >= 0
}
) {
fun indexOfMBSInstruction(methodDef: Method) =
methodDef.indexOfFirstInstruction {
opcode == Opcode.CONST_STRING &&
getReference<StringReference>()?.string?.startsWith("MBS: Return empty root for client: %s") == true
}
} }
)

View File

@ -12,8 +12,8 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.BottomS
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -40,8 +40,8 @@ object ShareSheetPatch : BaseBytecodePatch(
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
BottomSheetRecyclerViewFingerprint.resultOrThrow().mutableMethod.apply { BottomSheetRecyclerViewFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(BottomSheetRecyclerView) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(BottomSheetRecyclerView)
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST) val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(

View File

@ -8,7 +8,7 @@ import app.revanced.patches.music.misc.splash.fingerprints.CairoSplashAnimationC
import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH import app.revanced.patches.music.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.injectLiteralInstructionBooleanCall
@Patch( @Patch(
name = "Disable Cairo splash animation", name = "Disable Cairo splash animation",
@ -31,7 +31,7 @@ object CairoSplashAnimationPatch : BytecodePatch(
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
CairoSplashAnimationConfigFingerprint.result?.let { CairoSplashAnimationConfigFingerprint.result?.let {
CairoSplashAnimationConfigFingerprint.literalInstructionBooleanHook( CairoSplashAnimationConfigFingerprint.injectLiteralInstructionBooleanCall(
45635386, 45635386,
"$MISC_PATH/CairoSplashAnimationPatch;->disableCairoSplashAnimation(Z)Z" "$MISC_PATH/CairoSplashAnimationPatch;->disableCairoSplashAnimation(Z)Z"
) )

View File

@ -11,13 +11,12 @@ import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKA
import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.integrations.Constants.NAVIGATION_CLASS_DESCRIPTOR
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.Text1
import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.CategoryType
import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.getTargetIndexOrThrow
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -50,7 +49,7 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
* Enable black navigation bar * Enable black navigation bar
*/ */
TabLayoutFingerprint.resultOrThrow().mutableMethod.apply { TabLayoutFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(ColorGrey) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(ColorGrey)
val insertIndex = indexOfFirstInstructionOrThrow(constIndex) { val insertIndex = indexOfFirstInstructionOrThrow(constIndex) {
opcode == Opcode.INVOKE_VIRTUAL opcode == Opcode.INVOKE_VIRTUAL
&& getReference<MethodReference>()?.name == "setBackgroundColor" && getReference<MethodReference>()?.name == "setBackgroundColor"
@ -70,8 +69,9 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
*/ */
TabLayoutTextFingerprint.resultOrThrow().let { TabLayoutTextFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(SharedResourceIdPatch.Text1) val constIndex =
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST) indexOfFirstWideLiteralInstructionValueOrThrow(Text1)
val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
val targetParameter = getInstruction<ReferenceInstruction>(targetIndex).reference val targetParameter = getInstruction<ReferenceInstruction>(targetIndex).reference
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
@ -105,9 +105,12 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
it.mutableMethod.apply { it.mutableMethod.apply {
val enumIndex = it.scanResult.patternScanResult!!.startIndex + 3 val enumIndex = it.scanResult.patternScanResult!!.startIndex + 3
val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA val enumRegister = getInstruction<OneRegisterInstruction>(enumIndex).registerA
val insertEnumIndex = getTargetIndexOrThrow(Opcode.AND_INT_LIT8) - 2 val insertEnumIndex = indexOfFirstInstructionOrThrow(Opcode.AND_INT_LIT8) - 2
val pivotTabIndex = getTargetIndexWithMethodReferenceNameOrThrow("getVisibility") val pivotTabIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "getVisibility"
}
val pivotTabRegister = getInstruction<Instruction35c>(pivotTabIndex).registerC val pivotTabRegister = getInstruction<Instruction35c>(pivotTabIndex).registerC
addInstruction( addInstruction(

View File

@ -60,16 +60,13 @@ import app.revanced.patches.music.utils.videotype.VideoTypeHookPatch
import app.revanced.patches.shared.litho.LithoFilterPatch import app.revanced.patches.shared.litho.LithoFilterPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.getStringInstructionIndex
import app.revanced.util.getTargetIndex
import app.revanced.util.getTargetIndexOrThrow
import app.revanced.util.getTargetIndexReversedOrThrow
import app.revanced.util.getTargetIndexWithFieldReferenceTypeOrThrow
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.literalInstructionViewHook import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.injectLiteralInstructionViewCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import app.revanced.util.transformFields import app.revanced.util.transformFields
@ -145,8 +142,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
PlayerViewPager to "disablePlayerGesture" PlayerViewPager to "disablePlayerGesture"
).forEach { (literal, methodName) -> ).forEach { (literal, methodName) ->
val viewPagerReference = playerViewPagerConstructorMethod.let { val viewPagerReference = playerViewPagerConstructorMethod.let {
val constIndex = it.getWideLiteralInstructionIndex(literal) val constIndex = it.indexOfFirstWideLiteralInstructionValueOrThrow(literal)
val targetIndex = it.getTargetIndexOrThrow(constIndex, Opcode.IPUT_OBJECT) val targetIndex = it.indexOfFirstInstructionOrThrow(constIndex, Opcode.IPUT_OBJECT)
it.getInstruction<ReferenceInstruction>(targetIndex).reference.toString() it.getInstruction<ReferenceInstruction>(targetIndex).reference.toString()
} }
@ -156,7 +153,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
&& getReference<FieldReference>()?.toString() == viewPagerReference && getReference<FieldReference>()?.toString() == viewPagerReference
} }
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
val jumpIndex = getTargetIndex(insertIndex, Opcode.INVOKE_VIRTUAL) + 1 val jumpIndex =
indexOfFirstInstructionOrThrow(insertIndex, Opcode.INVOKE_VIRTUAL) + 1
addInstructionsWithLabels( addInstructionsWithLabels(
insertIndex, """ insertIndex, """
@ -198,8 +196,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
val relativeIndex = it.scanResult.patternScanResult!!.endIndex + 1 val relativeIndex = it.scanResult.patternScanResult!!.endIndex + 1
val invokeVirtualIndex = val invokeVirtualIndex =
getTargetIndexOrThrow(relativeIndex, Opcode.INVOKE_VIRTUAL) indexOfFirstInstructionOrThrow(relativeIndex, Opcode.INVOKE_VIRTUAL)
val iGetIndex = getTargetIndexOrThrow(relativeIndex, Opcode.IGET) val iGetIndex = indexOfFirstInstructionOrThrow(relativeIndex, Opcode.IGET)
colorMathPlayerInvokeVirtualReference = colorMathPlayerInvokeVirtualReference =
getInstruction<ReferenceInstruction>(invokeVirtualIndex).reference getInstruction<ReferenceInstruction>(invokeVirtualIndex).reference
@ -207,11 +205,11 @@ object PlayerComponentsPatch : BaseBytecodePatch(
getInstruction<ReferenceInstruction>(iGetIndex).reference getInstruction<ReferenceInstruction>(iGetIndex).reference
// black player background // black player background
val invokeDirectIndex = getTargetIndexOrThrow(Opcode.INVOKE_DIRECT) val invokeDirectIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT)
val targetMethod = getWalkerMethod(context, invokeDirectIndex) val targetMethod = getWalkerMethod(context, invokeDirectIndex)
targetMethod.apply { targetMethod.apply {
val insertIndex = getTargetIndexOrThrow(0, Opcode.IF_NE) val insertIndex = indexOfFirstInstructionOrThrow(Opcode.IF_NE)
addInstructions( addInstructions(
insertIndex, """ insertIndex, """
@ -225,8 +223,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
} }
parentResult.mutableMethod.apply { parentResult.mutableMethod.apply {
val colorGreyIndex = getWideLiteralInstructionIndex(ColorGrey) val colorGreyIndex = indexOfFirstWideLiteralInstructionValueOrThrow(ColorGrey)
val iPutIndex = getTargetIndexOrThrow(colorGreyIndex, Opcode.IPUT) val iPutIndex = indexOfFirstInstructionOrThrow(colorGreyIndex, Opcode.IPUT)
colorMathPlayerIPutReference = colorMathPlayerIPutReference =
getInstruction<ReferenceInstruction>(iPutIndex).reference getInstruction<ReferenceInstruction>(iPutIndex).reference
@ -240,7 +238,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
mutableMethod.apply { mutableMethod.apply {
val freeRegister = implementation!!.registerCount - parameters.size - 3 val freeRegister = implementation!!.registerCount - parameters.size - 3
val invokeDirectIndex = getTargetIndexReversedOrThrow(Opcode.INVOKE_DIRECT) val invokeDirectIndex =
indexOfFirstInstructionReversedOrThrow(Opcode.INVOKE_DIRECT)
val invokeDirectReference = val invokeDirectReference =
getInstruction<ReferenceInstruction>(invokeDirectIndex).reference getInstruction<ReferenceInstruction>(invokeDirectIndex).reference
@ -401,9 +400,9 @@ object PlayerComponentsPatch : BaseBytecodePatch(
reversed: Boolean reversed: Boolean
): Reference { ): Reference {
val targetIndex = if (reversed) val targetIndex = if (reversed)
getTargetIndexReversedOrThrow(swipeToDismissWidgetIndex, opcode) indexOfFirstInstructionReversedOrThrow(swipeToDismissWidgetIndex, opcode)
else else
getTargetIndexOrThrow(swipeToDismissWidgetIndex, opcode) indexOfFirstInstructionOrThrow(swipeToDismissWidgetIndex, opcode)
return getInstruction<ReferenceInstruction>(targetIndex).reference return getInstruction<ReferenceInstruction>(targetIndex).reference
} }
@ -411,7 +410,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
if (!SettingsPatch.upward0642) { if (!SettingsPatch.upward0642) {
SwipeToCloseFingerprint.resultOrThrow().let { SwipeToCloseFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = implementation!!.instructions.size - 1 val insertIndex = implementation!!.instructions.lastIndex
val targetRegister = val targetRegister =
getInstruction<OneRegisterInstruction>(insertIndex).registerA getInstruction<OneRegisterInstruction>(insertIndex).registerA
@ -430,8 +429,9 @@ object PlayerComponentsPatch : BaseBytecodePatch(
InteractionLoggingEnumFingerprint.resultOrThrow().let { InteractionLoggingEnumFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val stringIndex = val stringIndex =
getStringInstructionIndex("INTERACTION_LOGGING_GESTURE_TYPE_SWIPE") indexOfFirstStringInstructionOrThrow("INTERACTION_LOGGING_GESTURE_TYPE_SWIPE")
val sPutObjectIndex = getTargetIndexOrThrow(stringIndex, Opcode.SPUT_OBJECT) val sPutObjectIndex =
indexOfFirstInstructionOrThrow(stringIndex, Opcode.SPUT_OBJECT)
swipeToDismissSGetObjectReference = swipeToDismissSGetObjectReference =
getInstruction<ReferenceInstruction>(sPutObjectIndex).reference getInstruction<ReferenceInstruction>(sPutObjectIndex).reference
@ -440,7 +440,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
MusicActivityWidgetFingerprint.resultOrThrow().let { MusicActivityWidgetFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
swipeToDismissWidgetIndex = getWideLiteralInstructionIndex(79500) swipeToDismissWidgetIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(79500)
swipeToDismissIGetObjectReference = swipeToDismissIGetObjectReference =
getSwipeToDismissReference(Opcode.IGET_OBJECT, true) getSwipeToDismissReference(Opcode.IGET_OBJECT, true)
@ -468,8 +469,9 @@ object PlayerComponentsPatch : BaseBytecodePatch(
it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex) it.getWalkerMethod(context, it.scanResult.patternScanResult!!.startIndex)
dismissBehaviorMethod.apply { dismissBehaviorMethod.apply {
val insertIndex = val insertIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithFieldReferenceTypeOrThrow("Ljava/util/concurrent/atomic/AtomicBoolean;") getReference<FieldReference>()?.type == "Ljava/util/concurrent/atomic/AtomicBoolean;"
}
val primaryRegister = val primaryRegister =
getInstruction<TwoRegisterInstruction>(insertIndex).registerB getInstruction<TwoRegisterInstruction>(insertIndex).registerB
val secondaryRegister = primaryRegister + 1 val secondaryRegister = primaryRegister + 1
@ -592,7 +594,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
SwitchToggleColorFingerprint.resultOrThrow().let { SwitchToggleColorFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val invokeDirectIndex = getTargetIndexOrThrow(Opcode.INVOKE_DIRECT) val invokeDirectIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT)
val walkerMethod = getWalkerMethod(context, invokeDirectIndex) val walkerMethod = getWalkerMethod(context, invokeDirectIndex)
walkerMethod.addInstructions( walkerMethod.addInstructions(
@ -624,8 +626,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
// region patch for hide audio video switch toggle // region patch for hide audio video switch toggle
AudioVideoSwitchToggleFingerprint.resultOrThrow().mutableMethod.apply { AudioVideoSwitchToggleFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(AudioVideoSwitchToggle) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(AudioVideoSwitchToggle)
val viewIndex = getTargetIndexOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT) val viewIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT)
val viewRegister = getInstruction<OneRegisterInstruction>(viewIndex).registerA val viewRegister = getInstruction<OneRegisterInstruction>(viewIndex).registerA
addInstruction( addInstruction(
@ -667,7 +669,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
DarkBackground, DarkBackground,
TapBloomView TapBloomView
).forEach { literal -> ).forEach { literal ->
QuickSeekOverlayFingerprint.literalInstructionViewHook( QuickSeekOverlayFingerprint.injectLiteralInstructionViewCall(
literal, literal,
smaliInstruction smaliInstruction
) )
@ -742,9 +744,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
it.mutableMethod.apply { it.mutableMethod.apply {
rememberShuffleStateObjectClass = definingClass rememberShuffleStateObjectClass = definingClass
val constIndex = getWideLiteralInstructionIndex(45468) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(45468)
val iGetObjectIndex = getTargetIndexOrThrow(constIndex, Opcode.IGET_OBJECT) val iGetObjectIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.IGET_OBJECT)
val checkCastIndex = getTargetIndexOrThrow(iGetObjectIndex, Opcode.CHECK_CAST) val checkCastIndex =
indexOfFirstInstructionOrThrow(iGetObjectIndex, Opcode.CHECK_CAST)
val ordinalIndex = indexOfOrdinalInstruction(this) val ordinalIndex = indexOfOrdinalInstruction(this)
val imageViewIndex = indexOfImageViewInstruction(this) val imageViewIndex = indexOfImageViewInstruction(this)
@ -888,7 +891,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
// region patch for restore old comments popup panels // region patch for restore old comments popup panels
OldEngagementPanelFingerprint.result?.let { OldEngagementPanelFingerprint.result?.let {
OldEngagementPanelFingerprint.literalInstructionBooleanHook( OldEngagementPanelFingerprint.injectLiteralInstructionBooleanCall(
45427672, 45427672,
"$PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z" "$PLAYER_CLASS_DESCRIPTOR->restoreOldCommentsPopUpPanels(Z)Z"
) )
@ -905,7 +908,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
// region patch for restore old player background // region patch for restore old player background
OldPlayerBackgroundFingerprint.result?.let { OldPlayerBackgroundFingerprint.result?.let {
OldPlayerBackgroundFingerprint.literalInstructionBooleanHook( OldPlayerBackgroundFingerprint.injectLiteralInstructionBooleanCall(
45415319, 45415319,
"$PLAYER_CLASS_DESCRIPTOR->restoreOldPlayerBackground(Z)Z" "$PLAYER_CLASS_DESCRIPTOR->restoreOldPlayerBackground(Z)Z"
) )
@ -922,7 +925,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
// region patch for restore old player layout // region patch for restore old player layout
OldPlayerLayoutFingerprint.result?.let { OldPlayerLayoutFingerprint.result?.let {
OldPlayerLayoutFingerprint.literalInstructionBooleanHook( OldPlayerLayoutFingerprint.injectLiteralInstructionBooleanCall(
45399578, 45399578,
"$PLAYER_CLASS_DESCRIPTOR->restoreOldPlayerLayout(Z)Z" "$PLAYER_CLASS_DESCRIPTOR->restoreOldPlayerLayout(Z)Z"
) )
@ -943,11 +946,14 @@ object PlayerComponentsPatch : BaseBytecodePatch(
viewId: Long viewId: Long
) { ) {
val miniPlayerPlayPauseReplayButtonIndex = val miniPlayerPlayPauseReplayButtonIndex =
getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) indexOfFirstWideLiteralInstructionValueOrThrow(MiniPlayerPlayPauseReplayButton)
val miniPlayerPlayPauseReplayButtonRegister = val miniPlayerPlayPauseReplayButtonRegister =
getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA
val findViewByIdIndex = val findViewByIdIndex =
getTargetIndexOrThrow(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL) indexOfFirstInstructionOrThrow(
miniPlayerPlayPauseReplayButtonIndex,
Opcode.INVOKE_VIRTUAL
)
val parentViewRegister = val parentViewRegister =
getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC
@ -966,11 +972,14 @@ object PlayerComponentsPatch : BaseBytecodePatch(
viewId: Long viewId: Long
) { ) {
val miniPlayerPlayPauseReplayButtonIndex = val miniPlayerPlayPauseReplayButtonIndex =
getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) indexOfFirstWideLiteralInstructionValueOrThrow(MiniPlayerPlayPauseReplayButton)
val constRegister = val constRegister =
getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA getInstruction<OneRegisterInstruction>(miniPlayerPlayPauseReplayButtonIndex).registerA
val findViewByIdIndex = val findViewByIdIndex =
getTargetIndexOrThrow(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_VIRTUAL) indexOfFirstInstructionOrThrow(
miniPlayerPlayPauseReplayButtonIndex,
Opcode.INVOKE_VIRTUAL
)
val findViewByIdRegister = val findViewByIdRegister =
getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC getInstruction<FiveRegisterInstruction>(findViewByIdIndex).registerC
@ -986,9 +995,12 @@ object PlayerComponentsPatch : BaseBytecodePatch(
private fun MutableMethod.setViewArray() { private fun MutableMethod.setViewArray() {
val miniPlayerPlayPauseReplayButtonIndex = val miniPlayerPlayPauseReplayButtonIndex =
getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) indexOfFirstWideLiteralInstructionValueOrThrow(MiniPlayerPlayPauseReplayButton)
val invokeStaticIndex = val invokeStaticIndex =
getTargetIndexOrThrow(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_STATIC) indexOfFirstInstructionOrThrow(
miniPlayerPlayPauseReplayButtonIndex,
Opcode.INVOKE_STATIC
)
val viewArrayRegister = getInstruction<FiveRegisterInstruction>(invokeStaticIndex).registerC val viewArrayRegister = getInstruction<FiveRegisterInstruction>(invokeStaticIndex).registerC
addInstructions( addInstructions(
@ -1005,8 +1017,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
methodName: String, methodName: String,
fieldName: String fieldName: String
) { ) {
val startIndex = getStringInstructionIndex(intentString) val startIndex = indexOfFirstStringInstructionOrThrow(intentString)
val onClickIndex = getTargetIndexReversedOrThrow(startIndex, Opcode.INVOKE_VIRTUAL) val onClickIndex = indexOfFirstInstructionReversedOrThrow(startIndex, Opcode.INVOKE_VIRTUAL)
val onClickReference = getInstruction<ReferenceInstruction>(onClickIndex).reference val onClickReference = getInstruction<ReferenceInstruction>(onClickIndex).reference
val onClickReferenceDefiningClass = (onClickReference as MethodReference).definingClass val onClickReferenceDefiningClass = (onClickReference as MethodReference).definingClass
@ -1016,7 +1028,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
onClickClass.methods.find { method -> method.name == "<init>" } onClickClass.methods.find { method -> method.name == "<init>" }
?.apply { ?.apply {
addInstruction( addInstruction(
implementation!!.instructions.size - 1, implementation!!.instructions.lastIndex,
"sput-object p0, $PLAYER_CLASS_DESCRIPTOR->$fieldName:$onClickReferenceDefiningClass" "sput-object p0, $PLAYER_CLASS_DESCRIPTOR->$fieldName:$onClickReferenceDefiningClass"
) )
} ?: throw PatchException("onClickClass not found!") } ?: throw PatchException("onClickClass not found!")

View File

@ -3,13 +3,13 @@ package app.revanced.patches.music.player.components.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.ColorGrey
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
internal object MiniPlayerConstructorFingerprint : MethodFingerprint( internal object MiniPlayerConstructorFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
strings = listOf("sharedToggleMenuItemMutations"), strings = listOf("sharedToggleMenuItemMutations"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(ColorGrey) methodDef.containsWideLiteralInstructionValue(ColorGrey)
&& methodDef.containsWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) && methodDef.containsWideLiteralInstructionValue(MiniPlayerPlayPauseReplayButton)
} }
) )

View File

@ -2,7 +2,7 @@ package app.revanced.patches.music.player.components.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
internal object MppWatchWhileLayoutFingerprint : MethodFingerprint( internal object MppWatchWhileLayoutFingerprint : MethodFingerprint(
@ -11,6 +11,6 @@ internal object MppWatchWhileLayoutFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/MppWatchWhileLayout;") methodDef.definingClass.endsWith("/MppWatchWhileLayout;")
&& methodDef.name == "onFinishInflate" && methodDef.name == "onFinishInflate"
&& methodDef.containsWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton) && methodDef.containsWideLiteralInstructionValue(MiniPlayerPlayPauseReplayButton)
} }
) )

View File

@ -1,13 +1,13 @@
package app.revanced.patches.music.player.components.fingerprints package app.revanced.patches.music.player.components.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
internal object MusicActivityWidgetFingerprint : MethodFingerprint( internal object MusicActivityWidgetFingerprint : MethodFingerprint(
customFingerprint = handler@{ methodDef, _ -> customFingerprint = handler@{ methodDef, _ ->
if (!methodDef.definingClass.endsWith("/MusicActivity;")) if (!methodDef.definingClass.endsWith("/MusicActivity;"))
return@handler false return@handler false
methodDef.containsWideLiteralInstructionIndex(79500) methodDef.containsWideLiteralInstructionValue(79500)
} }
) )

View File

@ -4,14 +4,14 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerViewPager import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerViewPager
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerViewPager import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.PlayerViewPager
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object PlayerViewPagerConstructorFingerprint : MethodFingerprint( internal object PlayerViewPagerConstructorFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(MiniPlayerViewPager) methodDef.containsWideLiteralInstructionValue(MiniPlayerViewPager)
&& methodDef.containsWideLiteralInstructionIndex(PlayerViewPager) && methodDef.containsWideLiteralInstructionValue(PlayerViewPager)
}, },
) )

View File

@ -3,13 +3,13 @@ package app.revanced.patches.music.player.components.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.DarkBackground import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.DarkBackground
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TapBloomView import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TapBloomView
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
internal object QuickSeekOverlayFingerprint : MethodFingerprint( internal object QuickSeekOverlayFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
parameters = emptyList(), parameters = emptyList(),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(DarkBackground) methodDef.containsWideLiteralInstructionValue(DarkBackground)
&& methodDef.containsWideLiteralInstructionIndex(TapBloomView) && methodDef.containsWideLiteralInstructionValue(TapBloomView)
}, },
) )

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfImageViewInstruction import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfImageViewInstruction
import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfOrdinalInstruction import app.revanced.patches.music.player.components.fingerprints.ShuffleClassReferenceFingerprint.indexOfOrdinalInstruction
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
@ -19,7 +19,7 @@ internal object ShuffleClassReferenceFingerprint : MethodFingerprint(
parameters = emptyList(), parameters = emptyList(),
strings = listOf("Unknown shuffle mode"), strings = listOf("Unknown shuffle mode"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(45468) && methodDef.containsWideLiteralInstructionValue(45468) &&
indexOfOrdinalInstruction(methodDef) >= 0 && indexOfOrdinalInstruction(methodDef) >= 0 &&
indexOfImageViewInstruction(methodDef) >= 0 indexOfImageViewInstruction(methodDef) >= 0
} }

View File

@ -1,60 +0,0 @@
package app.revanced.patches.music.utils.fix.accessibility
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patches.music.utils.fix.accessibility.fingerprints.TouchExplorationHoverEventFingerprint
import app.revanced.util.containsMethodReferenceNameInstructionIndex
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object AccessibilityNodeInfoPatch : BytecodePatch(
setOf(TouchExplorationHoverEventFingerprint)
) {
override fun execute(context: BytecodeContext) {
/**
* The "getTouchDelegateInfo" method has been implemented in YT Music v6.44.52.
* For some reason this method sometimes returns null, which throws [IllegalArgumentException].
* This is considered unimplemented code, so remove all methods associated with it.
*/
TouchExplorationHoverEventFingerprint.result?.let {
it.mutableMethod.apply {
// Target instruction is invoke-static, but can also be invoke-virtual.
// Therefore, the opcode is not checked.
val touchExplorationHoverEventMethodIndex =
implementation!!.instructions.indexOfFirst { instruction ->
val reference =
((instruction as? ReferenceInstruction)?.reference as? MethodReference)
((instruction as? ReferenceInstruction)?.reference as? MethodReference)?.definingClass == definingClass
&& reference?.returnType == "Z"
}
// Doesn't raise an exception, even if the target instruction is not found in this method
val touchExplorationHoverEventMethodName =
if (touchExplorationHoverEventMethodIndex > -1)
(getInstruction<ReferenceInstruction>(touchExplorationHoverEventMethodIndex).reference as MethodReference).name
else
"UNDEFINED"
val methods = it.mutableClass.methods
methods.find { method ->
method.name == "getTouchDelegateInfo"
}?.apply {
if (!containsMethodReferenceNameInstructionIndex("isEmpty")) {
arrayOf(
"getTouchDelegateInfo",
name,
touchExplorationHoverEventMethodName
).forEach { methodName ->
methods.removeIf { method ->
method.name == methodName
}
}
}
}
}
} // If this method has not been added, there is no need to remove it, so it will not raise any exceptions.
}
}

View File

@ -1,8 +0,0 @@
package app.revanced.patches.music.utils.fix.accessibility.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object TouchExplorationHoverEventFingerprint : MethodFingerprint(
returnType = "Z",
customFingerprint = { methodDef, _ -> methodDef.name == "onTouchExplorationHoverEvent" }
)

View File

@ -1,16 +1,11 @@
package app.revanced.patches.music.utils.fix.header package app.revanced.patches.music.utils.fix.header
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.layout.header.ChangeHeaderPatch import app.revanced.patches.music.layout.header.ChangeHeaderPatch
import app.revanced.patches.music.utils.fix.header.fingerprints.HeaderSwitchConfigFingerprint import app.revanced.patches.music.utils.fix.header.fingerprints.HeaderSwitchConfigFingerprint
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.getWideLiteralInstructionIndex
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch( @Patch(
description = "Fix the issues where new headers are used." description = "Fix the issues where new headers are used."
@ -31,19 +26,10 @@ object RestoreOldHeaderPatch : BytecodePatch(
* TODO: Add a new header image file to [ChangeHeaderPatch] later. * TODO: Add a new header image file to [ChangeHeaderPatch] later.
*/ */
HeaderSwitchConfigFingerprint.result?.let { HeaderSwitchConfigFingerprint.result?.let {
it.mutableMethod.apply { HeaderSwitchConfigFingerprint.injectLiteralInstructionBooleanCall(
val targetIndex = 45617851,
getTargetIndexOrThrow( "0x0"
getWideLiteralInstructionIndex(45617851),
Opcode.MOVE_RESULT
) )
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction(
targetIndex + 1,
"const/4 v$targetRegister, 0x0"
)
}
} }
} }

View File

@ -17,7 +17,7 @@ import app.revanced.patches.music.utils.settings.fingerprints.PreferenceFingerpr
import app.revanced.patches.music.utils.settings.fingerprints.SettingsHeadersFragmentFingerprint import app.revanced.patches.music.utils.settings.fingerprints.SettingsHeadersFragmentFingerprint
import app.revanced.patches.shared.fingerprints.SharedSettingFingerprint import app.revanced.patches.shared.fingerprints.SharedSettingFingerprint
import app.revanced.patches.shared.integrations.Constants.INTEGRATIONS_UTILS_CLASS_DESCRIPTOR import app.revanced.patches.shared.integrations.Constants.INTEGRATIONS_UTILS_CLASS_DESCRIPTOR
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@ -52,7 +52,7 @@ object SettingsBytecodePatch : BytecodePatch(
*/ */
SharedSettingFingerprint.resultOrThrow().let { SharedSettingFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val stringIndex = getTargetIndexOrThrow(Opcode.CONST_STRING) val stringIndex = indexOfFirstInstructionOrThrow(Opcode.CONST_STRING)
val stringRegister = getInstruction<OneRegisterInstruction>(stringIndex).registerA val stringRegister = getInstruction<OneRegisterInstruction>(stringIndex).registerA
replaceInstruction( replaceInstruction(

View File

@ -3,7 +3,6 @@ package app.revanced.patches.music.utils.settings
import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.music.utils.fix.accessibility.AccessibilityNodeInfoPatch
import app.revanced.patches.music.utils.settings.ResourceUtils.addPreferenceCategory import app.revanced.patches.music.utils.settings.ResourceUtils.addPreferenceCategory
import app.revanced.patches.music.utils.settings.ResourceUtils.addPreferenceWithIntent import app.revanced.patches.music.utils.settings.ResourceUtils.addPreferenceWithIntent
import app.revanced.patches.music.utils.settings.ResourceUtils.addRVXSettingsPreference import app.revanced.patches.music.utils.settings.ResourceUtils.addRVXSettingsPreference
@ -22,10 +21,7 @@ import java.util.concurrent.TimeUnit
object SettingsPatch : BaseResourcePatch( object SettingsPatch : BaseResourcePatch(
name = "Settings for YouTube Music", name = "Settings for YouTube Music",
description = "Applies mandatory patches to implement ReVanced Extended settings into the application.", description = "Applies mandatory patches to implement ReVanced Extended settings into the application.",
dependencies = setOf( dependencies = setOf(SettingsBytecodePatch::class),
AccessibilityNodeInfoPatch::class,
SettingsBytecodePatch::class
),
compatiblePackages = COMPATIBLE_PACKAGE, compatiblePackages = COMPATIBLE_PACKAGE,
requiresIntegrations = true requiresIntegrations = true
), Closeable { ), Closeable {

View File

@ -14,13 +14,17 @@ import app.revanced.patches.music.utils.sponsorblock.fingerprints.MusicPlaybackC
import app.revanced.patches.music.utils.sponsorblock.fingerprints.SeekbarOnDrawFingerprint import app.revanced.patches.music.utils.sponsorblock.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.music.video.information.VideoInformationPatch import app.revanced.patches.music.video.information.VideoInformationPatch
import app.revanced.patches.music.video.videoid.VideoIdPatch import app.revanced.patches.music.video.videoid.VideoIdPatch
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.alsoResolve
import app.revanced.util.getTargetIndexWithMethodReferenceNameReversedOrThrow import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.resultOrThrow 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction 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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Patch( @Patch(
dependencies = [ dependencies = [
@ -55,10 +59,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
/** /**
* Responsible for seekbar in fullscreen * Responsible for seekbar in fullscreen
*/ */
val seekBarClass = SeekBarConstructorFingerprint.resultOrThrow().mutableClass SeekbarOnDrawFingerprint.alsoResolve(
SeekbarOnDrawFingerprint.resolve(context, seekBarClass) context, SeekBarConstructorFingerprint
).let {
SeekbarOnDrawFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
// Initialize seekbar method // Initialize seekbar method
addInstructions( addInstructions(
@ -70,7 +73,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
) )
// Set seekbar thickness // Set seekbar thickness
val roundIndex = getTargetIndexWithMethodReferenceNameOrThrow("round") + 1 val roundIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "round"
} + 1
val roundRegister = getInstruction<OneRegisterInstruction>(roundIndex).registerA val roundRegister = getInstruction<OneRegisterInstruction>(roundIndex).registerA
addInstruction( addInstruction(
roundIndex + 1, roundIndex + 1,
@ -79,8 +84,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
) )
// Draw segment // Draw segment
val drawCircleIndex = val drawCircleIndex = indexOfFirstInstructionReversedOrThrow {
getTargetIndexWithMethodReferenceNameReversedOrThrow("drawCircle") getReference<MethodReference>()?.name == "drawCircle"
}
val drawCircleInstruction = getInstruction<FiveRegisterInstruction>(drawCircleIndex) val drawCircleInstruction = getInstruction<FiveRegisterInstruction>(drawCircleIndex)
addInstruction( addInstruction(
drawCircleIndex, drawCircleIndex,
@ -115,7 +121,10 @@ object SponsorBlockBytecodePatch : BytecodePatch(
) )
// Draw segment // Draw segment
val drawCircleIndex = getTargetIndexWithMethodReferenceNameOrThrow("drawCircle") val drawCircleIndex = indexOfFirstInstructionReversedOrThrow {
opcode == Opcode.INVOKE_VIRTUAL
&& getReference<MethodReference>()?.name == "drawCircle"
}
val drawCircleInstruction = getInstruction<FiveRegisterInstruction>(drawCircleIndex) val drawCircleInstruction = getInstruction<FiveRegisterInstruction>(drawCircleIndex)
addInstruction( addInstruction(
drawCircleIndex, drawCircleIndex,

View File

@ -26,10 +26,9 @@ import app.revanced.patches.music.video.videoid.VideoIdPatch
import app.revanced.patches.shared.fingerprints.MdxPlayerDirectorSetVideoStageFingerprint import app.revanced.patches.shared.fingerprints.MdxPlayerDirectorSetVideoStageFingerprint
import app.revanced.util.addFieldAndInstructions import app.revanced.util.addFieldAndInstructions
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithFieldReferenceTypeReversedOrThrow
import app.revanced.util.getTargetIndexWithMethodReferenceNameReversedOrThrow
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -216,12 +215,10 @@ object VideoInformationPatch : BytecodePatch(
) )
VideoLengthFingerprint.resultOrThrow().let { VideoLengthFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val invalidateIndex = val invalidateIndex = VideoLengthFingerprint.indexOfInvalidateInstruction(this)
getTargetIndexWithMethodReferenceNameReversedOrThrow("invalidate") val rectangleIndex = indexOfFirstInstructionReversedOrThrow(invalidateIndex + 1) {
val rectangleIndex = getTargetIndexWithFieldReferenceTypeReversedOrThrow( getReference<FieldReference>()?.type == "Landroid/graphics/Rect;"
invalidateIndex + 1, }
"Landroid/graphics/Rect;"
)
rectangleFieldName = rectangleFieldName =
(getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name (getInstruction<ReferenceInstruction>(rectangleIndex).reference as FieldReference).name

View File

@ -1,9 +1,14 @@
package app.revanced.patches.music.video.information.fingerprints package app.revanced.patches.music.video.information.fingerprints
import app.revanced.util.fingerprint.MethodReferenceNameFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.music.video.information.fingerprints.VideoLengthFingerprint.indexOfInvalidateInstruction
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionReversed
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal object VideoLengthFingerprint : MethodReferenceNameFingerprint( internal object VideoLengthFingerprint : MethodFingerprint(
opcodes = listOf( opcodes = listOf(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_WIDE, Opcode.MOVE_RESULT_WIDE,
@ -12,5 +17,12 @@ internal object VideoLengthFingerprint : MethodReferenceNameFingerprint(
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_WIDE Opcode.MOVE_RESULT_WIDE
), ),
reference = { "invalidate" } customFingerprint = { methodDef, _ ->
) indexOfInvalidateInstruction(methodDef) >= 0
}
) {
fun indexOfInvalidateInstruction(methodDef: Method) =
methodDef.indexOfFirstInstructionReversed {
getReference<MethodReference>()?.name == "invalidate"
}
}

View File

@ -13,7 +13,7 @@ import app.revanced.patches.music.video.information.VideoInformationPatch
import app.revanced.patches.music.video.playback.fingerprints.PlaybackSpeedBottomSheetFingerprint import app.revanced.patches.music.video.playback.fingerprints.PlaybackSpeedBottomSheetFingerprint
import app.revanced.patches.music.video.playback.fingerprints.UserQualityChangeFingerprint import app.revanced.patches.music.video.playback.fingerprints.UserQualityChangeFingerprint
import app.revanced.patches.music.video.videoid.VideoIdPatch import app.revanced.patches.music.video.videoid.VideoIdPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -52,7 +52,7 @@ object VideoPlaybackPatch : BaseBytecodePatch(
it.mutableClass.methods.find { method -> method.name == "onItemClick" } it.mutableClass.methods.find { method -> method.name == "onItemClick" }
onItemClickMethod?.apply { onItemClickMethod?.apply {
val targetIndex = getTargetIndexOrThrow(Opcode.IGET) val targetIndex = indexOfFirstInstructionOrThrow(Opcode.IGET)
val targetRegister = val targetRegister =
getInstruction<TwoRegisterInstruction>(targetIndex).registerA getInstruction<TwoRegisterInstruction>(targetIndex).registerA

View File

@ -12,12 +12,15 @@ import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACK
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexWithFieldReferenceNameOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction 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") @Suppress("unused")
object AdsPatch : BaseBytecodePatch( object AdsPatch : BaseBytecodePatch(
@ -42,7 +45,9 @@ object AdsPatch : BaseBytecodePatch(
// region Filter promoted ads (does not work in popular or latest feed) // region Filter promoted ads (does not work in popular or latest feed)
AdPostFingerprint.resultOrThrow().let { AdPostFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = getTargetIndexWithFieldReferenceNameOrThrow("children") val targetIndex = indexOfFirstInstructionOrThrow {
getReference<FieldReference>()?.name == "children"
}
val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
addInstructions( addInstructions(
@ -59,7 +64,10 @@ object AdsPatch : BaseBytecodePatch(
// By removing the appending instruction no ad posts gets appended to the feed. // By removing the appending instruction no ad posts gets appended to the feed.
NewAdPostFingerprint.resultOrThrow().let { NewAdPostFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = getTargetIndexWithMethodReferenceNameOrThrow("add") val targetIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL
&& getReference<MethodReference>()?.toString() == "Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z"
}
val targetInstruction = getInstruction<FiveRegisterInstruction>(targetIndex) val targetInstruction = getInstruction<FiveRegisterInstruction>(targetIndex)
replaceInstruction( replaceInstruction(

View File

@ -9,15 +9,15 @@ import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACK
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexReversedOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getTargetIndexWithFieldReferenceNameOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.getTargetIndexWithReferenceOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction 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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.Reference import com.android.tools.smali.dexlib2.iface.reference.Reference
@Suppress("unused") @Suppress("unused")
@ -40,20 +40,31 @@ object RecentlyVisitedShelfPatch : BaseBytecodePatch(
it.mutableClass.methods.find { method -> method.name == "<init>" } it.mutableClass.methods.find { method -> method.name == "<init>" }
?.apply { ?.apply {
val recentlyVisitedFieldIndex = val recentlyVisitedFieldIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithFieldReferenceNameOrThrow("RECENTLY_VISITED") getReference<FieldReference>()?.name == "RECENTLY_VISITED"
}
val recentlyVisitedObjectIndex = val recentlyVisitedObjectIndex =
getTargetIndexOrThrow(recentlyVisitedFieldIndex, Opcode.IPUT_OBJECT) indexOfFirstInstructionOrThrow(
recentlyVisitedFieldIndex,
Opcode.IPUT_OBJECT
)
recentlyVisitedReference = recentlyVisitedReference =
getInstruction<ReferenceInstruction>(recentlyVisitedObjectIndex).reference getInstruction<ReferenceInstruction>(recentlyVisitedObjectIndex).reference
} ?: throw PatchException("Constructor method not found!") } ?: throw PatchException("Constructor method not found!")
it.mutableMethod.apply { it.mutableMethod.apply {
val recentlyVisitedObjectIndex = val recentlyVisitedObjectIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithReferenceOrThrow(recentlyVisitedReference.toString()) getReference<FieldReference>()?.toString() == recentlyVisitedReference.toString()
}
arrayOf( arrayOf(
getTargetIndexOrThrow(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC), indexOfFirstInstructionOrThrow(
getTargetIndexReversedOrThrow(recentlyVisitedObjectIndex, Opcode.INVOKE_STATIC) recentlyVisitedObjectIndex,
Opcode.INVOKE_STATIC
),
indexOfFirstInstructionReversedOrThrow(
recentlyVisitedObjectIndex,
Opcode.INVOKE_STATIC
)
).forEach { staticIndex -> ).forEach { staticIndex ->
val insertRegister = val insertRegister =
getInstruction<OneRegisterInstruction>(staticIndex + 1).registerA getInstruction<OneRegisterInstruction>(staticIndex + 1).registerA

View File

@ -3,14 +3,14 @@ package app.revanced.patches.reddit.layout.screenshotpopup.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.ScreenShotShareBanner import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.ScreenShotShareBanner
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object ScreenshotTakenBannerFingerprint : MethodFingerprint( internal object ScreenshotTakenBannerFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
customFingerprint = { methodDef, classDef -> customFingerprint = { methodDef, classDef ->
methodDef.containsWideLiteralInstructionIndex(ScreenShotShareBanner) methodDef.containsWideLiteralInstructionValue(ScreenShotShareBanner)
&& classDef.sourceFile == "ScreenshotTakenBanner.kt" && classDef.sourceFile == "ScreenshotTakenBanner.kt"
} }
) )

View File

@ -12,7 +12,7 @@ import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.Cancel
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.TextAppearanceRedditBaseOldButtonColored import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.TextAppearanceRedditBaseOldButtonColored
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@ -39,7 +39,8 @@ object SubRedditDialogPatch : BaseBytecodePatch(
FrequentUpdatesSheetScreenFingerprint.resultOrThrow().let { FrequentUpdatesSheetScreenFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val cancelButtonViewIndex = getWideLiteralInstructionIndex(CancelButton) + 2 val cancelButtonViewIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(CancelButton) + 2
val cancelButtonViewRegister = val cancelButtonViewRegister =
getInstruction<OneRegisterInstruction>(cancelButtonViewIndex).registerA getInstruction<OneRegisterInstruction>(cancelButtonViewIndex).registerA
@ -53,7 +54,9 @@ object SubRedditDialogPatch : BaseBytecodePatch(
RedditAlertDialogsFingerprint.resultOrThrow().let { RedditAlertDialogsFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = val insertIndex =
getWideLiteralInstructionIndex(TextAppearanceRedditBaseOldButtonColored) + 1 indexOfFirstWideLiteralInstructionValueOrThrow(
TextAppearanceRedditBaseOldButtonColored
) + 1
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerC
addInstruction( addInstruction(

View File

@ -3,14 +3,14 @@ package app.revanced.patches.reddit.layout.subredditdialog.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.CancelButton import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.CancelButton
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object FrequentUpdatesSheetScreenFingerprint : MethodFingerprint( internal object FrequentUpdatesSheetScreenFingerprint : MethodFingerprint(
returnType = "Landroid/view/View;", returnType = "Landroid/view/View;",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
customFingerprint = { methodDef, classDef -> customFingerprint = { methodDef, classDef ->
methodDef.containsWideLiteralInstructionIndex(CancelButton) methodDef.containsWideLiteralInstructionValue(CancelButton)
&& classDef.sourceFile == "FrequentUpdatesSheetScreen.kt" && classDef.sourceFile == "FrequentUpdatesSheetScreen.kt"
} }
) )

View File

@ -3,14 +3,14 @@ package app.revanced.patches.reddit.layout.subredditdialog.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.TextAppearanceRedditBaseOldButtonColored import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.TextAppearanceRedditBaseOldButtonColored
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object RedditAlertDialogsFingerprint : MethodFingerprint( internal object RedditAlertDialogsFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
customFingerprint = { methodDef, classDef -> customFingerprint = { methodDef, classDef ->
methodDef.containsWideLiteralInstructionIndex(TextAppearanceRedditBaseOldButtonColored) methodDef.containsWideLiteralInstructionValue(TextAppearanceRedditBaseOldButtonColored)
&& classDef.sourceFile == "RedditAlertDialogs.kt" && classDef.sourceFile == "RedditAlertDialogs.kt"
} }
) )

View File

@ -10,7 +10,7 @@ import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.ToolBarNavSearchCtaContainer import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.ToolBarNavSearchCtaContainer
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -35,7 +35,7 @@ object ToolBarButtonPatch : BaseBytecodePatch(
HomePagerScreenFingerprint.resultOrThrow().let { HomePagerScreenFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = val targetIndex =
getWideLiteralInstructionIndex(ToolBarNavSearchCtaContainer) + 3 indexOfFirstWideLiteralInstructionValueOrThrow(ToolBarNavSearchCtaContainer) + 3
val targetRegister = val targetRegister =
getInstruction<OneRegisterInstruction>(targetIndex - 1).registerA getInstruction<OneRegisterInstruction>(targetIndex - 1).registerA

View File

@ -3,7 +3,7 @@ package app.revanced.patches.reddit.layout.toolbar.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.ToolBarNavSearchCtaContainer import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.ToolBarNavSearchCtaContainer
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object HomePagerScreenFingerprint : MethodFingerprint( internal object HomePagerScreenFingerprint : MethodFingerprint(
@ -12,6 +12,6 @@ internal object HomePagerScreenFingerprint : MethodFingerprint(
parameters = listOf("Landroid/view/LayoutInflater;", "Landroid/view/ViewGroup;"), parameters = listOf("Landroid/view/LayoutInflater;", "Landroid/view/ViewGroup;"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/HomePagerScreen;") methodDef.definingClass.endsWith("/HomePagerScreen;")
&& methodDef.containsWideLiteralInstructionIndex(ToolBarNavSearchCtaContainer) && methodDef.containsWideLiteralInstructionValue(ToolBarNavSearchCtaContainer)
} }
) )

View File

@ -9,7 +9,7 @@ import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACK
import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.integrations.Constants.PATCHES_PATH
import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus import app.revanced.patches.reddit.utils.settings.SettingsBytecodePatch.updateSettingsStatus
import app.revanced.patches.reddit.utils.settings.SettingsPatch import app.revanced.patches.reddit.utils.settings.SettingsPatch
import app.revanced.util.getStringInstructionIndex import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
@ -27,7 +27,7 @@ object OpenLinksExternallyPatch : BaseBytecodePatch(
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
ScreenNavigatorFingerprint.resultOrThrow().let { ScreenNavigatorFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = getStringInstructionIndex("uri") + 2 val insertIndex = indexOfFirstStringInstructionOrThrow("uri") + 2
addInstructionsWithLabels( addInstructionsWithLabels(
insertIndex, """ insertIndex, """

View File

@ -15,8 +15,8 @@ import app.revanced.patches.reddit.utils.settings.fingerprints.AcknowledgementsL
import app.revanced.patches.reddit.utils.settings.fingerprints.OssLicensesMenuActivityOnCreateFingerprint import app.revanced.patches.reddit.utils.settings.fingerprints.OssLicensesMenuActivityOnCreateFingerprint
import app.revanced.patches.reddit.utils.settings.fingerprints.SettingsStatusLoadFingerprint import app.revanced.patches.reddit.utils.settings.fingerprints.SettingsStatusLoadFingerprint
import app.revanced.patches.shared.fingerprints.SharedSettingFingerprint import app.revanced.patches.shared.fingerprints.SharedSettingFingerprint
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -39,7 +39,7 @@ object SettingsBytecodePatch : BytecodePatch(
internal fun updateSettingsLabel(label: String) = internal fun updateSettingsLabel(label: String) =
acknowledgementsLabelBuilderMethod.apply { acknowledgementsLabelBuilderMethod.apply {
val insertIndex = val insertIndex =
getWideLiteralInstructionIndex(LabelAcknowledgements) + 3 indexOfFirstWideLiteralInstructionValueOrThrow(LabelAcknowledgements) + 3
val insertRegister = val insertRegister =
getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
@ -62,7 +62,7 @@ object SettingsBytecodePatch : BytecodePatch(
*/ */
SharedSettingFingerprint.resultOrThrow().let { SharedSettingFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val stringIndex = getTargetIndexOrThrow(Opcode.CONST_STRING) val stringIndex = indexOfFirstInstructionOrThrow(Opcode.CONST_STRING)
val stringRegister = getInstruction<OneRegisterInstruction>(stringIndex).registerA val stringRegister = getInstruction<OneRegisterInstruction>(stringIndex).registerA
replaceInstruction( replaceInstruction(

View File

@ -3,7 +3,7 @@ package app.revanced.patches.reddit.utils.settings.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.LabelAcknowledgements import app.revanced.patches.reddit.utils.resourceid.SharedResourceIdPatch.LabelAcknowledgements
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object AcknowledgementsLabelBuilderFingerprint : MethodFingerprint( internal object AcknowledgementsLabelBuilderFingerprint : MethodFingerprint(
@ -12,6 +12,6 @@ internal object AcknowledgementsLabelBuilderFingerprint : MethodFingerprint(
parameters = listOf("Landroidx/preference/Preference;"), parameters = listOf("Landroidx/preference/Preference;"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass.startsWith("Lcom/reddit/screen/settings/preferences/") methodDef.definingClass.startsWith("Lcom/reddit/screen/settings/preferences/")
&& methodDef.containsWideLiteralInstructionIndex(LabelAcknowledgements) && methodDef.containsWideLiteralInstructionValue(LabelAcknowledgements)
} }
) )

View File

@ -14,8 +14,8 @@ import app.revanced.patches.shared.ads.fingerprints.VideoAdsFingerprint
import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -75,7 +75,7 @@ abstract class BaseAdsPatch(
internal fun MethodFingerprintResult.hookNonLithoFullscreenAds(literal: Long) { internal fun MethodFingerprintResult.hookNonLithoFullscreenAds(literal: Long) {
mutableMethod.apply { mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(literal) + 2 val targetIndex = indexOfFirstWideLiteralInstructionValueOrThrow(literal) + 2
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(

View File

@ -8,14 +8,14 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patches.shared.customspeed.fingerprints.SpeedArrayGeneratorFingerprint import app.revanced.patches.shared.customspeed.fingerprints.SpeedArrayGeneratorFingerprint
import app.revanced.patches.shared.customspeed.fingerprints.SpeedLimiterFallBackFingerprint import app.revanced.patches.shared.customspeed.fingerprints.SpeedLimiterFallBackFingerprint
import app.revanced.patches.shared.customspeed.fingerprints.SpeedLimiterFingerprint import app.revanced.patches.shared.customspeed.fingerprints.SpeedLimiterFingerprint
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithFieldReferenceTypeOrThrow
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
abstract class BaseCustomPlaybackSpeedPatch( abstract class BaseCustomPlaybackSpeedPatch(
private val descriptor: String, private val descriptor: String,
@ -39,7 +39,9 @@ abstract class BaseCustomPlaybackSpeedPatch(
""" """
) )
val sizeIndex = getTargetIndexWithMethodReferenceNameOrThrow("size") + 1 val sizeIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "size"
} + 1
val sizeRegister = getInstruction<OneRegisterInstruction>(sizeIndex).registerA val sizeRegister = getInstruction<OneRegisterInstruction>(sizeIndex).registerA
addInstructions( addInstructions(
@ -49,7 +51,9 @@ abstract class BaseCustomPlaybackSpeedPatch(
""" """
) )
val arrayIndex = getTargetIndexWithFieldReferenceTypeOrThrow("[F") val arrayIndex = indexOfFirstInstructionOrThrow {
getReference<FieldReference>()?.type == "[F"
}
val arrayRegister = getInstruction<OneRegisterInstruction>(arrayIndex).registerA val arrayRegister = getInstruction<OneRegisterInstruction>(arrayIndex).registerA
addInstructions( addInstructions(
@ -73,7 +77,7 @@ abstract class BaseCustomPlaybackSpeedPatch(
val limiterMinConstIndex = val limiterMinConstIndex =
indexOfFirstInstructionOrThrow { (this as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() } indexOfFirstInstructionOrThrow { (this as? NarrowLiteralInstruction)?.narrowLiteral == 0.25f.toRawBits() }
val limiterMaxConstIndex = val limiterMaxConstIndex =
getTargetIndexOrThrow(limiterMinConstIndex + 1, Opcode.CONST_HIGH16) indexOfFirstInstructionOrThrow(limiterMinConstIndex + 1, Opcode.CONST_HIGH16)
val limiterMinConstDestination = val limiterMinConstDestination =
getInstruction<OneRegisterInstruction>(limiterMinConstIndex).registerA getInstruction<OneRegisterInstruction>(limiterMinConstIndex).registerA

View File

@ -7,10 +7,12 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.dialog.fingerprints.CreateDialogFingerprint import app.revanced.patches.shared.dialog.fingerprints.CreateDialogFingerprint
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
abstract class BaseViewerDiscretionDialogPatch( abstract class BaseViewerDiscretionDialogPatch(
private val classDescriptor: String, private val classDescriptor: String,
@ -22,7 +24,9 @@ abstract class BaseViewerDiscretionDialogPatch(
} }
) { ) {
private fun MutableMethod.invoke(isAgeVerified: Boolean) { private fun MutableMethod.invoke(isAgeVerified: Boolean) {
val showDialogIndex = getTargetIndexWithMethodReferenceNameOrThrow("show") val showDialogIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "show"
}
val dialogRegister = getInstruction<FiveRegisterInstruction>(showDialogIndex).registerC val dialogRegister = getInstruction<FiveRegisterInstruction>(showDialogIndex).registerC
val methodName = val methodName =

View File

@ -6,9 +6,11 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.drawable.fingerprints.DrawableFingerprint import app.revanced.patches.shared.drawable.fingerprints.DrawableFingerprint
import app.revanced.util.getTargetIndexWithMethodReferenceNameReversedOrThrow import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object DrawableColorPatch : BytecodePatch( object DrawableColorPatch : BytecodePatch(
setOf(DrawableFingerprint) setOf(DrawableFingerprint)
@ -17,17 +19,17 @@ object DrawableColorPatch : BytecodePatch(
DrawableFingerprint.resultOrThrow().mutableMethod.apply { DrawableFingerprint.resultOrThrow().mutableMethod.apply {
insertMethod = this insertMethod = this
insertIndex = getTargetIndexWithMethodReferenceNameReversedOrThrow("setColor") insertIndex = indexOfFirstInstructionReversedOrThrow {
getReference<MethodReference>()?.name == "setColor"
}
insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
} }
} }
private var offset = 0 private lateinit var insertMethod: MutableMethod
private var insertIndex: Int = 0 private var insertIndex: Int = 0
private var insertRegister: Int = 0 private var insertRegister: Int = 0
private lateinit var insertMethod: MutableMethod private var offset = 0
fun injectCall( fun injectCall(
methodDescriptor: String methodDescriptor: String

View File

@ -18,14 +18,12 @@ import app.revanced.patches.shared.gms.fingerprints.CastContextFetchFingerprint
import app.revanced.patches.shared.gms.fingerprints.CastDynamiteModuleFingerprint import app.revanced.patches.shared.gms.fingerprints.CastDynamiteModuleFingerprint
import app.revanced.patches.shared.gms.fingerprints.CastDynamiteModuleV2Fingerprint import app.revanced.patches.shared.gms.fingerprints.CastDynamiteModuleV2Fingerprint
import app.revanced.patches.shared.gms.fingerprints.CertificateFingerprint import app.revanced.patches.shared.gms.fingerprints.CertificateFingerprint
import app.revanced.patches.shared.gms.fingerprints.CertificateFingerprint.GET_PACKAGE_NAME_METHOD_REFERENCE
import app.revanced.patches.shared.gms.fingerprints.GmsCoreSupportFingerprint import app.revanced.patches.shared.gms.fingerprints.GmsCoreSupportFingerprint
import app.revanced.patches.shared.gms.fingerprints.GooglePlayUtilityFingerprint import app.revanced.patches.shared.gms.fingerprints.GooglePlayUtilityFingerprint
import app.revanced.patches.shared.gms.fingerprints.PrimeMethodFingerprint import app.revanced.patches.shared.gms.fingerprints.PrimeMethodFingerprint
import app.revanced.patches.shared.gms.fingerprints.ServiceCheckFingerprint import app.revanced.patches.shared.gms.fingerprints.ServiceCheckFingerprint
import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithReference
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import app.revanced.util.returnEarly import app.revanced.util.returnEarly
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -178,7 +176,7 @@ abstract class BaseGmsCoreSupportPatch(
CertificateFingerprint.result?.mutableClass?.methods?.forEach { mutableMethod -> CertificateFingerprint.result?.mutableClass?.methods?.forEach { mutableMethod ->
mutableMethod.apply { mutableMethod.apply {
val getPackageNameIndex = val getPackageNameIndex =
getTargetIndexWithReference(GET_PACKAGE_NAME_METHOD_REFERENCE) CertificateFingerprint.indexOfGetPackageNameInstruction(this)
if (getPackageNameIndex > -1) { if (getPackageNameIndex > -1) {
val targetRegister = val targetRegister =

View File

@ -1,20 +1,28 @@
package app.revanced.patches.shared.gms.fingerprints package app.revanced.patches.shared.gms.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patches.shared.gms.fingerprints.CertificateFingerprint.GET_PACKAGE_NAME_METHOD_REFERENCE import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.fingerprint.ReferenceFingerprint import app.revanced.patches.shared.gms.fingerprints.CertificateFingerprint.indexOfGetPackageNameInstruction
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
/** /**
* Method which the package name is used to check the app signature. * Method which the package name is used to check the app signature.
*/ */
internal object CertificateFingerprint : ReferenceFingerprint( internal object CertificateFingerprint : MethodFingerprint(
returnType = "Ljava/lang/String;", returnType = "Ljava/lang/String;",
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL, accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
parameters = emptyList(), parameters = emptyList(),
strings = listOf("X.509", "user", "S"), strings = listOf("X.509", "user", "S"),
reference = { GET_PACKAGE_NAME_METHOD_REFERENCE } customFingerprint = { methodDef, _ ->
) { indexOfGetPackageNameInstruction(methodDef) >= 0
const val GET_PACKAGE_NAME_METHOD_REFERENCE = }
"Landroid/content/Context;->getPackageName()Ljava/lang/String;" ) {
fun indexOfGetPackageNameInstruction(methodDef: Method) =
methodDef.indexOfFirstInstruction {
getReference<MethodReference>()?.toString() == "Landroid/content/Context;->getPackageName()Ljava/lang/String;"
}
} }

View File

@ -16,9 +16,9 @@ import app.revanced.patches.shared.litho.fingerprints.ByteBufferFingerprint
import app.revanced.patches.shared.litho.fingerprints.EmptyComponentsFingerprint import app.revanced.patches.shared.litho.fingerprints.EmptyComponentsFingerprint
import app.revanced.patches.shared.litho.fingerprints.PathBuilderFingerprint import app.revanced.patches.shared.litho.fingerprints.PathBuilderFingerprint
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.getStringInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -127,7 +127,7 @@ object LithoFilterPatch : BytecodePatch(
val stringBuilderRegister = val stringBuilderRegister =
getInstruction<TwoRegisterInstruction>(stringBuilderIndex).registerA getInstruction<TwoRegisterInstruction>(stringBuilderIndex).registerA
val emptyStringIndex = getStringInstructionIndex("") val emptyStringIndex = indexOfFirstStringInstructionOrThrow("")
val identifierRegister = getInstruction<TwoRegisterInstruction>( val identifierRegister = getInstruction<TwoRegisterInstruction>(
indexOfFirstInstructionReversedOrThrow(emptyStringIndex) { indexOfFirstInstructionReversedOrThrow(emptyStringIndex) {
opcode == Opcode.IPUT_OBJECT opcode == Opcode.IPUT_OBJECT

View File

@ -7,7 +7,7 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import kotlin.properties.Delegates import kotlin.properties.Delegates
@ -38,7 +38,8 @@ abstract class BaseMainActivityResolvePatch(
// set onBackPressed method // set onBackPressed method
onBackPressedMethod = getMethod("onBackPressed") onBackPressedMethod = getMethod("onBackPressed")
onBackPressedMethodIndex = onBackPressedMethod.getTargetIndexOrThrow(Opcode.RETURN_VOID) onBackPressedMethodIndex =
onBackPressedMethod.indexOfFirstInstructionOrThrow(Opcode.RETURN_VOID)
// set onConfigurationChanged method // set onConfigurationChanged method
onConfigurationChangedMethod = getMethod("onConfigurationChanged") onConfigurationChangedMethod = getMethod("onConfigurationChanged")

View File

@ -7,11 +7,13 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.shared.opus.fingerprints.CodecReferenceFingerprint import app.revanced.patches.shared.opus.fingerprints.CodecReferenceFingerprint
import app.revanced.patches.shared.opus.fingerprints.CodecSelectorFingerprint import app.revanced.patches.shared.opus.fingerprints.CodecSelectorFingerprint
import app.revanced.util.getTargetIndexWithReferenceOrThrow import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow 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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.Reference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
/** /**
* This patch is generally not required for the latest versions of YouTube and YouTube Music. * This patch is generally not required for the latest versions of YouTube and YouTube Music.
@ -25,15 +27,14 @@ abstract class BaseOpusCodecsPatch(
CodecSelectorFingerprint CodecSelectorFingerprint
) )
) { ) {
private lateinit var opusCodecReference: Reference
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
CodecReferenceFingerprint.resultOrThrow().let { val opusCodecReference = with(CodecReferenceFingerprint.resultOrThrow().mutableMethod) {
it.mutableMethod.apply { val codecIndex = indexOfFirstInstructionOrThrow {
val targetIndex = getTargetIndexWithReferenceOrThrow("Ljava/util/Set;") opcode == Opcode.INVOKE_STATIC &&
opusCodecReference = getInstruction<ReferenceInstruction>(targetIndex).reference getReference<MethodReference>()?.returnType == "Ljava/util/Set;"
} }
getInstruction<ReferenceInstruction>(codecIndex).reference
} }
CodecSelectorFingerprint.resultOrThrow().let { CodecSelectorFingerprint.resultOrThrow().let {

View File

@ -8,9 +8,11 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH import app.revanced.patches.shared.integrations.Constants.PATCHES_PATH
import app.revanced.patches.shared.settingmenu.fingerprints.SettingsMenuFingerprint import app.revanced.patches.shared.settingmenu.fingerprints.SettingsMenuFingerprint
import app.revanced.patches.shared.viewgroup.ViewGroupMarginLayoutParamsHookPatch import app.revanced.patches.shared.viewgroup.ViewGroupMarginLayoutParamsHookPatch
import app.revanced.util.getTargetIndexWithFieldReferenceTypeOrThrow import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
@Patch( @Patch(
description = "Hide the settings menu for YouTube or YouTube Music.", description = "Hide the settings menu for YouTube or YouTube Music.",
@ -25,8 +27,9 @@ object SettingsMenuPatch : BytecodePatch(
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
SettingsMenuFingerprint.resultOrThrow().mutableMethod.apply { SettingsMenuFingerprint.resultOrThrow().mutableMethod.apply {
val insertIndex = val insertIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithFieldReferenceTypeOrThrow("Landroid/support/v7/widget/RecyclerView;") getReference<FieldReference>()?.type == "Landroid/support/v7/widget/RecyclerView;"
}
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
addInstruction( addInstruction(

View File

@ -6,7 +6,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint
import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint.indexOfReleaseInstruction import app.revanced.patches.shared.fingerprints.CreatePlayerRequestBodyWithModelFingerprint.indexOfReleaseInstruction
import app.revanced.util.getTargetIndexReversedOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
@ -20,7 +20,8 @@ abstract class BaseSpoofAppVersionPatch(
CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.apply { CreatePlayerRequestBodyWithModelFingerprint.resultOrThrow().mutableMethod.apply {
val versionIndex = indexOfReleaseInstruction(this) + 1 val versionIndex = indexOfReleaseInstruction(this) + 1
val insertIndex = getTargetIndexReversedOrThrow(versionIndex, Opcode.IPUT_OBJECT) val insertIndex =
indexOfFirstInstructionReversedOrThrow(versionIndex, Opcode.IPUT_OBJECT)
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
addInstructions( addInstructions(

View File

@ -2,7 +2,7 @@ package app.revanced.patches.youtube.ads.general.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SlidingDialogAnimation 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 import com.android.tools.smali.dexlib2.Opcode
internal object ShowDialogCommandFingerprint : MethodFingerprint( internal object ShowDialogCommandFingerprint : MethodFingerprint(
@ -16,7 +16,7 @@ internal object ShowDialogCommandFingerprint : MethodFingerprint(
// 18.43 and earlier has a different first parameter. // 18.43 and earlier has a different first parameter.
// Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures. // Since this fingerprint is somewhat weak, work around by checking for both method parameter signatures.
customFingerprint = custom@{ methodDef, _ -> customFingerprint = custom@{ methodDef, _ ->
if (!methodDef.containsWideLiteralInstructionIndex(SlidingDialogAnimation)) { if (!methodDef.containsWideLiteralInstructionValue(SlidingDialogAnimation)) {
return@custom false return@custom false
} }
// 18.43 and earlier parameters are: "L", "L" // 18.43 and earlier parameters are: "L", "L"

View File

@ -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
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.CaptionToggleContainer import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.CaptionToggleContainer
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexReversedOrThrow
import app.revanced.util.getTargetIndexWithMethodReferenceName
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow 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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -113,8 +112,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
// region patch for hide caption button // region patch for hide caption button
CaptionsButtonFingerprint.resultOrThrow().mutableMethod.apply { CaptionsButtonFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(CaptionToggleContainer) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(CaptionToggleContainer)
val insertIndex = getTargetIndexReversedOrThrow(constIndex, Opcode.IF_EQZ) val insertIndex = indexOfFirstInstructionReversedOrThrow(constIndex, Opcode.IF_EQZ)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions( addInstructions(
@ -126,8 +125,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
} }
CaptionsButtonSyntheticFingerprint.resultOrThrow().mutableMethod.apply { CaptionsButtonSyntheticFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(CaptionToggleContainer) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(CaptionToggleContainer)
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT) val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.MOVE_RESULT_OBJECT)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(
@ -198,7 +197,7 @@ object FeedComponentsPatch : BaseBytecodePatch(
&& reference.returnType.startsWith("L") && reference.returnType.startsWith("L")
} }
val objectIndex = getTargetIndexOrThrow(Opcode.MOVE_OBJECT) val objectIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_OBJECT)
val objectRegister = getInstruction<TwoRegisterInstruction>(objectIndex).registerA val objectRegister = getInstruction<TwoRegisterInstruction>(objectIndex).registerA
val jumpIndex = it.scanResult.patternScanResult!!.startIndex val jumpIndex = it.scanResult.patternScanResult!!.startIndex
@ -253,7 +252,9 @@ object FeedComponentsPatch : BaseBytecodePatch(
ChannelTabRendererFingerprint.resultOrThrow().let { ChannelTabRendererFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val iteratorIndex = getTargetIndexWithMethodReferenceName("hasNext") val iteratorIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "hasNext"
}
val iteratorRegister = val iteratorRegister =
getInstruction<FiveRegisterInstruction>(iteratorIndex).registerC getInstruction<FiveRegisterInstruction>(iteratorIndex).registerC
@ -265,7 +266,8 @@ object FeedComponentsPatch : BaseBytecodePatch(
&& reference.parameterTypes == channelTabBuilderMethod.parameterTypes && reference.parameterTypes == channelTabBuilderMethod.parameterTypes
} }
val objectIndex = getTargetIndexReversedOrThrow(targetIndex, Opcode.IGET_OBJECT) val objectIndex =
indexOfFirstInstructionReversedOrThrow(targetIndex, Opcode.IGET_OBJECT)
val objectInstruction = getInstruction<TwoRegisterInstruction>(objectIndex) val objectInstruction = getInstruction<TwoRegisterInstruction>(objectIndex)
val objectReference = getInstruction<ReferenceInstruction>(objectIndex).reference val objectReference = getInstruction<ReferenceInstruction>(objectIndex).reference

View File

@ -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.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.settings.SettingsPatch 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.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction 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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object AudioTracksPatch : BaseBytecodePatch( object AudioTracksPatch : BaseBytecodePatch(
@ -32,15 +33,14 @@ object AudioTracksPatch : BaseBytecodePatch(
opcode == Opcode.CHECK_CAST opcode == Opcode.CHECK_CAST
&& (this as ReferenceInstruction).reference.toString() == "Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;" && (this as ReferenceInstruction).reference.toString() == "Lcom/google/android/libraries/youtube/innertube/model/media/FormatStreamModel;"
} }
val arrayListIndex = getTargetIndexWithReferenceOrThrow( val arrayListIndex = indexOfFirstInstructionOrThrow(formatStreamModelIndex) {
formatStreamModelIndex, opcode == Opcode.INVOKE_INTERFACE &&
"Ljava/util/List;->add(Ljava/lang/Object;)Z" getReference<MethodReference>()?.toString() == "Ljava/util/List;->add(Ljava/lang/Object;)Z"
) }
val insertIndex = val insertIndex = indexOfFirstInstructionOrThrow(arrayListIndex) {
getTargetIndexWithReferenceOrThrow( opcode == Opcode.INVOKE_INTERFACE &&
arrayListIndex, getReference<MethodReference>()?.toString() == "Ljava/util/List;->isEmpty()Z"
"Ljava/util/List;->isEmpty()Z" } + 2
) + 2
val formatStreamModelRegister = val formatStreamModelRegister =
getInstruction<OneRegisterInstruction>(formatStreamModelIndex).registerA getInstruction<OneRegisterInstruction>(formatStreamModelIndex).registerA

View File

@ -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
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithMethodReferenceName import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode 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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction 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.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.util.MethodUtil import com.android.tools.smali.dexlib2.util.MethodUtil
@Suppress("unused") @Suppress("unused")
@ -171,10 +172,13 @@ object LayoutComponentsPatch : BaseBytecodePatch(
AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let { AccountSwitcherAccessibilityLabelFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(AccountSwitcherAccessibility) val constIndex =
val insertIndex = getTargetIndexOrThrow(constIndex, Opcode.IF_EQZ) indexOfFirstWideLiteralInstructionValueOrThrow(AccountSwitcherAccessibility)
val setVisibilityIndex = val insertIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.IF_EQZ)
getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility") val setVisibilityIndex = indexOfFirstInstructionOrThrow(insertIndex) {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setVisibility"
}
val visibilityRegister = val visibilityRegister =
getInstruction<FiveRegisterInstruction>(setVisibilityIndex).registerD getInstruction<FiveRegisterInstruction>(setVisibilityIndex).registerD
@ -209,8 +213,8 @@ object LayoutComponentsPatch : BaseBytecodePatch(
// region patch for hide tooltip content // region patch for hide tooltip content
TooltipContentFullscreenFingerprint.resultOrThrow().mutableMethod.apply { TooltipContentFullscreenFingerprint.resultOrThrow().mutableMethod.apply {
val literalIndex = getWideLiteralInstructionIndex(45384061) val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(45384061)
val targetIndex = getTargetIndexOrThrow(literalIndex, Opcode.MOVE_RESULT) val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.MOVE_RESULT)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(

View File

@ -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.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.getTargetIndexReversedOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -34,7 +33,7 @@ object LayoutSwitchPatch : BaseBytecodePatch(
GetFormFactorFingerprint.resultOrThrow().let { GetFormFactorFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val jumpIndex = getTargetIndexReversedOrThrow(Opcode.SGET_OBJECT) val jumpIndex = indexOfFirstInstructionReversedOrThrow(Opcode.SGET_OBJECT)
addInstructionsWithLabels( addInstructionsWithLabels(
0, """ 0, """
@ -56,7 +55,7 @@ object LayoutSwitchPatch : BaseBytecodePatch(
LayoutSwitchFingerprint.resultOrThrow().let { LayoutSwitchFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = getTargetIndexOrThrow(Opcode.IF_NEZ) val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.IF_NEZ)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions( addInstructions(

View File

@ -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.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
@Suppress("unused") @Suppress("unused")
@ -29,7 +29,7 @@ object GradientLoadingScreenPatch : BaseBytecodePatch(
GradientLoadingScreenPrimaryFingerprint to 45412406, GradientLoadingScreenPrimaryFingerprint to 45412406,
GradientLoadingScreenSecondaryFingerprint to 45418917 GradientLoadingScreenSecondaryFingerprint to 45418917
).forEach { (fingerprint, literal) -> ).forEach { (fingerprint, literal) ->
fingerprint.literalInstructionBooleanHook( fingerprint.injectLiteralInstructionBooleanCall(
literal, literal,
"$GENERAL_CLASS_DESCRIPTOR->enableGradientLoadingScreen()Z" "$GENERAL_CLASS_DESCRIPTOR->enableGradientLoadingScreen()Z"
) )

View File

@ -44,8 +44,8 @@ import app.revanced.util.fingerprint.LiteralValueFingerprint
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfWideLiteralInstructionOrThrow import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
@ -170,7 +170,7 @@ object MiniplayerPatch : BaseBytecodePatch(
} }
if (SettingsPatch.upward1925) { if (SettingsPatch.upward1925) {
MiniplayerModernEnabledFingerprint.literalInstructionBooleanHook( MiniplayerModernEnabledFingerprint.injectLiteralInstructionBooleanCall(
45622882, 45622882,
"$INTEGRATIONS_CLASS_DESCRIPTOR->getModernMiniplayerOverride(Z)Z" "$INTEGRATIONS_CLASS_DESCRIPTOR->getModernMiniplayerOverride(Z)Z"
) )
@ -181,11 +181,11 @@ object MiniplayerPatch : BaseBytecodePatch(
// region Enable double tap action. // region Enable double tap action.
if (SettingsPatch.upward1925) { if (SettingsPatch.upward1925) {
MiniplayerModernConstructorFingerprint.literalInstructionBooleanHook( MiniplayerModernConstructorFingerprint.injectLiteralInstructionBooleanCall(
45628823, 45628823,
"$INTEGRATIONS_CLASS_DESCRIPTOR->enableMiniplayerDoubleTapAction()Z" "$INTEGRATIONS_CLASS_DESCRIPTOR->enableMiniplayerDoubleTapAction()Z"
) )
MiniplayerModernConstructorFingerprint.literalInstructionBooleanHook( MiniplayerModernConstructorFingerprint.injectLiteralInstructionBooleanCall(
45630429, 45630429,
"$INTEGRATIONS_CLASS_DESCRIPTOR->getModernMiniplayerOverride(Z)Z" "$INTEGRATIONS_CLASS_DESCRIPTOR->getModernMiniplayerOverride(Z)Z"
) )
@ -211,7 +211,8 @@ object MiniplayerPatch : BaseBytecodePatch(
YtOutlinePictureInPictureWhite to YtOutlineXWhite, YtOutlinePictureInPictureWhite to YtOutlineXWhite,
YtOutlineXWhite to YtOutlinePictureInPictureWhite, YtOutlineXWhite to YtOutlinePictureInPictureWhite,
).forEach { (originalResource, replacementResource) -> ).forEach { (originalResource, replacementResource) ->
val imageResourceIndex = indexOfWideLiteralInstructionOrThrow(originalResource) val imageResourceIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(originalResource)
val register = val register =
getInstruction<OneRegisterInstruction>(imageResourceIndex).registerA getInstruction<OneRegisterInstruction>(imageResourceIndex).registerA
@ -321,7 +322,7 @@ object MiniplayerPatch : BaseBytecodePatch(
// region Enable drag and drop. // region Enable drag and drop.
if (SettingsPatch.upward1923) { if (SettingsPatch.upward1923) {
MiniplayerModernDragAndDropFingerprint.literalInstructionBooleanHook( MiniplayerModernDragAndDropFingerprint.injectLiteralInstructionBooleanCall(
45628752, 45628752,
"$INTEGRATIONS_CLASS_DESCRIPTOR->enableMiniplayerDragAndDrop()Z" "$INTEGRATIONS_CLASS_DESCRIPTOR->enableMiniplayerDragAndDrop()Z"
) )
@ -388,7 +389,7 @@ object MiniplayerPatch : BaseBytecodePatch(
) { ) {
resultOrThrow().mutableMethod.apply { resultOrThrow().mutableMethod.apply {
val imageViewIndex = indexOfFirstInstructionOrThrow( val imageViewIndex = indexOfFirstInstructionOrThrow(
indexOfWideLiteralInstructionOrThrow(literalValue) indexOfFirstWideLiteralInstructionValueOrThrow(literalValue)
) { ) {
opcode == Opcode.CHECK_CAST && getReference<TypeReference>()?.type == hookedClassType opcode == Opcode.CHECK_CAST && getReference<TypeReference>()?.type == hookedClassType
} }

View File

@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.general.miniplayer.fingerprints.MiniplayerModernConstructorFingerprint.constructorMethodCount import app.revanced.patches.youtube.general.miniplayer.fingerprints.MiniplayerModernConstructorFingerprint.constructorMethodCount
import app.revanced.patches.youtube.utils.settings.SettingsPatch 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.AccessFlags
import com.android.tools.smali.dexlib2.util.MethodUtil import com.android.tools.smali.dexlib2.util.MethodUtil
@ -13,7 +13,7 @@ internal object MiniplayerModernConstructorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L"), parameters = listOf("L"),
customFingerprint = custom@{ methodDef, classDef -> 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 return@custom false
classDef.methods.forEach { classDef.methods.forEach {
@ -24,8 +24,8 @@ internal object MiniplayerModernConstructorFingerprint : MethodFingerprint(
return@custom true return@custom true
// Double tap action (Used in YouTube 19.25.39+). // Double tap action (Used in YouTube 19.25.39+).
methodDef.containsWideLiteralInstructionIndex(45628823) methodDef.containsWideLiteralInstructionValue(45628823)
&& methodDef.containsWideLiteralInstructionIndex(45630429) && methodDef.containsWideLiteralInstructionValue(45630429)
} }
) { ) {
private var constructorMethodCount = 0 private var constructorMethodCount = 0

View File

@ -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.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.navigation.NavigationBarHookPatch import app.revanced.patches.youtube.utils.navigation.NavigationBarHookPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getStringInstructionIndex import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object NavigationBarComponentsPatch : BaseBytecodePatch( object NavigationBarComponentsPatch : BaseBytecodePatch(
@ -48,7 +51,7 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
// region patch for enable translucent navigation bar // region patch for enable translucent navigation bar
if (SettingsPatch.upward1923) { if (SettingsPatch.upward1923) {
TranslucentNavigationBarFingerprint.literalInstructionBooleanHook( TranslucentNavigationBarFingerprint.injectLiteralInstructionBooleanCall(
45630927, 45630927,
"$GENERAL_CLASS_DESCRIPTOR->enableTranslucentNavigationBar()Z" "$GENERAL_CLASS_DESCRIPTOR->enableTranslucentNavigationBar()Z"
) )
@ -85,7 +88,7 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
AutoMotiveFingerprint.resultOrThrow().let { AutoMotiveFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = getStringInstructionIndex("Android Automotive") - 1 val insertIndex = indexOfFirstStringInstructionOrThrow("Android Automotive") - 1
val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA val register = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions( addInstructions(
@ -103,7 +106,10 @@ object NavigationBarComponentsPatch : BaseBytecodePatch(
PivotBarSetTextFingerprint.resultOrThrow().let { PivotBarSetTextFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = getTargetIndexWithMethodReferenceNameOrThrow("setText") val targetIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setText"
}
val targetRegister = getInstruction<FiveRegisterInstruction>(targetIndex).registerC val targetRegister = getInstruction<FiveRegisterInstruction>(targetIndex).registerC
addInstruction( addInstruction(

View File

@ -2,13 +2,13 @@ package app.revanced.patches.youtube.general.splashanimation.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkSplashAnimation import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkSplashAnimation
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
internal object SplashAnimationFingerprint : MethodFingerprint( internal object SplashAnimationFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
parameters = listOf("Landroid/os/Bundle;"), parameters = listOf("Landroid/os/Bundle;"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.name == "onCreate" methodDef.name == "onCreate"
&& methodDef.containsWideLiteralInstructionIndex(DarkSplashAnimation) && methodDef.containsWideLiteralInstructionValue(DarkSplashAnimation)
} }
) )

View File

@ -2,7 +2,7 @@ package app.revanced.patches.youtube.general.splashanimation.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
internal object StartUpResourceIdFingerprint : MethodFingerprint( internal object StartUpResourceIdFingerprint : MethodFingerprint(
@ -10,7 +10,7 @@ internal object StartUpResourceIdFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("I"), parameters = listOf("I"),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(3) methodDef.containsWideLiteralInstructionValue(3)
&& methodDef.containsWideLiteralInstructionIndex(4) && methodDef.containsWideLiteralInstructionValue(4)
} }
) )

View File

@ -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.settings.SettingsPatch.contexts
import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.util.alsoResolve
import app.revanced.util.doRecursively import app.revanced.util.doRecursively
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
import app.revanced.util.getTargetIndexWithReferenceOrThrow
import app.revanced.util.getTargetIndexWithReferenceReversedOrThrow
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.literalInstructionHook import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.replaceLiteralInstructionCall
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import app.revanced.util.updatePatchStatus import app.revanced.util.updatePatchStatus
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -106,7 +106,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
YtPremiumWordMarkHeader, YtPremiumWordMarkHeader,
YtWordMarkHeader YtWordMarkHeader
).forEach { literal -> ).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. // 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. // The sidebar's header is lithoView. Add a listener to change it.
DrawerContentViewFingerprint.resolve( DrawerContentViewFingerprint.alsoResolve(
context, context, DrawerContentViewConstructorFingerprint
DrawerContentViewConstructorFingerprint.resultOrThrow().classDef ).let {
)
DrawerContentViewFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = getTargetIndexWithMethodReferenceNameOrThrow("addView") val insertIndex = DrawerContentViewFingerprint.indexOfAddViewInstruction(this)
val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
addInstruction( addInstruction(
@ -147,7 +145,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
setActionBarRingoMutableClass.methods.first { method -> setActionBarRingoMutableClass.methods.first { method ->
MethodUtil.isConstructor(method) MethodUtil.isConstructor(method)
}.apply { }.apply {
val insertIndex = getTargetIndexOrThrow(Opcode.IPUT_BOOLEAN) val insertIndex = indexOfFirstInstructionOrThrow(Opcode.IPUT_BOOLEAN)
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
addInstruction( addInstruction(
@ -172,7 +170,8 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
ActionBarRingoBackgroundFingerprint.resultOrThrow().let { ActionBarRingoBackgroundFingerprint.resultOrThrow().let {
ActionBarRingoTextFingerprint.resolve(context, it.classDef) ActionBarRingoTextFingerprint.resolve(context, it.classDef)
it.mutableMethod.apply { it.mutableMethod.apply {
val viewIndex = getWideLiteralInstructionIndex(ActionBarRingoBackground) + 2 val viewIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(ActionBarRingoBackground) + 2
val viewRegister = getInstruction<OneRegisterInstruction>(viewIndex).registerA val viewRegister = getInstruction<OneRegisterInstruction>(viewIndex).registerA
addInstructions( addInstructions(
@ -281,16 +280,16 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
CreateSearchSuggestionsFingerprint.resultOrThrow().let { result -> CreateSearchSuggestionsFingerprint.resultOrThrow().let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
val relativeIndex = getWideLiteralInstructionIndex(40) val relativeIndex = indexOfFirstWideLiteralInstructionValueOrThrow(40)
val replaceIndex = getTargetIndexWithReferenceReversedOrThrow( val replaceIndex = indexOfFirstInstructionReversedOrThrow(relativeIndex) {
relativeIndex, opcode == Opcode.INVOKE_VIRTUAL &&
"Landroid/widget/ImageView;->setVisibility(I)V" getReference<MethodReference>()?.toString() == "Landroid/widget/ImageView;->setVisibility(I)V"
) - 1 } - 1
val jumpIndex = getTargetIndexWithReferenceOrThrow( val jumpIndex = indexOfFirstInstructionOrThrow(relativeIndex) {
relativeIndex, opcode == Opcode.INVOKE_STATIC &&
"Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" getReference<MethodReference>()?.toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;"
) + 4 } + 4
val replaceIndexInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex) val replaceIndexInstruction = getInstruction<TwoRegisterInstruction>(replaceIndex)
val replaceIndexReference = val replaceIndexReference =
@ -313,7 +312,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
// region patch for hide voice search button // region patch for hide voice search button
if (SettingsPatch.upward1928) { if (SettingsPatch.upward1928) {
ImageSearchButtonConfigFingerprint.literalInstructionBooleanHook( ImageSearchButtonConfigFingerprint.injectLiteralInstructionBooleanCall(
45617544, 45617544,
"$GENERAL_CLASS_DESCRIPTOR->hideImageSearchButton(Z)Z" "$GENERAL_CLASS_DESCRIPTOR->hideImageSearchButton(Z)Z"
) )
@ -327,15 +326,15 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
// region patch for hide voice search button // region patch for hide voice search button
SearchBarFingerprint.resolve( SearchBarFingerprint.alsoResolve(
context, context, SearchBarParentFingerprint
SearchBarParentFingerprint.resultOrThrow().classDef ).let {
)
SearchBarFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex val startIndex = it.scanResult.patternScanResult!!.startIndex
val setVisibilityIndex = val setVisibilityIndex = indexOfFirstInstructionOrThrow(startIndex) {
getTargetIndexWithMethodReferenceNameOrThrow(startIndex, "setVisibility") opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setVisibility"
}
val setVisibilityInstruction = val setVisibilityInstruction =
getInstruction<FiveRegisterInstruction>(setVisibilityIndex) getInstruction<FiveRegisterInstruction>(setVisibilityIndex)
@ -349,12 +348,11 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
SearchResultFingerprint.resultOrThrow().let { SearchResultFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val startIndex = getWideLiteralInstructionIndex(VoiceSearch) val startIndex = indexOfFirstWideLiteralInstructionValueOrThrow(VoiceSearch)
val setOnClickListenerIndex = val setOnClickListenerIndex = indexOfFirstInstructionOrThrow(startIndex) {
getTargetIndexWithMethodReferenceNameOrThrow( opcode == Opcode.INVOKE_VIRTUAL &&
startIndex, getReference<MethodReference>()?.name == "setOnClickListener"
"setOnClickListener" }
)
val viewRegister = val viewRegister =
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC
@ -370,7 +368,7 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
// region patch for replace create button // region patch for replace create button
CreateButtonDrawableFingerprint.resultOrThrow().mutableMethod.apply { CreateButtonDrawableFingerprint.resultOrThrow().mutableMethod.apply {
val index = getWideLiteralInstructionIndex(YtOutlineVideoCamera) val index = indexOfFirstWideLiteralInstructionValueOrThrow(YtOutlineVideoCamera)
val register = getInstruction<OneRegisterInstruction>(index).registerA val register = getInstruction<OneRegisterInstruction>(index).registerA
addInstructions( addInstructions(

View File

@ -3,7 +3,7 @@ package app.revanced.patches.youtube.general.toolbar.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.general.toolbar.fingerprints.ActionBarRingoBackgroundFingerprint.indexOfStaticInstruction import app.revanced.patches.youtube.general.toolbar.fingerprints.ActionBarRingoBackgroundFingerprint.indexOfStaticInstruction
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.ActionBarRingoBackground 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.getReference
import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -13,7 +13,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal object ActionBarRingoBackgroundFingerprint : MethodFingerprint( internal object ActionBarRingoBackgroundFingerprint : MethodFingerprint(
returnType = "Landroid/view/View;", returnType = "Landroid/view/View;",
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(ActionBarRingoBackground) && methodDef.containsWideLiteralInstructionValue(ActionBarRingoBackground) &&
indexOfStaticInstruction(methodDef) >= 0 indexOfStaticInstruction(methodDef) >= 0
} }
) { ) {

View File

@ -1,9 +1,14 @@
package app.revanced.patches.youtube.general.toolbar.fingerprints 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.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", returnType = "V",
parameters = listOf("L"), parameters = listOf("L"),
opcodes = listOf( opcodes = listOf(
@ -12,5 +17,13 @@ internal object DrawerContentViewFingerprint : MethodReferenceNameFingerprint(
Opcode.NEW_INSTANCE, Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
), ),
reference = { "addView" } customFingerprint = { methodDef, _ ->
) indexOfAddViewInstruction(methodDef) >= 0
}
) {
fun indexOfAddViewInstruction(methodDef: Method) =
methodDef.indexOfFirstInstructionReversed {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "addView"
}
}

View File

@ -1,9 +1,12 @@
package app.revanced.patches.youtube.general.toolbar.fingerprints 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.Opcode
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object SearchBarFingerprint : MethodReferenceNameFingerprint( object SearchBarFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
parameters = listOf("Ljava/lang/String;"), parameters = listOf("Ljava/lang/String;"),
opcodes = listOf( opcodes = listOf(
@ -12,5 +15,9 @@ object SearchBarFingerprint : MethodReferenceNameFingerprint(
Opcode.IGET_BOOLEAN, Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ Opcode.IF_EQZ
), ),
reference = { "isEmpty" } customFingerprint = { methodDef, _ ->
methodDef.indexOfFirstInstructionReversed {
getReference<MethodReference>()?.name == "isEmpty"
} >= 0
}
) )

View File

@ -17,8 +17,24 @@ object TranslationsPatch : BaseResourcePatch(
) { ) {
// Array of supported translations, each represented by its language code. // Array of supported translations, each represented by its language code.
private val TRANSLATIONS = arrayOf( private val TRANSLATIONS = arrayOf(
"ar", "bg-rBG", "de-rDE", "el-rGR", "es-rES", "fr-rFR", "hu-rHU", "it-rIT", "ja-rJP", "ko-rKR", "ar",
"pl-rPL", "pt-rBR", "ru-rRU", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW" "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( private var CustomTranslations by stringPatchOption(

View File

@ -144,7 +144,8 @@ object VisualPreferencesIconsPatch : BaseResourcePatch(
else -> null else -> null
} }
if (drawableName == EMPTY_ICON && if (drawableName == EMPTY_ICON &&
ApplyToAll == false) return@loop ApplyToAll == false
) return@loop
drawableName?.let { drawableName?.let {
node.setAttribute("android:icon", "@drawable/$it") node.setAttribute("android:icon", "@drawable/$it")

View File

@ -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.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH import app.revanced.patches.youtube.utils.integrations.Constants.MISC_PATH
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object OpenLinksDirectlyPatch : BaseBytecodePatch( object OpenLinksDirectlyPatch : BaseBytecodePatch(
@ -32,7 +35,10 @@ object OpenLinksDirectlyPatch : BaseBytecodePatch(
).forEach { fingerprint -> ).forEach { fingerprint ->
fingerprint.resultOrThrow().let { fingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = getTargetIndexWithMethodReferenceNameOrThrow("parse") val insertIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_STATIC &&
getReference<MethodReference>()?.name == "parse"
}
val insertRegister = val insertRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC getInstruction<FiveRegisterInstruction>(insertIndex).registerC

View File

@ -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
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BottomSheetRecyclerView import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BottomSheetRecyclerView
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -46,8 +46,8 @@ object ShareSheetPatch : BaseBytecodePatch(
// Detects that the Share sheet panel has been invoked. // Detects that the Share sheet panel has been invoked.
BottomSheetRecyclerViewFingerprint.resultOrThrow().mutableMethod.apply { BottomSheetRecyclerViewFingerprint.resultOrThrow().mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(BottomSheetRecyclerView) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(BottomSheetRecyclerView)
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST) val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(

View File

@ -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.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getStringInstructionIndex import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.getTargetIndexReversedOrThrow import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -46,12 +46,12 @@ object AmbientModeSwitchPatch : BaseBytecodePatch(
).forEach { (fingerprint, reversed) -> ).forEach { (fingerprint, reversed) ->
fingerprint.resultOrThrow().mutableMethod.apply { fingerprint.resultOrThrow().mutableMethod.apply {
val stringIndex = val stringIndex =
getStringInstructionIndex("android.os.action.POWER_SAVE_MODE_CHANGED") indexOfFirstStringInstructionOrThrow("android.os.action.POWER_SAVE_MODE_CHANGED")
val targetIndex = val targetIndex =
if (reversed) if (reversed)
getTargetIndexReversedOrThrow(stringIndex, Opcode.INVOKE_DIRECT) indexOfFirstInstructionReversedOrThrow(stringIndex, Opcode.INVOKE_DIRECT)
else else
getTargetIndexOrThrow(stringIndex, Opcode.INVOKE_DIRECT) indexOfFirstInstructionOrThrow(stringIndex, Opcode.INVOKE_DIRECT)
val targetClass = val targetClass =
(getInstruction<ReferenceInstruction>(targetIndex).reference as MethodReference).definingClass (getInstruction<ReferenceInstruction>(targetIndex).reference as MethodReference).definingClass
@ -87,7 +87,7 @@ object AmbientModeSwitchPatch : BaseBytecodePatch(
// region patch for disable ambient mode in fullscreen // region patch for disable ambient mode in fullscreen
AmbientModeInFullscreenFingerprint.literalInstructionBooleanHook( AmbientModeInFullscreenFingerprint.injectLiteralInstructionBooleanCall(
45389368, 45389368,
"$PLAYER_CLASS_DESCRIPTOR->disableAmbientModeInFullscreen()Z" "$PLAYER_CLASS_DESCRIPTOR->disableAmbientModeInFullscreen()Z"
) )

View File

@ -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.PlayerCollapseButton
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TitleAnchor import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TitleAnchor
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -63,9 +63,10 @@ object PlayerButtonsPatch : BaseBytecodePatch(
LayoutConstructorFingerprint.resultOrThrow().let { LayoutConstructorFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(AutoNavToggle) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(AutoNavToggle)
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA 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( addInstructionsWithLabels(
constIndex, """ constIndex, """
@ -124,9 +125,9 @@ object PlayerButtonsPatch : BaseBytecodePatch(
// region patch for hide collapse button // region patch for hide collapse button
TitleAnchorFingerprint.resultOrThrow().mutableMethod.apply { TitleAnchorFingerprint.resultOrThrow().mutableMethod.apply {
val titleAnchorConstIndex = getWideLiteralInstructionIndex(TitleAnchor) val titleAnchorConstIndex = indexOfFirstWideLiteralInstructionValueOrThrow(TitleAnchor)
val titleAnchorIndex = val titleAnchorIndex =
getTargetIndexOrThrow(titleAnchorConstIndex, Opcode.MOVE_RESULT_OBJECT) indexOfFirstInstructionOrThrow(titleAnchorConstIndex, Opcode.MOVE_RESULT_OBJECT)
val titleAnchorRegister = val titleAnchorRegister =
getInstruction<OneRegisterInstruction>(titleAnchorIndex).registerA getInstruction<OneRegisterInstruction>(titleAnchorIndex).registerA
@ -136,9 +137,9 @@ object PlayerButtonsPatch : BaseBytecodePatch(
) )
val playerCollapseButtonConstIndex = val playerCollapseButtonConstIndex =
getWideLiteralInstructionIndex(PlayerCollapseButton) indexOfFirstWideLiteralInstructionValueOrThrow(PlayerCollapseButton)
val playerCollapseButtonIndex = val playerCollapseButtonIndex =
getTargetIndexOrThrow(playerCollapseButtonConstIndex, Opcode.CHECK_CAST) indexOfFirstInstructionOrThrow(playerCollapseButtonConstIndex, Opcode.CHECK_CAST)
val playerCollapseButtonRegister = val playerCollapseButtonRegister =
getInstruction<OneRegisterInstruction>(playerCollapseButtonIndex).registerA getInstruction<OneRegisterInstruction>(playerCollapseButtonIndex).registerA
@ -159,7 +160,7 @@ object PlayerButtonsPatch : BaseBytecodePatch(
(instruction.value as? WideLiteralInstruction)?.wideLiteral == FullScreenButton (instruction.value as? WideLiteralInstruction)?.wideLiteral == FullScreenButton
} }
val constIndex = buttonCalls.elementAt(buttonCalls.size - 1).index 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 insertIndex = castIndex + 1
val insertRegister = getInstruction<OneRegisterInstruction>(castIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(castIndex).registerA
@ -180,7 +181,7 @@ object PlayerButtonsPatch : BaseBytecodePatch(
PlayerControlsVisibilityModelFingerprint.resultOrThrow().let { PlayerControlsVisibilityModelFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val callIndex = getTargetIndexOrThrow(Opcode.INVOKE_DIRECT_RANGE) val callIndex = indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT_RANGE)
val callInstruction = getInstruction<Instruction3rc>(callIndex) val callInstruction = getInstruction<Instruction3rc>(callIndex)
val hasNextParameterRegister = callInstruction.startRegister + HAS_NEXT val hasNextParameterRegister = callInstruction.startRegister + HAS_NEXT

View File

@ -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.CfFullscreenButton
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FadeDurationFast import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FadeDurationFast
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.FullScreenButton 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 import com.android.tools.smali.dexlib2.AccessFlags
internal object FullScreenButtonFingerprint : MethodFingerprint( internal object FullScreenButtonFingerprint : MethodFingerprint(
@ -13,10 +13,10 @@ internal object FullScreenButtonFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Landroid/view/View;"), parameters = listOf("Landroid/view/View;"),
customFingerprint = handler@{ methodDef, _ -> customFingerprint = handler@{ methodDef, _ ->
if (!methodDef.containsWideLiteralInstructionIndex(FullScreenButton)) if (!methodDef.containsWideLiteralInstructionValue(FullScreenButton))
return@handler false return@handler false
methodDef.containsWideLiteralInstructionIndex(FadeDurationFast) // YouTube 18.29.38 ~ YouTube 19.18.41 methodDef.containsWideLiteralInstructionValue(FadeDurationFast) // YouTube 18.29.38 ~ YouTube 19.18.41
|| methodDef.containsWideLiteralInstructionIndex(CfFullscreenButton) // YouTube 19.19.39 ~ || methodDef.containsWideLiteralInstructionValue(CfFullscreenButton) // YouTube 19.19.39 ~
}, },
) )

View File

@ -3,12 +3,12 @@ package app.revanced.patches.youtube.player.buttons.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.PlayerCollapseButton import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.PlayerCollapseButton
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TitleAnchor import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TitleAnchor
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
internal object TitleAnchorFingerprint : MethodFingerprint( internal object TitleAnchorFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(PlayerCollapseButton) methodDef.containsWideLiteralInstructionValue(PlayerCollapseButton)
&& methodDef.containsWideLiteralInstructionIndex(TitleAnchor) && methodDef.containsWideLiteralInstructionValue(TitleAnchor)
} }
) )

View File

@ -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.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getTargetIndexOrThrow
import app.revanced.util.getWalkerMethod 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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -56,14 +56,15 @@ object CommentsComponentPatch : BaseBytecodePatch(
ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.resultOrThrow().let { ShortsLiveStreamEmojiPickerOnClickListenerFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val emojiPickerEndpointIndex = getWideLiteralInstructionIndex(126326492) val emojiPickerEndpointIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(126326492)
val emojiPickerOnClickListenerIndex = val emojiPickerOnClickListenerIndex =
getTargetIndexOrThrow(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT) indexOfFirstInstructionOrThrow(emojiPickerEndpointIndex, Opcode.INVOKE_DIRECT)
val emojiPickerOnClickListenerMethod = val emojiPickerOnClickListenerMethod =
getWalkerMethod(context, emojiPickerOnClickListenerIndex) getWalkerMethod(context, emojiPickerOnClickListenerIndex)
emojiPickerOnClickListenerMethod.apply { emojiPickerOnClickListenerMethod.apply {
val insertIndex = getTargetIndexOrThrow(Opcode.IF_EQZ) val insertIndex = indexOfFirstInstructionOrThrow(Opcode.IF_EQZ)
val insertRegister = val insertRegister =
getInstruction<OneRegisterInstruction>(insertIndex).registerA getInstruction<OneRegisterInstruction>(insertIndex).registerA

View File

@ -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.utils.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexReversedOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.literalInstructionViewHook import app.revanced.util.injectLiteralInstructionViewCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode 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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction 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.instruction.WideLiteralInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object PlayerComponentsPatch : BaseBytecodePatch( object PlayerComponentsPatch : BaseBytecodePatch(
@ -107,8 +108,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
YouTubeControlsOverlayFingerprint.resultOrThrow().let { YouTubeControlsOverlayFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(ScrimOverlay) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(ScrimOverlay)
val targetIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST) val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
val targetParameter = getInstruction<ReferenceInstruction>(targetIndex).reference val targetParameter = getInstruction<ReferenceInstruction>(targetIndex).reference
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
@ -144,7 +145,8 @@ object PlayerComponentsPatch : BaseBytecodePatch(
if (fingerprint == StartVideoInformerFingerprint) { if (fingerprint == StartVideoInformerFingerprint) {
hookInitVideoPanel(1) hookInitVideoPanel(1)
} else { } else {
val syntheticIndex = getTargetIndexOrThrow(Opcode.NEW_INSTANCE) val syntheticIndex =
indexOfFirstInstructionOrThrow(opcode = Opcode.NEW_INSTANCE)
val syntheticReference = val syntheticReference =
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString() getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
val syntheticClass = val syntheticClass =
@ -228,7 +230,7 @@ object PlayerComponentsPatch : BaseBytecodePatch(
DarkBackground, DarkBackground,
TapBloomView TapBloomView
).forEach { literal -> ).forEach { literal ->
QuickSeekOverlayFingerprint.literalInstructionViewHook( QuickSeekOverlayFingerprint.injectLiteralInstructionViewCall(
literal, literal,
smaliInstruction smaliInstruction
) )
@ -273,10 +275,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
YouTubeControlsOverlayFingerprint.resultOrThrow().let { YouTubeControlsOverlayFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(FadeDurationFast) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(FadeDurationFast)
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
val insertIndex = val insertIndex =
getTargetIndexReversedOrThrow(constIndex, Opcode.INVOKE_VIRTUAL) + 1 indexOfFirstInstructionReversedOrThrow(constIndex, Opcode.INVOKE_VIRTUAL) + 1
val jumpIndex = implementation!!.instructions.let { instruction -> val jumpIndex = implementation!!.instructions.let { instruction ->
insertIndex + instruction.subList(insertIndex, instruction.size - 1) insertIndex + instruction.subList(insertIndex, instruction.size - 1)
.indexOfFirst { instructions -> .indexOfFirst { instructions ->
@ -341,11 +343,14 @@ object PlayerComponentsPatch : BaseBytecodePatch(
YouTubeControlsOverlayFingerprint.resultOrThrow().let { result -> YouTubeControlsOverlayFingerprint.resultOrThrow().let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
val insertIndex = getWideLiteralInstructionIndex(SeekUndoEduOverlayStub) val insertIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(SeekUndoEduOverlayStub)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val onClickListenerIndex = val onClickListenerIndex = indexOfFirstInstructionOrThrow(insertIndex) {
getTargetIndexWithMethodReferenceNameOrThrow(insertIndex, "setOnClickListener") opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setOnClickListener"
}
val constComponent = getConstComponent(insertIndex, onClickListenerIndex - 1) val constComponent = getConstComponent(insertIndex, onClickListenerIndex - 1)
if (constComponent.isNotEmpty()) { if (constComponent.isNotEmpty()) {
@ -390,8 +395,10 @@ object PlayerComponentsPatch : BaseBytecodePatch(
it.mutableClass.methods.find { method -> it.mutableClass.methods.find { method ->
method.parameters == listOf("Landroid/view/View${'$'}OnClickListener;") method.parameters == listOf("Landroid/view/View${'$'}OnClickListener;")
}?.apply { }?.apply {
val setOnClickListenerIndex = val setOnClickListenerIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithMethodReferenceNameOrThrow("setOnClickListener") opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setOnClickListener"
}
val setOnClickListenerRegister = val setOnClickListenerRegister =
getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC getInstruction<FiveRegisterInstruction>(setOnClickListenerIndex).registerC

View File

@ -3,13 +3,13 @@ package app.revanced.patches.youtube.player.components.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkBackground import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.DarkBackground
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TapBloomView import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TapBloomView
import app.revanced.util.containsWideLiteralInstructionIndex import app.revanced.util.containsWideLiteralInstructionValue
internal object QuickSeekOverlayFingerprint : MethodFingerprint( internal object QuickSeekOverlayFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
parameters = emptyList(), parameters = emptyList(),
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(DarkBackground) methodDef.containsWideLiteralInstructionValue(DarkBackground)
&& methodDef.containsWideLiteralInstructionIndex(TapBloomView) && methodDef.containsWideLiteralInstructionValue(TapBloomView)
}, },
) )

View File

@ -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.recyclerview.BottomSheetRecyclerViewPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch 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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object DescriptionComponentsPatch : BaseBytecodePatch( object DescriptionComponentsPatch : BaseBytecodePatch(
@ -54,16 +58,16 @@ object DescriptionComponentsPatch : BaseBytecodePatch(
// In order to maintain compatibility with YouTube v18.48.39 or previous versions, // 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. // This patch is applied only to the version after YouTube v18.49.37.
if (SettingsPatch.upward1849) { if (SettingsPatch.upward1849) {
RollingNumberTextViewAnimationUpdateFingerprint.resolve( RollingNumberTextViewAnimationUpdateFingerprint.alsoResolve(
context, context, RollingNumberTextViewFingerprint
RollingNumberTextViewFingerprint.resultOrThrow().classDef ).let {
)
RollingNumberTextViewAnimationUpdateFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val freeRegister = implementation!!.registerCount - parameters.size - 2 val freeRegister = implementation!!.registerCount - parameters.size - 2
val imageSpanIndex = it.scanResult.patternScanResult!!.startIndex val imageSpanIndex = it.scanResult.patternScanResult!!.startIndex
val setTextIndex = getTargetIndexWithMethodReferenceNameOrThrow("setText") val setTextIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setText"
}
addInstruction(setTextIndex, "nop") addInstruction(setTextIndex, "nop")
addInstructionsWithLabels( addInstructionsWithLabels(
imageSpanIndex, """ imageSpanIndex, """
@ -106,13 +110,11 @@ object DescriptionComponentsPatch : BaseBytecodePatch(
} }
} }
EngagementPanelTitleFingerprint.resolve( EngagementPanelTitleFingerprint.alsoResolve(
context, context, EngagementPanelTitleParentFingerprint
EngagementPanelTitleParentFingerprint.resultOrThrow().classDef ).mutableMethod.apply {
) val contentDescriptionIndex = EngagementPanelTitleFingerprint
EngagementPanelTitleFingerprint.resultOrThrow().mutableMethod.apply { .indexOfContentDescriptionInstruction(this)
val contentDescriptionIndex =
getTargetIndexWithMethodReferenceNameOrThrow("setContentDescription")
val contentDescriptionRegister = val contentDescriptionRegister =
getInstruction<FiveRegisterInstruction>(contentDescriptionIndex).registerD getInstruction<FiveRegisterInstruction>(contentDescriptionIndex).registerD

View File

@ -1,8 +1,22 @@
package app.revanced.patches.youtube.player.descriptions.fingerprints 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(". "), strings = listOf(". "),
reference = { "setContentDescription" } customFingerprint = { methodDef, _ ->
) indexOfContentDescriptionInstruction(methodDef) >= 0
}
) {
fun indexOfContentDescriptionInstruction(methodDef: Method) =
methodDef.indexOfFirstInstructionReversed {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "setContentDescription"
}
}

View File

@ -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.resourceid.SharedResourceIdPatch.BottomSheetFooterText
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow import app.revanced.util.getReference
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.literalInstructionViewHook import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.injectLiteralInstructionViewCall
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow 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.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object PlayerFlyoutMenuPatch : BaseBytecodePatch( object PlayerFlyoutMenuPatch : BaseBytecodePatch(
@ -56,7 +59,7 @@ object PlayerFlyoutMenuPatch : BaseBytecodePatch(
val smaliInstruction = """ val smaliInstruction = """
invoke-static {v$REGISTER_TEMPLATE_REPLACEMENT}, $PLAYER_CLASS_DESCRIPTOR->$name(Landroid/view/View;)V invoke-static {v$REGISTER_TEMPLATE_REPLACEMENT}, $PLAYER_CLASS_DESCRIPTOR->$name(Landroid/view/View;)V
""" """
fingerprint.literalInstructionViewHook(BottomSheetFooterText, smaliInstruction) fingerprint.injectLiteralInstructionViewCall(BottomSheetFooterText, smaliInstruction)
} }
arrayOf( arrayOf(
@ -64,12 +67,14 @@ object PlayerFlyoutMenuPatch : BaseBytecodePatch(
QualityMenuViewInflateFingerprint QualityMenuViewInflateFingerprint
).forEach { fingerprint -> ).forEach { fingerprint ->
fingerprint.resultOrThrow().mutableMethod.apply { 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 val insertRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
addInstructions( addInstructions(
insertIndex, insertIndex, """
"""
invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hidePlayerFlyoutMenuQualityHeader(Landroid/view/View;)Landroid/view/View; invoke-static {v$insertRegister}, $PLAYER_CLASS_DESCRIPTOR->hidePlayerFlyoutMenuQualityHeader(Landroid/view/View;)Landroid/view/View;
move-result-object v$insertRegister move-result-object v$insertRegister
""" """
@ -95,7 +100,7 @@ object PlayerFlyoutMenuPatch : BaseBytecodePatch(
SettingsPatch.updatePatchStatus(this) SettingsPatch.updatePatchStatus(this)
if (SettingsPatch.upward1839) { if (SettingsPatch.upward1839) {
PiPModeConfigFingerprint.literalInstructionBooleanHook( PiPModeConfigFingerprint.injectLiteralInstructionBooleanCall(
45427407, 45427407,
"$PLAYER_CLASS_DESCRIPTOR->hidePiPModeMenu(Z)Z" "$PLAYER_CLASS_DESCRIPTOR->hidePiPModeMenu(Z)Z"
) )

View File

@ -4,13 +4,13 @@ import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BottomSheetFooterText import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.BottomSheetFooterText
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.SubtitleMenuSettingsFooterInfo 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 import com.android.tools.smali.dexlib2.AccessFlags
internal object CaptionsBottomSheetFingerprint : MethodFingerprint( internal object CaptionsBottomSheetFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.containsWideLiteralInstructionIndex(BottomSheetFooterText) methodDef.containsWideLiteralInstructionValue(BottomSheetFooterText)
&& methodDef.containsWideLiteralInstructionIndex(SubtitleMenuSettingsFooterInfo) && methodDef.containsWideLiteralInstructionValue(SubtitleMenuSettingsFooterInfo)
} }
) )

View File

@ -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.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getReference 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.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow 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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -139,13 +138,15 @@ object ChangeTogglePatch : BaseBytecodePatch(
} }
val classRegister = getInstruction<TwoRegisterInstruction>(iGetIndex).registerB 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 = val iGetObjectPrimaryIndex =
getTargetIndexReversedOrThrow(checkCastIndex, Opcode.IGET_OBJECT) indexOfFirstInstructionReversedOrThrow(checkCastIndex, Opcode.IGET_OBJECT)
val iGetObjectSecondaryIndex = val iGetObjectSecondaryIndex =
getTargetIndexOrThrow(checkCastIndex, Opcode.IGET_OBJECT) indexOfFirstInstructionOrThrow(checkCastIndex, Opcode.IGET_OBJECT)
val checkCastReference = val checkCastReference =
getInstruction<ReferenceInstruction>(checkCastIndex).reference getInstruction<ReferenceInstruction>(checkCastIndex).reference
@ -154,14 +155,15 @@ object ChangeTogglePatch : BaseBytecodePatch(
val iGetObjectSecondaryReference = val iGetObjectSecondaryReference =
getInstruction<ReferenceInstruction>(iGetObjectSecondaryIndex).reference getInstruction<ReferenceInstruction>(iGetObjectSecondaryIndex).reference
val invokeVirtualIndex = getTargetIndexOrThrow(stringIndex, Opcode.INVOKE_VIRTUAL) val invokeVirtualIndex =
indexOfFirstInstructionOrThrow(stringIndex, Opcode.INVOKE_VIRTUAL)
val invokeVirtualInstruction = val invokeVirtualInstruction =
getInstruction<FiveRegisterInstruction>(invokeVirtualIndex) getInstruction<FiveRegisterInstruction>(invokeVirtualIndex)
val freeRegisterC = invokeVirtualInstruction.registerC val freeRegisterC = invokeVirtualInstruction.registerC
val freeRegisterD = invokeVirtualInstruction.registerD val freeRegisterD = invokeVirtualInstruction.registerD
val freeRegisterE = invokeVirtualInstruction.registerE val freeRegisterE = invokeVirtualInstruction.registerE
val insertIndex = getTargetIndexOrThrow(stringIndex, Opcode.RETURN_VOID) val insertIndex = indexOfFirstInstructionOrThrow(stringIndex, Opcode.RETURN_VOID)
addInstructionsWithLabels( addInstructionsWithLabels(
insertIndex, """ insertIndex, """

View File

@ -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.resourceid.SharedResourceIdPatch.QuickActionsElementContainer
import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getReference 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.getWalkerMethod
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow 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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import app.revanced.util.updatePatchStatus import app.revanced.util.updatePatchStatus
@ -80,8 +78,9 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
EngagementPanelFingerprint.resultOrThrow().let { EngagementPanelFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val literalIndex = getWideLiteralInstructionIndex(FullScreenEngagementPanel) val literalIndex =
val targetIndex = getTargetIndexOrThrow(literalIndex, Opcode.CHECK_CAST) indexOfFirstWideLiteralInstructionValueOrThrow(FullScreenEngagementPanel)
val targetIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.CHECK_CAST)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstruction( addInstruction(
@ -94,7 +93,10 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
PlayerTitleViewFingerprint.resultOrThrow().let { PlayerTitleViewFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = getTargetIndexWithMethodReferenceNameOrThrow("addView") val insertIndex = indexOfFirstInstructionOrThrow {
opcode == Opcode.INVOKE_VIRTUAL &&
getReference<MethodReference>()?.name == "addView"
}
val insertReference = val insertReference =
getInstruction<ReferenceInstruction>(insertIndex).reference.toString() getInstruction<ReferenceInstruction>(insertIndex).reference.toString()
if (!insertReference.startsWith("Landroid/widget/FrameLayout;")) if (!insertReference.startsWith("Landroid/widget/FrameLayout;"))
@ -115,9 +117,10 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
LayoutConstructorFingerprint.resultOrThrow().let { LayoutConstructorFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(AutoNavPreviewStub) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(AutoNavPreviewStub)
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA 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( addInstructionsWithLabels(
constIndex, """ constIndex, """
@ -159,7 +162,7 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
} }
val constIndex = containerCalls.elementAt(containerCalls.size - 1).index val constIndex = containerCalls.elementAt(containerCalls.size - 1).index
val checkCastIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST) val checkCastIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
val insertRegister = val insertRegister =
getInstruction<OneRegisterInstruction>(checkCastIndex).registerA getInstruction<OneRegisterInstruction>(checkCastIndex).registerA
@ -183,9 +186,11 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
YouTubeControlsOverlayFingerprint.resultOrThrow().let { YouTubeControlsOverlayFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = val targetIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithMethodReferenceNameOrThrow("setFocusableInTouchMode") opcode == Opcode.INVOKE_VIRTUAL &&
val walkerIndex = getTargetIndexOrThrow(targetIndex, Opcode.INVOKE_STATIC) getReference<MethodReference>()?.name == "setFocusableInTouchMode"
}
val walkerIndex = indexOfFirstInstructionOrThrow(targetIndex, Opcode.INVOKE_STATIC)
val walkerMethod = getWalkerMethod(context, walkerIndex) val walkerMethod = getWalkerMethod(context, walkerIndex)
walkerMethod.apply { walkerMethod.apply {
@ -209,14 +214,14 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
ClientSettingEndpointFingerprint.resultOrThrow().let { ClientSettingEndpointFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val getActivityIndex = getStringInstructionIndex("watch") + 2 val getActivityIndex = indexOfFirstStringInstructionOrThrow("watch") + 2
val getActivityReference = val getActivityReference =
getInstruction<ReferenceInstruction>(getActivityIndex).reference getInstruction<ReferenceInstruction>(getActivityIndex).reference
val classRegister = val classRegister =
getInstruction<TwoRegisterInstruction>(getActivityIndex).registerB getInstruction<TwoRegisterInstruction>(getActivityIndex).registerB
val watchDescriptorMethodIndex = val watchDescriptorMethodIndex =
getStringInstructionIndex("start_watch_minimized") - 1 indexOfFirstStringInstructionOrThrow("start_watch_minimized") - 1
val watchDescriptorRegister = val watchDescriptorRegister =
getInstruction<FiveRegisterInstruction>(watchDescriptorMethodIndex).registerD getInstruction<FiveRegisterInstruction>(watchDescriptorMethodIndex).registerD
@ -228,7 +233,7 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
) )
// hooks Activity. // hooks Activity.
val insertIndex = getStringInstructionIndex("force_fullscreen") val insertIndex = indexOfFirstStringInstructionOrThrow("force_fullscreen")
val freeRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val freeRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions( addInstructions(
@ -244,9 +249,10 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
VideoPortraitParentFingerprint.resultOrThrow().let { VideoPortraitParentFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val stringIndex = val stringIndex =
getStringInstructionIndex("Acquiring NetLatencyActionLogger failed. taskId=") indexOfFirstStringInstructionOrThrow("Acquiring NetLatencyActionLogger failed. taskId=")
val invokeIndex = getTargetIndexOrThrow(stringIndex, Opcode.INVOKE_INTERFACE) val invokeIndex =
val targetIndex = getTargetIndexOrThrow(invokeIndex, Opcode.CHECK_CAST) indexOfFirstInstructionOrThrow(stringIndex, Opcode.INVOKE_INTERFACE)
val targetIndex = indexOfFirstInstructionOrThrow(invokeIndex, Opcode.CHECK_CAST)
val targetClass = context val targetClass = context
.findClass(getInstruction<ReferenceInstruction>(targetIndex).reference.toString())!! .findClass(getInstruction<ReferenceInstruction>(targetIndex).reference.toString())!!
.mutableClass .mutableClass
@ -328,8 +334,9 @@ object FullscreenComponentsPatch : BaseBytecodePatch(
BroadcastReceiverFingerprint.resultOrThrow().let { result -> BroadcastReceiverFingerprint.resultOrThrow().let { result ->
result.mutableMethod.apply { result.mutableMethod.apply {
val stringIndex = val stringIndex =
getStringInstructionIndex("android.intent.action.SCREEN_ON") indexOfFirstStringInstructionOrThrow("android.intent.action.SCREEN_ON")
val insertIndex = getTargetIndexOrThrow(stringIndex, Opcode.IF_EQZ) + 1 val insertIndex =
indexOfFirstInstructionOrThrow(stringIndex, Opcode.IF_EQZ) + 1
addInstruction( addInstruction(
insertIndex, insertIndex,

View File

@ -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.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.settings.SettingsPatch 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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@ -65,7 +65,7 @@ object HapticFeedBackPatch : BaseBytecodePatch(
var register = 0 var register = 0
if (name == "run") { if (name == "run") {
index = getTargetIndexOrThrow(Opcode.SGET) index = indexOfFirstInstructionOrThrow(Opcode.SGET)
register = getInstruction<OneRegisterInstruction>(index).registerA register = getInstruction<OneRegisterInstruction>(index).registerA
} }

View File

@ -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
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexWithMethodReferenceNameOrThrow
import app.revanced.util.getWalkerMethod import app.revanced.util.getWalkerMethod
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstInstructionOrThrow
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.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode 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.NarrowLiteralInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction 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.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import org.w3c.dom.Element import org.w3c.dom.Element
@Suppress("DEPRECATION", "unused") @Suppress("DEPRECATION", "unused")
@ -139,11 +140,14 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
TotalTimeFingerprint.resultOrThrow().let { TotalTimeFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val charSequenceIndex = val charSequenceIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithMethodReferenceNameOrThrow("getString") + 1 getReference<MethodReference>()?.name == "getString"
} + 1
val charSequenceRegister = val charSequenceRegister =
getInstruction<OneRegisterInstruction>(charSequenceIndex).registerA getInstruction<OneRegisterInstruction>(charSequenceIndex).registerA
val textViewIndex = getTargetIndexWithMethodReferenceNameOrThrow("getText") val textViewIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "getText"
}
val textViewRegister = val textViewRegister =
getInstruction<FiveRegisterInstruction>(textViewIndex).registerC getInstruction<FiveRegisterInstruction>(textViewIndex).registerC
@ -162,12 +166,12 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
// region patch for seekbar color // region patch for seekbar color
PlayerSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply { PlayerSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply {
hook(getWideLiteralInstructionIndex(InlineTimeBarColorizedBarPlayedColorDark) + 2) hook(InlineTimeBarColorizedBarPlayedColorDark)
hook(getWideLiteralInstructionIndex(InlineTimeBarPlayedNotHighlightedColor) + 2) hook(InlineTimeBarPlayedNotHighlightedColor)
} }
ShortsSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply { ShortsSeekbarColorFingerprint.resultOrThrow().mutableMethod.apply {
hook(getWideLiteralInstructionIndex(ReelTimeBarPlayedColor) + 2) hook(ReelTimeBarPlayedColor)
} }
ControlsOverlayStyleFingerprint.resultOrThrow().let { ControlsOverlayStyleFingerprint.resultOrThrow().let {
@ -212,7 +216,7 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
PlayerButtonsVisibilityFingerprint.resultOrThrow().let { PlayerButtonsVisibilityFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val freeRegister = implementation!!.registerCount - parameters.size - 2 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 val viewRegister = getInstruction<FiveRegisterInstruction>(viewIndex).registerD
addInstructionsWithLabels( addInstructionsWithLabels(
@ -271,7 +275,7 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
// region patch for restore old seekbar thumbnails // region patch for restore old seekbar thumbnails
ThumbnailPreviewConfigFingerprint.result?.let { ThumbnailPreviewConfigFingerprint.result?.let {
ThumbnailPreviewConfigFingerprint.literalInstructionBooleanHook( ThumbnailPreviewConfigFingerprint.injectLiteralInstructionBooleanCall(
45398577, 45398577,
"$PLAYER_CLASS_DESCRIPTOR->restoreOldSeekbarThumbnails()Z" "$PLAYER_CLASS_DESCRIPTOR->restoreOldSeekbarThumbnails()Z"
) )
@ -285,7 +289,7 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
// region patch for enable cairo seekbar // region patch for enable cairo seekbar
if (SettingsPatch.upward1923) { if (SettingsPatch.upward1923) {
CairoSeekbarConfigFingerprint.literalInstructionBooleanHook( CairoSeekbarConfigFingerprint.injectLiteralInstructionBooleanCall(
45617850, 45617850,
"$PLAYER_CLASS_DESCRIPTOR->enableCairoSeekbar()Z" "$PLAYER_CLASS_DESCRIPTOR->enableCairoSeekbar()Z"
) )
@ -303,7 +307,8 @@ object SeekbarComponentsPatch : BaseBytecodePatch(
SettingsPatch.updatePatchStatus(this) 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 val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstructions( addInstructions(

View File

@ -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.RestoreSlideToSeekBehaviorFingerprint
import app.revanced.patches.youtube.player.speedoverlay.fingerprints.SlideToSeekMotionEventFingerprint 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.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.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.integrations.Constants.PLAYER_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.util.alsoResolve
import app.revanced.util.getReference 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.indexOfFirstInstructionOrThrow
import app.revanced.util.literalInstructionBooleanHook import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.injectLiteralInstructionBooleanCall
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction 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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction 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.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.util.MethodUtil
@Patch(dependencies = [SharedResourceIdPatch::class]) @Patch(dependencies = [SharedResourceIdPatch::class])
object SpeedOverlayPatch : BytecodePatch( object SpeedOverlayPatch : BytecodePatch(
@ -43,8 +42,8 @@ object SpeedOverlayPatch : BytecodePatch(
NextGenWatchLayoutFingerprint, NextGenWatchLayoutFingerprint,
RestoreSlideToSeekBehaviorFingerprint, RestoreSlideToSeekBehaviorFingerprint,
SpeedOverlayFingerprint, SpeedOverlayFingerprint,
SpeedOverlayFloatValueFingerprint,
SpeedOverlayTextValueFingerprint, SpeedOverlayTextValueFingerprint,
SpeedOverlayValueFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
@ -52,36 +51,33 @@ object SpeedOverlayPatch : BytecodePatch(
val restoreSlideToSeekBehaviorFingerprintResult = val restoreSlideToSeekBehaviorFingerprintResult =
RestoreSlideToSeekBehaviorFingerprint.result RestoreSlideToSeekBehaviorFingerprint.result
val speedOverlayFingerprintResult = SpeedOverlayFingerprint.result val speedOverlayFingerprintResult = SpeedOverlayFingerprint.result
val speedOverlayValueFingerprintResult = SpeedOverlayValueFingerprint.result val speedOverlayFloatValueFingerprintResult = SpeedOverlayFloatValueFingerprint.result
val resolvable = val resolvable =
restoreSlideToSeekBehaviorFingerprintResult != null restoreSlideToSeekBehaviorFingerprintResult != null
&& speedOverlayFingerprintResult != null && speedOverlayFingerprintResult != null
&& speedOverlayValueFingerprintResult != null && speedOverlayFloatValueFingerprintResult != null
if (resolvable) { if (resolvable) {
// Legacy method.
// Used on YouTube 18.29.38 ~ YouTube 19.17.41 // 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( mapOf(
RestoreSlideToSeekBehaviorFingerprint to 45411329, RestoreSlideToSeekBehaviorFingerprint to 45411329,
SpeedOverlayFingerprint to 45411330 SpeedOverlayFingerprint to 45411330
).forEach { (fingerprint, literal) -> ).forEach { (fingerprint, literal) ->
fingerprint.result!!.let { fingerprint.injectLiteralInstructionBooleanCall(
fingerprint.literalInstructionBooleanHook(
literal, literal,
"$PLAYER_CLASS_DESCRIPTOR->disableSpeedOverlay(Z)Z" "$PLAYER_CLASS_DESCRIPTOR->disableSpeedOverlay(Z)Z"
) )
} }
}
// endregion // endregion
// region patch for custom speed overlay value // region patch for Custom speed overlay float value
speedOverlayValueFingerprintResult!!.let { speedOverlayFloatValueFingerprintResult!!.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val index = it.scanResult.patternScanResult!!.startIndex val index = it.scanResult.patternScanResult!!.startIndex
val register = getInstruction<TwoRegisterInstruction>(index).registerA val register = getInstruction<TwoRegisterInstruction>(index).registerA
@ -98,13 +94,18 @@ object SpeedOverlayPatch : BytecodePatch(
// endregion // endregion
} else { } else {
// New method.
// Used on YouTube 19.18.41~ // Used on YouTube 19.18.41~
NextGenWatchLayoutFingerprint.resultOrThrow().mutableMethod.apply { // region patch for Disable speed overlay (Enable slide to seek)
val booleanValueIndex = getTargetIndexWithMethodReferenceNameOrThrow("booleanValue")
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 insertInstruction = getInstruction<TwoRegisterInstruction>(insertIndex)
val insertReference = getInstruction<ReferenceInstruction>(insertIndex).reference val insertReference = getInstruction<ReferenceInstruction>(insertIndex).reference
@ -113,77 +114,107 @@ object SpeedOverlayPatch : BytecodePatch(
"iget-object v${insertInstruction.registerA}, v${insertInstruction.registerB}, $insertReference" "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) hook(insertIndex + 1, insertInstruction.registerA, jumpIndex)
} }
SlideToSeekMotionEventFingerprint.resolve( val (slideToSeekBooleanMethod, slideToSeekSyntheticMethod) =
context, SlideToSeekMotionEventFingerprint.alsoResolve(
HorizontalTouchOffsetConstructorFingerprint.resultOrThrow().classDef context, HorizontalTouchOffsetConstructorFingerprint
) ).let {
SlideToSeekMotionEventFingerprint.resultOrThrow().let { with(it.mutableMethod) {
it.mutableMethod.apply {
val scanResult = it.scanResult.patternScanResult!! val scanResult = it.scanResult.patternScanResult!!
val slideToSeekBooleanIndex = scanResult.startIndex + 1
slideToSeekBooleanMethod = getWalkerMethod(context, slideToSeekBooleanIndex)
val jumpIndex = scanResult.endIndex + 1 val jumpIndex = scanResult.endIndex + 1
val insertIndex = scanResult.endIndex - 1 val insertIndex = scanResult.endIndex - 1
val insertRegister = val insertRegister =
getInstruction<TwoRegisterInstruction>(insertIndex).registerA getInstruction<TwoRegisterInstruction>(insertIndex).registerA
hook(insertIndex, insertRegister, jumpIndex) 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 { slideToSeekBooleanMethod.apply {
var insertIndex = getTargetIndexOrThrow(Opcode.IGET_OBJECT) val insertIndex = indexOfFirstInstructionOrThrow {
var insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA opcode == Opcode.IGET_OBJECT
var jumpIndex = getTargetIndexReversedOrThrow(Opcode.INVOKE_VIRTUAL) }
val insertRegister = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
val jumpIndex = indexOfFirstInstructionReversedOrThrow {
opcode == Opcode.INVOKE_VIRTUAL
}
hook(insertIndex, insertRegister, jumpIndex) hook(insertIndex, insertRegister, jumpIndex)
}
val constructorMethod = slideToSeekSyntheticMethod.apply {
context.findClass(definingClass)?.mutableClass val speedOverlayFloatValueIndex = indexOfFirstInstructionOrThrow {
?.methods?.find { method -> method.name == "<init>" } (this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits()
?: throw PatchException("Could not find constructor method") }
val insertIndex =
indexOfFirstInstructionReversedOrThrow(speedOverlayFloatValueIndex) {
getReference<MethodReference>()?.name == "removeCallbacks"
} + 1
val insertRegister =
getInstruction<FiveRegisterInstruction>(insertIndex - 1).registerC
val jumpIndex =
indexOfFirstInstructionOrThrow(
speedOverlayFloatValueIndex,
Opcode.RETURN_VOID
) + 1
constructorMethod.apply { hook(insertIndex, insertRegister, jumpIndex)
val syntheticIndex = getTargetIndexReversedOrThrow(Opcode.NEW_INSTANCE) }
val syntheticClass =
getInstruction<ReferenceInstruction>(syntheticIndex).reference.toString()
val syntheticMethod = // endregion
context.findClass(syntheticClass)?.mutableClass
?.methods?.find { method -> method.name == "run" }
?: throw PatchException("Could not find synthetic method")
syntheticMethod.apply { // region patch for Custom speed overlay float value
val speedOverlayValueIndex =
indexOfFirstInstructionOrThrow { (this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits() } slideToSeekSyntheticMethod.apply {
val speedOverlayValueRegister = val speedOverlayFloatValueIndex = indexOfFirstInstructionOrThrow {
getInstruction<OneRegisterInstruction>(speedOverlayValueIndex).registerA (this as? NarrowLiteralInstruction)?.narrowLiteral == 2.0f.toRawBits()
}
val speedOverlayFloatValueRegister =
getInstruction<OneRegisterInstruction>(speedOverlayFloatValueIndex).registerA
addInstructions( addInstructions(
speedOverlayValueIndex + 1, """ speedOverlayFloatValueIndex + 1, """
invoke-static {v$speedOverlayValueRegister}, $PLAYER_CLASS_DESCRIPTOR->speedOverlayValue(F)F invoke-static {v$speedOverlayFloatValueRegister}, $PLAYER_CLASS_DESCRIPTOR->speedOverlayValue(F)F
move-result v$speedOverlayValueRegister move-result v$speedOverlayFloatValueRegister
""" """
) )
insertIndex = getTargetIndexWithMethodReferenceNameReversedOrThrow(
speedOverlayValueIndex,
"removeCallbacks"
) + 1
insertRegister =
getInstruction<FiveRegisterInstruction>(insertIndex - 1).registerC
jumpIndex =
getTargetIndexOrThrow(speedOverlayValueIndex, Opcode.RETURN_VOID) + 1
hook(insertIndex, insertRegister, jumpIndex)
}
}
} }
SpeedOverlayTextValueFingerprint.resultOrThrow().let { SpeedOverlayTextValueFingerprint.resultOrThrow().let {
@ -200,10 +231,11 @@ object SpeedOverlayPatch : BytecodePatch(
) )
} }
} }
}
}
private lateinit var slideToSeekBooleanMethod: MutableMethod // endregion
}
}
// restore slide to seek // restore slide to seek
private fun MutableMethod.hook( private fun MutableMethod.hook(
@ -220,14 +252,4 @@ object SpeedOverlayPatch : BytecodePatch(
""", ExternalLabel("disable", getInstruction(jumpIndex)) """, 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
}
}
} }

View File

@ -2,8 +2,10 @@ package app.revanced.patches.youtube.player.speedoverlay.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint 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.AccessFlags
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal object NextGenWatchLayoutFingerprint : MethodFingerprint( internal object NextGenWatchLayoutFingerprint : MethodFingerprint(
returnType = "Z", returnType = "Z",
@ -13,6 +15,8 @@ internal object NextGenWatchLayoutFingerprint : MethodFingerprint(
if (methodDef.definingClass != "Lcom/google/android/apps/youtube/app/watch/nextgenwatch/ui/NextGenWatchLayout;") if (methodDef.definingClass != "Lcom/google/android/apps/youtube/app/watch/nextgenwatch/ui/NextGenWatchLayout;")
return@handler false return@handler false
methodDef.containsMethodReferenceNameInstructionIndex("booleanValue") methodDef.indexOfFirstInstruction {
getReference<MethodReference>()?.name == "booleanValue"
} >= 0
} }
) )

View File

@ -5,6 +5,7 @@ import com.android.tools.smali.dexlib2.Opcode
/** /**
* This value restores the 'Slide to seek' behavior. * This value restores the 'Slide to seek' behavior.
* Deprecated in YouTube v19.18.41+.
*/ */
internal object RestoreSlideToSeekBehaviorFingerprint : LiteralValueFingerprint( internal object RestoreSlideToSeekBehaviorFingerprint : LiteralValueFingerprint(
returnType = "Z", returnType = "Z",

View File

@ -5,6 +5,7 @@ import com.android.tools.smali.dexlib2.Opcode
/** /**
* This value disables 'Playing at 2x speed' while holding down. * This value disables 'Playing at 2x speed' while holding down.
* Deprecated in YouTube v19.18.41+.
*/ */
internal object SpeedOverlayFingerprint : LiteralValueFingerprint( internal object SpeedOverlayFingerprint : LiteralValueFingerprint(
returnType = "Z", returnType = "Z",

View File

@ -7,8 +7,9 @@ import com.android.tools.smali.dexlib2.Opcode
/** /**
* This value is the key for the playback speed overlay value. * 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", returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
opcodes = listOf(Opcode.DOUBLE_TO_FLOAT), opcodes = listOf(Opcode.DOUBLE_TO_FLOAT),

View File

@ -1,14 +1,21 @@
package app.revanced.patches.youtube.player.speedoverlay.fingerprints package app.revanced.patches.youtube.player.speedoverlay.fingerprints
import app.revanced.patcher.extensions.or 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.AccessFlags
import com.android.tools.smali.dexlib2.Opcode 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", returnType = "V",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
parameters = emptyList(), parameters = emptyList(),
opcodes = listOf(Opcode.CONST_WIDE_HIGH16), 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
}
) )

View File

@ -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.patches.youtube.utils.settings.SettingsPatch.contexts
import app.revanced.util.ResourceGroup import app.revanced.util.ResourceGroup
import app.revanced.util.copyResources import app.revanced.util.copyResources
import app.revanced.util.getWideLiteralInstructionIndex
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@ -38,7 +38,7 @@ object ShortsAnimationPatch : BytecodePatch(
ReelFeedbackPause to "setShortsPauseFeedback", ReelFeedbackPause to "setShortsPauseFeedback",
ReelFeedbackPlay to "setShortsPlayFeedback", ReelFeedbackPlay to "setShortsPlayFeedback",
).forEach { (literal, methodName) -> ).forEach { (literal, methodName) ->
val literalIndex = getWideLiteralInstructionIndex(literal) val literalIndex = indexOfFirstWideLiteralInstructionValueOrThrow(literal)
val viewIndex = indexOfFirstInstructionOrThrow(literalIndex) { val viewIndex = indexOfFirstInstructionOrThrow(literalIndex) {
opcode == Opcode.CHECK_CAST opcode == Opcode.CHECK_CAST
&& (this as? ReferenceInstruction)?.reference?.toString() == LOTTIE_ANIMATION_VIEW_CLASS_DESCRIPTOR && (this as? ReferenceInstruction)?.reference?.toString() == LOTTIE_ANIMATION_VIEW_CLASS_DESCRIPTOR

View File

@ -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.utils.settings.SettingsPatch
import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.getReference
import app.revanced.util.getTargetIndexReversedOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.getTargetIndexWithReferenceOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.getWideLiteralInstructionIndex import app.revanced.util.indexOfFirstWideLiteralInstructionValueOrThrow
import app.revanced.util.literalInstructionHook
import app.revanced.util.patch.BaseBytecodePatch import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.replaceLiteralInstructionCall
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction 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.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction 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.FieldReference
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused") @Suppress("unused")
object ShortsComponentPatch : BaseBytecodePatch( object ShortsComponentPatch : BaseBytecodePatch(
@ -106,10 +107,11 @@ object ShortsComponentPatch : BaseBytecodePatch(
ShortsButtonFingerprint.resultOrThrow().let { ShortsButtonFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(ReelRightDislikeIcon) val constIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(ReelRightDislikeIcon)
val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA val constRegister = getInstruction<OneRegisterInstruction>(constIndex).registerA
val jumpIndex = getTargetIndexOrThrow(constIndex, Opcode.CONST_CLASS) + 2 val jumpIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CONST_CLASS) + 2
addInstructionsWithLabels( addInstructionsWithLabels(
constIndex + 1, """ constIndex + 1, """
@ -128,9 +130,9 @@ object ShortsComponentPatch : BaseBytecodePatch(
ShortsButtonFingerprint.resultOrThrow().let { ShortsButtonFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = getWideLiteralInstructionIndex(ReelRightLikeIcon) val insertIndex = indexOfFirstWideLiteralInstructionValueOrThrow(ReelRightLikeIcon)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val jumpIndex = getTargetIndexOrThrow(insertIndex, Opcode.CONST_CLASS) + 2 val jumpIndex = indexOfFirstInstructionOrThrow(insertIndex, Opcode.CONST_CLASS) + 2
addInstructionsWithLabels( addInstructionsWithLabels(
insertIndex + 1, """ insertIndex + 1, """
@ -152,11 +154,12 @@ object ShortsComponentPatch : BaseBytecodePatch(
if (shortsPivotLegacyFingerprintResult != null) { if (shortsPivotLegacyFingerprintResult != null) {
// Legacy method. // Legacy method.
shortsPivotLegacyFingerprintResult.mutableMethod.apply { shortsPivotLegacyFingerprintResult.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(ReelForcedMuteButton) val targetIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(ReelForcedMuteButton)
val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val targetRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
val insertIndex = getTargetIndexReversedOrThrow(targetIndex, Opcode.IF_EQZ) val insertIndex = indexOfFirstInstructionReversedOrThrow(targetIndex, Opcode.IF_EQZ)
val jumpIndex = getTargetIndexOrThrow(targetIndex, Opcode.GOTO) val jumpIndex = indexOfFirstInstructionOrThrow(targetIndex, Opcode.GOTO)
addInstructionsWithLabels( addInstructionsWithLabels(
insertIndex, """ insertIndex, """
@ -173,7 +176,7 @@ object ShortsComponentPatch : BaseBytecodePatch(
move-result v$REGISTER_TEMPLATE_REPLACEMENT move-result v$REGISTER_TEMPLATE_REPLACEMENT
""" """
context.literalInstructionHook( context.replaceLiteralInstructionCall(
ReelPlayerRightPivotV2Size, ReelPlayerRightPivotV2Size,
smaliInstruction smaliInstruction
) )
@ -242,7 +245,8 @@ object ShortsComponentPatch : BaseBytecodePatch(
lateinit var subscriptionFieldReference: FieldReference lateinit var subscriptionFieldReference: FieldReference
parentResult.mutableMethod.apply { parentResult.mutableMethod.apply {
val targetIndex = getWideLiteralInstructionIndex(ReelPlayerFooter) - 1 val targetIndex =
indexOfFirstWideLiteralInstructionValueOrThrow(ReelPlayerFooter) - 1
subscriptionFieldReference = subscriptionFieldReference =
(getInstruction<ReferenceInstruction>(targetIndex)).reference as FieldReference (getInstruction<ReferenceInstruction>(targetIndex)).reference as FieldReference
} }
@ -297,9 +301,9 @@ object ShortsComponentPatch : BaseBytecodePatch(
TextComponentSpecFingerprint.resultOrThrow().let { TextComponentSpecFingerprint.resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val insertIndex = val insertIndex = indexOfFirstInstructionOrThrow {
getTargetIndexWithReferenceOrThrow("Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;") getReference<MethodReference>()?.toString() == "Landroid/text/SpannableString;->valueOf(Ljava/lang/CharSequence;)Landroid/text/SpannableString;"
}
val charSequenceRegister = val charSequenceRegister =
getInstruction<FiveRegisterInstruction>(insertIndex).registerC getInstruction<FiveRegisterInstruction>(insertIndex).registerC
val conversionContextRegister = val conversionContextRegister =
@ -342,11 +346,11 @@ object ShortsComponentPatch : BaseBytecodePatch(
) { ) {
resultOrThrow().let { resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(id) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(id)
val insertIndex = if (reversed) val insertIndex = if (reversed)
getTargetIndexReversedOrThrow(constIndex, Opcode.CHECK_CAST) indexOfFirstInstructionReversedOrThrow(constIndex, Opcode.CHECK_CAST)
else else
getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST) indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstruction( addInstruction(
@ -363,8 +367,8 @@ object ShortsComponentPatch : BaseBytecodePatch(
) { ) {
resultOrThrow().let { resultOrThrow().let {
it.mutableMethod.apply { it.mutableMethod.apply {
val constIndex = getWideLiteralInstructionIndex(id) val constIndex = indexOfFirstWideLiteralInstructionValueOrThrow(id)
val insertIndex = getTargetIndexOrThrow(constIndex, Opcode.CHECK_CAST) val insertIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
hideButtons(insertIndex, descriptor) hideButtons(insertIndex, descriptor)
} }

View File

@ -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.shorts.components.fingerprints.SetPivotBarFingerprint
import app.revanced.patches.youtube.utils.fingerprints.InitializeButtonsFingerprint import app.revanced.patches.youtube.utils.fingerprints.InitializeButtonsFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR 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.getWalkerMethod
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
object ShortsNavigationBarPatch : BytecodePatch( object ShortsNavigationBarPatch : BytecodePatch(
setOf( setOf(
@ -51,7 +53,9 @@ object ShortsNavigationBarPatch : BytecodePatch(
BottomNavigationBarFingerprint.result?.let { BottomNavigationBarFingerprint.result?.let {
it.mutableMethod.apply { it.mutableMethod.apply {
val targetIndex = getTargetIndexWithMethodReferenceNameOrThrow("findViewById") + 1 val targetIndex = indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "findViewById"
} + 1
val insertRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
addInstructions( addInstructions(

View File

@ -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.ReelEnumConstructorFingerprint
import app.revanced.patches.youtube.shorts.components.fingerprints.ReelEnumStaticFingerprint import app.revanced.patches.youtube.shorts.components.fingerprints.ReelEnumStaticFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.SHORTS_CLASS_DESCRIPTOR 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.findMutableMethodOf
import app.revanced.util.getStringInstructionIndex import app.revanced.util.getReference
import app.revanced.util.getTargetIndexOrThrow import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstStringInstructionOrThrow
import app.revanced.util.resultOrThrow import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction 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.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( object ShortsRepeatPatch : BytecodePatch(
setOf(ReelEnumConstructorFingerprint) setOf(ReelEnumConstructorFingerprint)
@ -36,16 +40,15 @@ object ShortsRepeatPatch : BytecodePatch(
} }
val endScreenStringIndex = val endScreenStringIndex =
getStringInstructionIndex("REEL_LOOP_BEHAVIOR_END_SCREEN") indexOfFirstStringInstructionOrThrow("REEL_LOOP_BEHAVIOR_END_SCREEN")
val endScreenReferenceIndex = val endScreenReferenceIndex =
getTargetIndexOrThrow(endScreenStringIndex, Opcode.SPUT_OBJECT) indexOfFirstInstructionOrThrow(endScreenStringIndex, Opcode.SPUT_OBJECT)
val endScreenReference = val endScreenReference =
getInstruction<ReferenceInstruction>(endScreenReferenceIndex).reference.toString() getInstruction<ReferenceInstruction>(endScreenReferenceIndex).reference.toString()
val enumMethodName = ReelEnumStaticFingerprint.resultOrThrow().mutableMethod.name val enumMethod = ReelEnumStaticFingerprint.resultOrThrow().mutableMethod
val enumMethodCall = "$definingClass->$enumMethodName(I)$definingClass"
context.injectHook(endScreenReference, enumMethodCall) context.injectHook(endScreenReference, enumMethod)
} }
} }
} }
@ -54,8 +57,8 @@ object ShortsRepeatPatch : BytecodePatch(
enumName: String, enumName: String,
fieldName: String fieldName: String
) { ) {
val stringIndex = getStringInstructionIndex(enumName) val stringIndex = indexOfFirstStringInstructionOrThrow(enumName)
val insertIndex = getTargetIndexOrThrow(stringIndex, Opcode.SPUT_OBJECT) val insertIndex = indexOfFirstInstructionOrThrow(stringIndex, Opcode.SPUT_OBJECT)
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstruction( addInstruction(
@ -66,25 +69,31 @@ object ShortsRepeatPatch : BytecodePatch(
private fun BytecodeContext.injectHook( private fun BytecodeContext.injectHook(
endScreenReference: String, endScreenReference: String,
enumMethodCall: String enumMethod: MutableMethod
) { ) {
classes.forEach { classDef -> classes.forEach { classDef ->
classDef.methods.filter { method -> classDef.methods.filter { method ->
method.parameters.size == 1 method.parameters.size == 1
&& method.parameters[0].startsWith("L") && method.parameters[0].startsWith("L")
&& method.returnType == "V" && method.returnType == "V"
&& method.containsReferenceInstructionIndex(endScreenReference) && method.indexOfFirstInstruction {
getReference<FieldReference>()?.toString() == endScreenReference
} >= 0
}.forEach { targetMethod -> }.forEach { targetMethod ->
proxy(classDef) proxy(classDef)
.mutableClass .mutableClass
.findMutableMethodOf(targetMethod) .findMutableMethodOf(targetMethod)
.apply { .apply {
for ((index, instruction) in implementation!!.instructions.withIndex()) { implementation!!.instructions
if (instruction.opcode != Opcode.INVOKE_STATIC) .withIndex()
continue .filter { (_, instruction) ->
if ((instruction as ReferenceInstruction).reference.toString() != enumMethodCall) val reference = (instruction as? ReferenceInstruction)?.reference
continue reference is MethodReference &&
MethodUtil.methodSignaturesMatch(enumMethod, reference)
}
.map { (index, _) -> index }
.reversed()
.forEach { index ->
val register = val register =
getInstruction<OneRegisterInstruction>(index + 1).registerA getInstruction<OneRegisterInstruction>(index + 1).registerA

Some files were not shown because too many files have changed in this diff Show More