From 49727dfb3a2f22aedf0394e04fb7260a8a09b1e9 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 22 Mar 2024 23:53:17 +0900 Subject: [PATCH] chore: lint code --- .../music/account/handle/HideHandlePatch.kt | 22 ++--- .../fingerprints/FloatingButtonFingerprint.kt | 3 - .../HistoryMenuItemOfflineTabFingerprint.kt | 2 +- .../general/startpage/ChangeStartPagePatch.kt | 6 +- .../misc/tastebuilder/TasteBuilderPatch.kt | 4 +- .../TasteBuilderConstructorFingerprint.kt | 4 +- .../utils/resourceid/SharedResourceIdPatch.kt | 2 +- .../youtube/general/handle/HideHandlePatch.kt | 19 ++-- ...ntSwitcherAccessibilityLabelFingerprint.kt | 10 -- .../append/AppendTimeStampInformationPatch.kt | 19 +--- .../kotlin/app/revanced/util/BytecodeUtils.kt | 94 +++++++++++++++++-- 11 files changed, 116 insertions(+), 69 deletions(-) diff --git a/src/main/kotlin/app/revanced/patches/music/account/handle/HideHandlePatch.kt b/src/main/kotlin/app/revanced/patches/music/account/handle/HideHandlePatch.kt index 515ee4cfe..2d87dc598 100644 --- a/src/main/kotlin/app/revanced/patches/music/account/handle/HideHandlePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/account/handle/HideHandlePatch.kt @@ -14,12 +14,9 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.util.exception -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.Opcode +import app.revanced.util.getTargetIndexWithMethodReferenceName +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.formats.Instruction35c -import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Patch( name = "Hide handle", @@ -61,19 +58,12 @@ object HideHandlePatch : BytecodePatch( AccountSwitcherAccessibilityLabelFingerprint.result?.let { result -> result.mutableMethod.apply { - val textColorIndex = indexOfFirstInstruction { - getReference()?.name == "setTextColor" - } - val setTextIndex = implementation!!.instructions.let { - textColorIndex + it.subList(textColorIndex, textColorIndex + 10).indexOfFirst { instruction -> - instruction.opcode == Opcode.INVOKE_VIRTUAL - && instruction.getReference()?.name == "setVisibility" - } - } - val textViewInstruction = getInstruction(setTextIndex) + val textColorIndex = getTargetIndexWithMethodReferenceName("setTextColor") + val setVisibilityIndex = getTargetIndexWithMethodReferenceName(textColorIndex, "setVisibility") + val textViewInstruction = getInstruction(setVisibilityIndex) replaceInstruction( - setTextIndex, + setVisibilityIndex, "invoke-static {v${textViewInstruction.registerC}, v${textViewInstruction.registerD}}, $ACCOUNT->hideHandle(Landroid/widget/TextView;I)V" ) } diff --git a/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonFingerprint.kt index 16a5f2be0..686fdd2af 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/floatingbutton/fingerprints/FloatingButtonFingerprint.kt @@ -1,13 +1,10 @@ package app.revanced.patches.music.general.floatingbutton.fingerprints -import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode object FloatingButtonFingerprint : MethodFingerprint( returnType = "V", - accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, parameters = listOf("L"), opcodes = listOf(Opcode.AND_INT_LIT16) ) diff --git a/src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt index 8b7e49160..2776fa6b1 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/historybutton/fingerprints/HistoryMenuItemOfflineTabFingerprint.kt @@ -16,7 +16,7 @@ object HistoryMenuItemOfflineTabFingerprint : MethodFingerprint( Opcode.INVOKE_INTERFACE, Opcode.RETURN_VOID ), - customFingerprint = { methodDef, classDef -> + customFingerprint = { methodDef, _ -> methodDef.containsWideLiteralInstructionIndex(HistoryMenuItem) && methodDef.containsWideLiteralInstructionIndex(OfflineSettingsMenuItem) } diff --git a/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt b/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt index dd61c853e..4e6251e15 100644 --- a/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt @@ -9,7 +9,6 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.music.general.startpage.fingerprints.ColdStartUpFingerprint import app.revanced.patches.music.utils.integrations.Constants.GENERAL -import app.revanced.patches.music.utils.intenthook.IntentHookPatch import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.SettingsPatch import app.revanced.patches.music.utils.settings.SettingsPatch.contexts @@ -20,10 +19,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Patch( name = "Change start page", description = "Adds an option to set which page the app opens in instead of the homepage.", - dependencies = [ - IntentHookPatch::class, - SettingsPatch::class - ], + dependencies = [SettingsPatch::class], compatiblePackages = [ CompatiblePackage( "com.google.android.apps.youtube.music", diff --git a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/TasteBuilderPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/TasteBuilderPatch.kt index 88aa74a5e..0de996340 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/TasteBuilderPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/TasteBuilderPatch.kt @@ -10,7 +10,7 @@ import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.music.misc.tastebuilder.fingerprints.TasteBuilderConstructorFingerprint import app.revanced.patches.music.misc.tastebuilder.fingerprints.TasteBuilderSyntheticFingerprint 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.MusicTasteBuilderShelf import app.revanced.util.exception import app.revanced.util.getTargetIndex import app.revanced.util.getWideLiteralInstructionIndex @@ -49,7 +49,7 @@ object TasteBuilderPatch : BytecodePatch( parentResult.mutableMethod.apply { val freeRegister = implementation!!.registerCount - parameters.size - 2 - val constIndex = getWideLiteralInstructionIndex(MusicTastebuilderShelf) + val constIndex = getWideLiteralInstructionIndex(MusicTasteBuilderShelf) val targetIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT) val targetRegister = getInstruction(targetIndex).registerA diff --git a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt index 5d0af1799..b17d3255c 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/tastebuilder/fingerprints/TasteBuilderConstructorFingerprint.kt @@ -1,12 +1,12 @@ package app.revanced.patches.music.misc.tastebuilder.fingerprints import app.revanced.patcher.extensions.or -import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTastebuilderShelf +import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MusicTasteBuilderShelf import app.revanced.util.fingerprint.LiteralValueFingerprint import com.android.tools.smali.dexlib2.AccessFlags object TasteBuilderConstructorFingerprint : LiteralValueFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - literalSupplier = { MusicTastebuilderShelf } + literalSupplier = { MusicTasteBuilderShelf } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt b/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt index 7bb08f691..6def9221f 100644 --- a/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt @@ -32,7 +32,7 @@ object SharedResourceIdPatch : ResourcePatch() { var MiniPlayerPlayPauseReplayButton: Long = -1 var MusicMenuLikeButtons: Long = -1 var MusicNotifierShelf: Long = -1 - var MusicTastebuilderShelf: Long = -1 + var MusicTasteBuilderShelf: Long = -1 var NamesInactiveAccountThumbnailSize: Long = -1 var OfflineSettingsMenuItem: Long = -1 var PlayerCastMediaRouteButton: Long = -1 diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/handle/HideHandlePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/handle/HideHandlePatch.kt index 5c4d900d2..1c59d9773 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/handle/HideHandlePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/handle/HideHandlePatch.kt @@ -11,9 +11,14 @@ import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL import app.revanced.patches.youtube.utils.litho.LithoFilterPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.exception -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import app.revanced.util.getTargetIndex +import app.revanced.util.getTargetIndexWithMethodReferenceName +import app.revanced.util.getWideLiteralInstructionIndex +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction @Patch( name = "Hide handle", @@ -66,13 +71,15 @@ object HideHandlePatch : BytecodePatch( AccountSwitcherAccessibilityLabelFingerprint.result?.let { it.mutableMethod.apply { - val targetIndex = it.scanResult.patternScanResult!!.endIndex - 2 - val targetRegister = getInstruction(targetIndex).registerA + val constIndex = getWideLiteralInstructionIndex(AccountSwitcherAccessibility) + val insertIndex = getTargetIndex(constIndex, Opcode.IF_EQZ) + val setVisibilityIndex = getTargetIndexWithMethodReferenceName(insertIndex, "setVisibility") + val visibilityRegister = getInstruction(setVisibilityIndex).registerD addInstructions( - targetIndex + 2, """ - invoke-static {v$targetRegister}, $GENERAL->hideHandle(I)I - move-result v$targetRegister + insertIndex, """ + invoke-static {v$visibilityRegister}, $GENERAL->hideHandle(I)I + move-result v$visibilityRegister """ ) } diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt index f4d73867e..3197cd1d4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/general/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/general/handle/fingerprints/AccountSwitcherAccessibilityLabelFingerprint.kt @@ -2,19 +2,9 @@ package app.revanced.patches.youtube.general.handle.fingerprints import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.AccountSwitcherAccessibility import app.revanced.util.fingerprint.LiteralValueFingerprint -import com.android.tools.smali.dexlib2.Opcode object AccountSwitcherAccessibilityLabelFingerprint : LiteralValueFingerprint( returnType = "V", parameters = listOf("L", "Ljava/lang/Object;"), - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.NEW_ARRAY, - Opcode.CONST_4, - Opcode.APUT_OBJECT, - Opcode.CONST - ), literalSupplier = { AccountSwitcherAccessibility } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/seekbar/append/AppendTimeStampInformationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/seekbar/append/AppendTimeStampInformationPatch.kt index 744dff1ad..adb262e84 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/seekbar/append/AppendTimeStampInformationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/seekbar/append/AppendTimeStampInformationPatch.kt @@ -11,17 +11,11 @@ import app.revanced.patches.youtube.utils.integrations.Constants.SEEKBAR import app.revanced.patches.youtube.utils.overridequality.OverrideQualityHookPatch import app.revanced.patches.youtube.utils.overridespeed.OverrideSpeedHookPatch import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch -import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.TotalTime import app.revanced.patches.youtube.utils.settings.SettingsPatch import app.revanced.util.exception -import app.revanced.util.getReference -import app.revanced.util.getTargetIndex -import app.revanced.util.getWideLiteralInstructionIndex -import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.Opcode +import app.revanced.util.getTargetIndexWithMethodReferenceName +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.formats.Instruction35c -import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Patch( name = "Append time stamps information", @@ -71,14 +65,11 @@ object AppendTimeStampInformationPatch : BytecodePatch( override fun execute(context: BytecodeContext) { TotalTimeFingerprint.result?.let { it.mutableMethod.apply { - val constIndex = getWideLiteralInstructionIndex(TotalTime) - val charSequenceIndex = getTargetIndex(constIndex, Opcode.MOVE_RESULT_OBJECT) + val charSequenceIndex = getTargetIndexWithMethodReferenceName("getString") + 1 val charSequenceRegister = getInstruction(charSequenceIndex).registerA - val textViewIndex = indexOfFirstInstruction { - getReference()?.name == "getText" - } + val textViewIndex = getTargetIndexWithMethodReferenceName("getText") val textViewRegister = - getInstruction(textViewIndex).registerC + getInstruction(textViewIndex).registerC addInstructions( textViewIndex, """ diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index adfb1d007..c5a0ced78 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -1,3 +1,5 @@ +@file:Suppress("unused") + package app.revanced.util import app.revanced.patcher.data.BytecodeContext @@ -15,6 +17,8 @@ import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.Instruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.Reference import com.android.tools.smali.dexlib2.util.MethodUtil @@ -109,6 +113,9 @@ fun Method.getStringInstructionIndex(value: String) = implementation?.let { fun Method.containsWideLiteralInstructionIndex(literal: Long) = getWideLiteralInstructionIndex(literal) >= 0 +fun Method.containsMethodReferenceNameInstructionIndex(methodName: String) = + getTargetIndexWithMethodReferenceName(methodName) >= 0 + /** * Traverse the class hierarchy starting from the given root class. * @@ -136,14 +143,10 @@ fun BytecodeContext.traverseClassHierarchy( inline fun Instruction.getReference() = (this as? ReferenceInstruction)?.reference as? T -/** - * Get the index of the first [Instruction] that matches the predicate. - * - * @param predicate The predicate to match. - * @return The index of the first [Instruction] that matches the predicate. - */ -fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) = - this.implementation!!.instructions.indexOfFirst(predicate) +fun MutableMethod.getTargetIndex(opcode: Opcode) = getTargetIndex(0, opcode) + +fun MutableMethod.getTargetIndexReversed(opcode: Opcode) = + getTargetIndex(implementation!!.instructions.size - 1, opcode) fun MutableMethod.getTargetIndex(startIndex: Int, opcode: Opcode) = implementation!!.instructions.let { @@ -159,7 +162,80 @@ fun MutableMethod.getTargetIndexReversed(startIndex: Int, opcode: Opcode): Int { return index } - throw PatchException("Failed to find target index") + return -1 +} + +fun Method.getTargetIndexWithFieldReferenceType(returnType: String) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + instruction.getReference()?.type == returnType + } +} ?: -1 + +fun MutableMethod.getTargetIndexWithFieldReferenceTypeReversed(returnType: String) += getTargetIndexWithFieldReferenceTypeReversed(implementation!!.instructions.size - 1, returnType) + +fun MutableMethod.getTargetIndexWithFieldReferenceType(startIndex: Int, returnType: String) = + implementation!!.instructions.let { + startIndex + it.subList(startIndex, it.size - 1).indexOfFirst { instruction -> + instruction.getReference()?.type == returnType + } + } + +fun MutableMethod.getTargetIndexWithFieldReferenceTypeReversed(startIndex: Int, returnType: String): Int { + for (index in startIndex downTo 0) { + val instruction = getInstruction(index) + if (instruction.getReference()?.type != returnType) + continue + + return index + } + return -1 +} + +fun Method.getTargetIndexWithMethodReferenceName(methodName: String) = implementation?.let { + it.instructions.indexOfFirst { instruction -> + instruction.getReference()?.name == methodName + } +} ?: -1 + +fun MutableMethod.getTargetIndexWithMethodReferenceNameReversed(methodName: String) += getTargetIndexWithMethodReferenceNameReversed(implementation!!.instructions.size - 1, methodName) + + +fun MutableMethod.getTargetIndexWithMethodReferenceName(startIndex: Int, methodName: String) = + implementation!!.instructions.let { + startIndex + it.subList(startIndex, it.size - 1).indexOfFirst { instruction -> + instruction.getReference()?.name == methodName + } + } + +fun MutableMethod.getTargetIndexWithMethodReferenceNameReversed(startIndex: Int, methodName: String): Int { + for (index in startIndex downTo 0) { + val instruction = getInstruction(index) + if (instruction.getReference()?.name != methodName) + continue + + return index + } + return -1 +} + +fun MutableMethod.getTargetIndexWithReference(startIndex: Int, reference: String) = + implementation!!.instructions.let { + startIndex + it.subList(startIndex, it.size - 1).indexOfFirst { instruction -> + (instruction as? ReferenceInstruction)?.reference.toString().contains(reference) + } + } + +fun MutableMethod.getTargetIndexWithReferenceReversed(startIndex: Int, reference: String): Int { + for (index in startIndex downTo 0) { + val instruction = getInstruction(index) + if (!(instruction as? ReferenceInstruction)?.reference.toString().contains(reference)) + continue + + return index + } + return -1 } fun BytecodeContext.updatePatchStatus(