diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/Fingerprints.kt index 27c91b4c8..161599e54 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/Fingerprints.kt @@ -1,4 +1,3 @@ - package app.revanced.patches.instagram.hide.navigation import app.revanced.patcher.* @@ -11,6 +10,9 @@ internal val BytecodePatchContext.initializeNavigationButtonsListMethod by getti returnType("Ljava/util/List;") } -internal val navigationButtonsEnumClassDefMatch = firstMethodComposite( - "FEED", "fragment_feed", "SEARCH", "fragment_search", +internal val BytecodePatchContext.navigationButtonsEnumMethod by gettingFirstMethodDeclaratively( + "FEED", + "fragment_feed", + "SEARCH", + "fragment_search", ) diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt index 587196938..fc8d863ff 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt @@ -2,6 +2,7 @@ package app.revanced.patches.instagram.hide.navigation import app.revanced.patcher.extensions.getInstruction import app.revanced.patcher.firstMutableMethodDeclaratively +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.name import app.revanced.patcher.patch.booleanOption import app.revanced.patcher.patch.creatingBytecodePatch @@ -73,7 +74,7 @@ val `Hide navigation buttons` by creatingBytecodePatch( // Get the field name which contains the name of the enum for the navigation button // ("fragment_clips", "fragment_share", ...) - val enumNameField = navigationButtonsEnumClassDefMatch.classDef.firstMutableMethodDeclaratively { + val enumNameField = navigationButtonsEnumMethod.immutableClassDef.firstMutableMethodDeclaratively { name("") }.let { method -> method.indexOfFirstInstructionOrThrow { diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatch.kt index 82b52a6ae..7cb165095 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/EnableDeveloperMenuPatch.kt @@ -1,13 +1,11 @@ package app.revanced.patches.instagram.misc.devmenu +import app.revanced.patcher.extensions.methodReference import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.util.Utils.trimIndentMultiline -import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionReversedOrThrow -import app.revanced.util.indexOfFirstStringInstruction import app.revanced.util.returnEarly import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Suppress("unused", "ObjectPropertyName") val `Enable developer menu` by creatingBytecodePatch( @@ -21,16 +19,17 @@ val `Enable developer menu` by creatingBytecodePatch( compatibleWith("com.instagram.android") apply { - clearNotificationReceiverMethod.apply { - val stringIndex = indexOfFirstStringInstruction("NOTIFICATION_DISMISSED") - indexOfFirstInstructionReversedOrThrow(stringIndex) { - val reference = getReference() + clearNotificationReceiverMethodMatch.let { + val stringIndex = it.indices.first() + + it.method.indexOfFirstInstructionReversedOrThrow(stringIndex) { + val reference = methodReference opcode in listOf(Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC_RANGE) && reference?.parameterTypes?.size == 1 && reference.parameterTypes.first() == "Lcom/instagram/common/session/UserSession;" && reference.returnType == "Z" }.let { index -> - navigate(this).to(index).stop().returnEarly(true) + navigate(it.method).to(index).stop().returnEarly(true) } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/Fingerprints.kt index 45936b370..1ba3c4fd5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/devmenu/Fingerprints.kt @@ -1,11 +1,9 @@ package app.revanced.patches.instagram.misc.devmenu import app.revanced.patcher.* -import app.revanced.patcher.patch.BytecodePatchContext -internal val BytecodePatchContext.clearNotificationReceiverMethod by gettingFirstMutableMethodDeclaratively( - "NOTIFICATION_DISMISSED", -) { +internal val clearNotificationReceiverMethodMatch = firstMethodComposite { name("onReceive") definingClass("Lcom/instagram/notifications/push/ClearNotificationReceiver;") + instructions("NOTIFICATION_DISMISSED"()) } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/Fingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/Fingerprint.kt index 335f8e1c6..3a06dfec7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/Fingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/Fingerprint.kt @@ -7,7 +7,7 @@ import app.revanced.patcher.returnType internal const val TARGET_STRING = "Tracking.ARG_CLICK_SOURCE" -internal val inAppBrowserFunctionMethodMatch = firstMethodComposite { - instructions("TrackingInfo.ARG_MODULE_NAME"(), TARGET_STRING()) +internal val inAppBrowserFunctionMethodMatch = firstMethodComposite("TrackingInfo.ARG_MODULE_NAME") { + instructions(TARGET_STRING()) returnType("Z") } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/OpenLinksExternallyPatch.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/OpenLinksExternallyPatch.kt index f47b3dad9..e5067f91d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/OpenLinksExternallyPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/links/OpenLinksExternallyPatch.kt @@ -21,25 +21,27 @@ val `Open links externally` by creatingBytecodePatch( compatibleWith("com.instagram.android") apply { - inAppBrowserFunctionMethodMatch.method.apply { - val stringMatchIndex = inAppBrowserFunctionMethodMatch.indices.first() + inAppBrowserFunctionMethodMatch.let { + val stringMatchIndex = it.indices.first() - val urlResultObjIndex = indexOfFirstInstructionOrThrow( - stringMatchIndex, - Opcode.MOVE_OBJECT_FROM16, - ) + it.method.apply { + val urlResultObjIndex = indexOfFirstInstructionOrThrow( + stringMatchIndex, + Opcode.MOVE_OBJECT_FROM16, + ) - // Register that contains the url after moving from a higher register. - val urlRegister = getInstruction(urlResultObjIndex).registerA + // Register that contains the url after moving from a higher register. + val urlRegister = getInstruction(urlResultObjIndex).registerA - addInstructions( - urlResultObjIndex + 1, - """ - invoke-static { v$urlRegister }, $EXTENSION_CLASS_DESCRIPTOR->openExternally(Ljava/lang/String;)Z - move-result v$urlRegister - return v$urlRegister - """, - ) + addInstructions( + urlResultObjIndex + 1, + """ + invoke-static { v$urlRegister }, $EXTENSION_CLASS_DESCRIPTOR->openExternally(Ljava/lang/String;)Z + move-result v$urlRegister + return v$urlRegister + """, + ) + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/EditShareLinksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/EditShareLinksPatch.kt index 8c71f8e1a..298f7fa02 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/EditShareLinksPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/EditShareLinksPatch.kt @@ -3,24 +3,22 @@ package app.revanced.patches.instagram.misc.share import app.revanced.patcher.extensions.getInstruction import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.indexOfFirstStringInstruction import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.mutable.MutableMethod -context(_: BytecodePatchContext) -internal fun editShareLinksPatch(block: MutableMethod.(index: Int, register: Int) -> Unit) { +internal fun BytecodePatchContext.editShareLinksPatch(block: MutableMethod.(index: Int, register: Int) -> Unit) { val methodsToPatch = arrayOf( - permalinkResponseJsonParserMethod, - storyUrlResponseJsonParserMethod, - profileUrlResponseJsonParserMethod, - liveUrlResponseJsonParserMethod, + permalinkResponseJsonParserMethodMatch, + storyUrlResponseJsonParserMethodMatch, + profileUrlResponseJsonParserMethodMatch, + liveUrlResponseJsonParserMethodMatch, ) - for (method in methodsToPatch) { - method.apply { + for (match in methodsToPatch) { + match.method.apply { val putSharingUrlIndex = indexOfFirstInstruction( - indexOfFirstStringInstruction("permalink"), + match.indices.first(), Opcode.IPUT_OBJECT, ) diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/Fingerprints.kt new file mode 100644 index 000000000..50a13daf6 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/Fingerprints.kt @@ -0,0 +1,34 @@ +package app.revanced.patches.instagram.misc.share + +import app.revanced.patcher.firstMethodComposite +import app.revanced.patcher.instructions +import app.revanced.patcher.invoke +import app.revanced.patcher.name + +internal val permalinkResponseJsonParserMethodMatch = firstMethodComposite( + "PermalinkResponse", +) { + name("parseFromJson") + instructions("permalink"()) +} + +internal val storyUrlResponseJsonParserMethodMatch = firstMethodComposite( + "StoryItemUrlResponse", +) { + name("parseFromJson") + instructions("story_item_to_share_url"()) +} + +internal val profileUrlResponseJsonParserMethodMatch = firstMethodComposite( + "ProfileUrlResponse", +) { + name("parseFromJson") + instructions("profile_to_share_url"()) +} + +internal val liveUrlResponseJsonParserMethodMatch = firstMethodComposite( + "LiveItemLinkUrlResponse", +) { + name("parseFromJson") + instructions("live_to_share_url"()) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/PermalinkResponseJsonParserFingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/PermalinkResponseJsonParserFingerprint.kt deleted file mode 100644 index 650313c71..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/PermalinkResponseJsonParserFingerprint.kt +++ /dev/null @@ -1,28 +0,0 @@ -package app.revanced.patches.instagram.misc.share - -import app.revanced.patcher.* -import app.revanced.patcher.patch.BytecodePatchContext - -internal val BytecodePatchContext.permalinkResponseJsonParserMethod by gettingFirstMutableMethodDeclaratively( - "permalink", "PermalinkResponse", -) { - name("parseFromJson") -} - -internal val BytecodePatchContext.storyUrlResponseJsonParserMethod by gettingFirstMutableMethodDeclaratively( - "story_item_to_share_url", "StoryItemUrlResponse", -) { - name("parseFromJson") -} - -internal val BytecodePatchContext.profileUrlResponseJsonParserMethod by gettingFirstMutableMethodDeclaratively( - "profile_to_share_url", "ProfileUrlResponse", -) { - name("parseFromJson") -} - -internal val BytecodePatchContext.liveUrlResponseJsonParserMethod by gettingFirstMutableMethodDeclaratively( - "live_to_share_url", "LiveItemLinkUrlResponse", -) { - name("parseFromJson") -} diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/domain/Fingerprint.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/domain/Fingerprint.kt index 33ed47d1b..df3f4e573 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/domain/Fingerprint.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/share/domain/Fingerprint.kt @@ -5,9 +5,9 @@ import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.AccessFlags internal val BytecodePatchContext.getCustomShareDomainMethod by gettingFirstMutableMethodDeclaratively { + name("getCustomShareDomain") + definingClass(EXTENSION_CLASS_DESCRIPTOR) accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) returnType("Ljava/lang/String;") parameterTypes() - name("getCustomShareDomain") - definingClass(EXTENSION_CLASS_DESCRIPTOR) } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/signature/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/signature/Fingerprints.kt index a0350d596..d4681549f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/signature/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/signature/Fingerprints.kt @@ -2,20 +2,16 @@ package app.revanced.patches.instagram.misc.signature import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.ClassDef -internal val isValidSignatureClassMethodMatch = firstMethodComposite( - "The provider for uri '", "' is not trusted: ", +context(_: BytecodePatchContext) +internal fun ClassDef.getIsValidSignatureClassMethod() = firstMutableMethodDeclaratively( + "The provider for uri '", + "' is not trusted: ", ) internal val BytecodePatchContext.isValidSignatureMethodMethod by gettingFirstMutableMethodDeclaratively { parameterTypes("L", "Z") returnType("Z") - custom { - indexOfFirstInstruction { - getReference()?.name == "keySet" - } >= 0 - } + instructions(method("keySet")) } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/signature/SignatureCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/signature/SignatureCheckPatch.kt index 4d7641260..287b2c3b7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/signature/SignatureCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/signature/SignatureCheckPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.instagram.misc.signature +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.util.returnEarly @@ -12,9 +13,6 @@ val `Disable signature check` by creatingBytecodePatch( compatibleWith("com.instagram.android") apply { - isValidSignatureMethodMethod - .match(isValidSignatureClassMethodMatch.classDef) - .method - .returnEarly(true) + isValidSignatureMethodMethod.immutableClassDef.getIsValidSignatureClassMethod().returnEarly(true) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/Fingerprints.kt index ec43ea258..4149549d9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/Fingerprints.kt @@ -13,7 +13,8 @@ internal val metaAIKillSwitchCheckMethodMatch = firstMethodComposite("SearchAiag opcodes(Opcode.CONST_WIDE) } -internal val extensionMethodMethodMatch = firstMethodComposite("REPLACED_BY_PATCH") { +internal val extensionMethodMatch = firstMethodComposite { name(EXTENSION_METHOD_NAME) definingClass(EXTENSION_CLASS_DESCRIPTOR) + instructions("REPLACED_BY_PATCH"()) } diff --git a/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/RemoveMetaAIPatch.kt b/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/RemoveMetaAIPatch.kt index ac17c44e6..78ae851f7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/RemoveMetaAIPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/messenger/metaai/RemoveMetaAIPatch.kt @@ -39,12 +39,10 @@ val `Remove Meta AI` by creatingBytecodePatch( }.toString().substring(0, 7) // Replace placeholder in the extension method. - extensionMethodMethodMatch.let { + extensionMethodMatch.let { it.method.replaceInstruction( it.indices.first(), - """ - const-string v1, "$relevantDigits" - """, + "const-string v1, \"$relevantDigits\"", ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt index 4f561a391..5a1ae50bd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt @@ -55,9 +55,9 @@ val `Change start page` by creatingBytecodePatch( ) // Hook browseId. - browseIdMethod.let { + browseIdMethodMatch.let { it.method.apply { - val browseIdIndex = it.instructionMatches.first().index + val browseIdIndex = it.indices.first() val browseIdRegister = getInstruction(browseIdIndex).registerA addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt index bd673da4d..02bec111c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/Fingerprints.kt @@ -10,12 +10,11 @@ internal val BytecodePatchContext.intentActionMethod by gettingFirstMutableMetho parameterTypes("Landroid/content/Intent;") } -internal val BytecodePatchContext.browseIdMethod by gettingFirstMutableMethodDeclaratively( - "FEwhat_to_watch", -) { +internal val browseIdMethodMatch = firstMethodComposite { returnType("Lcom/google/android/apps/youtube/app/common/ui/navigation/PaneDescriptor;") // parameterTypes() // 20.30 and earlier is no parameters. 20.31+ parameter is L. instructions( + "FEwhat_to_watch"(), 512L(), allOf(Opcode.IPUT_OBJECT(), field { type == "Ljava/lang/String;" }), ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt index 76afb98d1..abc9268e7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/Fingerprints.kt @@ -1,24 +1,21 @@ package app.revanced.patches.youtube.layout.theme import app.revanced.patcher.* -import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patches.youtube.shared.YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE -internal val BytecodePatchContext.useGradientLoadingScreenMethod by gettingFirstMutableMethodDeclaratively { - instructions( - 45412406L(), - ) +internal val useGradientLoadingScreenMethodMatch = firstMethodComposite { + instructions(45412406L()) } -internal val BytecodePatchContext.splashScreenStyleMethod by gettingFirstMutableMethodDeclaratively { +internal val splashScreenStyleMethodMatch = firstMethodComposite { + definingClass(YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE) + name("onCreate") returnType("V") parameterTypes("Landroid/os/Bundle;") instructions( - anyInstruction( + anyOf( 1074339245L(), // 20.30+ 269032877L(), // 20.29 and lower. ), ) - definingClass(YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE) - name("onCreate") } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt index b566c6405..efcda2b9d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt @@ -200,15 +200,15 @@ val themePatch = baseThemePatch( ) } - useGradientLoadingScreenMethod.insertLiteralOverride( - 45412406L, + useGradientLoadingScreenMethodMatch.method.insertLiteralOverride( + useGradientLoadingScreenMethodMatch.indices.first(), "$EXTENSION_CLASS_DESCRIPTOR->gradientLoadingScreenEnabled(Z)Z", ) if (is_19_47_or_greater) { // Lottie splash screen exists in earlier versions, but it may not be always on. - splashScreenStyleMethod.insertLiteralOverride( - 1074339245L, + splashScreenStyleMethodMatch.method.insertLiteralOverride( + splashScreenStyleMethodMatch.indices.first(), "$EXTENSION_CLASS_DESCRIPTOR->getLoadingScreenType(I)I", ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/Fingerprints.kt index 8431e18d5..bb4255191 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/Fingerprints.kt @@ -1,13 +1,15 @@ package app.revanced.patches.youtube.misc.dimensions.spoof -import app.revanced.patcher.* +import app.revanced.patcher.gettingFirstMutableMethodDeclaratively +import app.revanced.patcher.instructions +import app.revanced.patcher.invoke import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.returnType -// Strings are partial matches (format delimiters), so keep in instructions block. -internal val deviceDimensionsModelToStringMethodMatch = firstMethodComposite { +internal val BytecodePatchContext.deviceDimensionsModelToStringMethod by gettingFirstMutableMethodDeclaratively { returnType("L") - strings { - +"minh." - +";maxh." - } + instructions( + "minh."(), + ";maxh."(), + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt index 52653e521..e24b03350 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt @@ -1,6 +1,8 @@ package app.revanced.patches.youtube.misc.dimensions.spoof +import app.revanced.patcher.classDef import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.firstMutableMethod import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch @@ -38,21 +40,20 @@ val `Spoof device dimensions` by creatingBytecodePatch( SwitchPreference("revanced_spoof_device_dimensions"), ) - deviceDimensionsModelToStringMethodMatch.classDef.methods.first { method -> method.name == "" } - // Override the parameters containing the dimensions. - .addInstructions( - 1, // Add after super call. - arrayOf( - 1 to "MinHeightOrWidth", // p1 = min height - 2 to "MaxHeightOrWidth", // p2 = max height - 3 to "MinHeightOrWidth", // p3 = min width - 4 to "MaxHeightOrWidth", // p4 = max width - ).map { (parameter, method) -> - """ - invoke-static { p$parameter }, $EXTENSION_CLASS_DESCRIPTOR->get$method(I)I - move-result p$parameter - """ - }.joinToString("\n") { it }, - ) + // Override the parameters containing the dimensions. + deviceDimensionsModelToStringMethod.classDef.methods.firstMutableMethod { name == "" }.addInstructions( + 1, // Add after super call. + arrayOf( + 1 to "MinHeightOrWidth", // p1 = min height + 2 to "MaxHeightOrWidth", // p2 = max height + 3 to "MinHeightOrWidth", // p3 = min width + 4 to "MaxHeightOrWidth", // p4 = max width + ).map { (parameter, method) -> + """ + invoke-static { p$parameter }, $EXTENSION_CLASS_DESCRIPTOR->get$method(I)I + move-result p$parameter + """ + }.joinToString("\n") { it }, + ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Fingerprints.kt index d8ca1b7ba..23f6c1149 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Fingerprints.kt @@ -1,7 +1,6 @@ package app.revanced.patches.youtube.misc.gms import app.revanced.patcher.* -import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patches.shared.misc.mapping.ResourceType import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -14,7 +13,7 @@ internal val specificNetworkErrorViewControllerMethodMatch = firstMethodComposit ResourceType.DRAWABLE("ic_offline_no_content_upside_down"), ResourceType.STRING("offline_no_content_body_text_not_offline_eligible"), method { name == "getString" && returnType == "Ljava/lang/String;" }, - Opcode.MOVE_RESULT_OBJECT(), + after(Opcode.MOVE_RESULT_OBJECT()), ) } @@ -28,6 +27,6 @@ internal val loadingFrameLayoutControllerMethodMatch = firstMethodComposite { ResourceType.DRAWABLE("ic_offline_no_content_upside_down"), ResourceType.STRING("offline_no_content_body_text_not_offline_eligible"), method { name == "getString" && returnType == "Ljava/lang/String;" }, - Opcode.MOVE_RESULT_OBJECT(), + after(Opcode.MOVE_RESULT_OBJECT()), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook.kt index 1f3e3b543..03c0e94b4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/CronetImageUrlHook.kt @@ -1,8 +1,10 @@ package app.revanced.patches.youtube.misc.imageurlhook +import app.revanced.patcher.classDef import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.instructions +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.util.getReference @@ -30,14 +32,9 @@ val cronetImageUrlHookPatch = bytecodePatch( dependsOn(sharedExtensionPatch) apply { - loadImageUrlMethod = messageDigestImageUrlMethod - .match(messageDigestImageUrlParentMethodMatch.classDef) - - loadImageSuccessCallbackMethod = onSucceededMethod - .match(onResponseStartedMethodMatch.classDef) - - loadImageErrorCallbackMethod = onFailureMethod - .match(onResponseStartedMethodMatch.classDef) + loadImageUrlMethod = messageDigestImageUrlParentMethod.immutableClassDef.getMessageDigestImageUrlMethod() + loadImageSuccessCallbackMethod = onResponseStartedMethod.immutableClassDef.getOnSucceededMethod() + loadImageErrorCallbackMethod = onResponseStartedMethod.immutableClassDef.getOnFailureMethod() // The URL is required for the failure callback hook, but the URL field is obfuscated. // Add a helper get method that returns the URL field. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt index 7f86ebfd9..e45548d55 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/imageurlhook/Fingerprints.kt @@ -3,8 +3,11 @@ package app.revanced.patches.youtube.misc.imageurlhook import app.revanced.patcher.* import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.iface.ClassDef -internal val BytecodePatchContext.onFailureMethod by gettingFirstMutableMethodDeclaratively { +context(_: BytecodePatchContext) +internal fun ClassDef.getOnFailureMethod() = firstMutableMethodDeclaratively { + name("onFailed") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("V") parameterTypes( @@ -12,49 +15,50 @@ internal val BytecodePatchContext.onFailureMethod by gettingFirstMutableMethodDe "Lorg/chromium/net/UrlResponseInfo;", "Lorg/chromium/net/CronetException;", ) - name("onFailed") } // Acts as a parent fingerprint. -internal val onResponseStartedMethodMatch = firstMethodComposite( +internal val BytecodePatchContext.onResponseStartedMethod by gettingFirstMutableMethodDeclaratively( "Content-Length", "Content-Type", "identity", "application/x-protobuf", ) { + name("onResponseStarted") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("V") parameterTypes("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;") - name("onResponseStarted") } -internal val BytecodePatchContext.onSucceededMethod by gettingFirstMutableMethodDeclaratively { +context(_: BytecodePatchContext) +internal fun ClassDef.getOnSucceededMethod() = firstMutableMethodDeclaratively { + name("onSucceeded") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("V") parameterTypes("Lorg/chromium/net/UrlRequest;", "Lorg/chromium/net/UrlResponseInfo;") - name("onSucceeded") } internal const val CRONET_URL_REQUEST_CLASS_DESCRIPTOR = "Lorg/chromium/net/impl/CronetUrlRequest;" internal val BytecodePatchContext.requestMethod by gettingFirstMutableMethodDeclaratively { - accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) definingClass(CRONET_URL_REQUEST_CLASS_DESCRIPTOR) + accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) } -internal val BytecodePatchContext.messageDigestImageUrlMethod by gettingFirstMutableMethodDeclaratively { +context(_: BytecodePatchContext) +internal fun ClassDef.getMessageDigestImageUrlMethod() = firstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameterTypes("Ljava/lang/String;", "L") } -internal val messageDigestImageUrlParentMethodMatch = firstMethodComposite { +internal val BytecodePatchContext.messageDigestImageUrlParentMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("Ljava/lang/String;") parameterTypes() - strings { + instructions( anyOf( - "@#&=*+-_.,:!?()/~'%;\$", - "@#&=*+-_.,:!?()/~'%;\$[]", // 20.38+ - ) - } + "@#&=*+-_.,:!?()/~'%;$"(), + "@#&=*+-_.,:!?()/~'%;$[]"(), // 20.38+ + ), + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt index 07219eced..36e96baa9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/Fingerprints.kt @@ -10,13 +10,10 @@ internal val abUriParserLegacyMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("Ljava/lang/Object;") parameterTypes("Ljava/lang/Object;") - strings { - // Partial string match - keep in instructions block - +"Found entityKey=`" - // "that does not contain a PlaylistVideoEntityId" - partial, skipped - } instructions( - method { smali == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" }, + "Found entityKey=`"(), + "that does not contain a PlaylistVideoEntityId"(String::contains), + method { toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" }, ) } @@ -30,10 +27,10 @@ internal val abUriParserMethodMatch = firstMethodComposite { instructions( // Method is a switch statement of unrelated code, // and there's no strings or anything unique to fingerprint. - method { smali == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" }, - method { smali == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" }, - method { smali == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" }, - method { smali == "Ljava/util/List;->get(I)Ljava/lang/Object;" }, + method { toString() == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" }, + method { toString() == "Ljava/lang/Boolean;->valueOf(Z)Ljava/lang/Boolean;" }, + method { toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" }, + method { toString() == "Ljava/util/List;->get(I)Ljava/lang/Object;" }, ) } @@ -42,11 +39,9 @@ internal val httpUriParserMethodMatch = firstMethodComposite { returnType("Landroid/net/Uri;") parameterTypes("Ljava/lang/String;") instructions( - method { smali == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" }, + method { toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" }, + "https"(), + "://"(), + "https:"(), ) - strings { - +"https" - +"://" - +"https:" - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt index 3f0009908..ad37bdb17 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/Fingerprints.kt @@ -12,6 +12,7 @@ import app.revanced.patcher.returnType import app.revanced.util.literal import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.ClassDef internal val BytecodePatchContext.videoQualityItemOnClickParentMethod by gettingFirstMethodDeclaratively( "VIDEO_QUALITIES_MENU_BOTTOM_SHEET_FRAGMENT", @@ -20,7 +21,7 @@ internal val BytecodePatchContext.videoQualityItemOnClickParentMethod by getting } context(_: BytecodePatchContext) -internal fun com.android.tools.smali.dexlib2.iface.ClassDef.getVideoQualityItemOnClickMethod() = firstMutableMethodDeclaratively { +internal fun ClassDef.getVideoQualityItemOnClickMethod() = firstMutableMethodDeclaratively { name("onItemClick") returnType("V") parameterTypes( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt index 8072fda61..77e1971d2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/CustomPlaybackSpeedPatch.kt @@ -140,7 +140,8 @@ internal val customPlaybackSpeedPatch = bytecodePatch( // Get the "showOldPlaybackSpeedMenu" method. // This is later called on the field INSTANCE. - val showOldPlaybackSpeedMenuMethod = getOldPlaybackSpeedsMethod.classDef.getShowOldPlaybackSpeedMenuMethod() + val showOldPlaybackSpeedMenuMethod = + getOldPlaybackSpeedsMethod.immutableClassDef.getShowOldPlaybackSpeedMenuMethod() // Insert the call to the "showOldPlaybackSpeedMenu" method on the field INSTANCE. showOldPlaybackSpeedMenuExtensionMethod.apply { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt index 3acd379b1..b3ed07bbf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt @@ -16,8 +16,8 @@ internal fun ClassDef.getVideoIdMethodMatch() = firstMethodComposite { parameterTypes("L") instructions( method { - definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" - && returnType == "Ljava/lang/String;" + definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" && + returnType == "Ljava/lang/String;" }, Opcode.MOVE_RESULT_OBJECT(), ) @@ -29,8 +29,8 @@ internal val videoIdBackgroundPlayMethodMatch = firstMethodComposite { parameterTypes("L") instructions( method { - definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" - && returnType == "Ljava/lang/String;" + definingClass == "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;" && + returnType == "Ljava/lang/String;" }, Opcode.MOVE_RESULT_OBJECT(), Opcode.IPUT_OBJECT(), @@ -40,11 +40,8 @@ internal val videoIdBackgroundPlayMethodMatch = firstMethodComposite { Opcode.RETURN_VOID(), ) custom { - implementation != null && - ( - definingClass.methods.count() == 17 || // 20.39 and lower. - definingClass.methods.count() == 16 - ) // 20.40+ + immutableClassDef.methods.count() == 17 || // 20.39 and lower. + immutableClassDef.methods.count() == 16 // 20.40+ } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt index 121827f79..1b342cf25 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/VideoIdPatch.kt @@ -92,17 +92,19 @@ val videoIdPatch = bytecodePatch( ) apply { - videoIdParentMethodMatch.classDef.getVideoIdMethodMatch().let { + videoIdParentMethodMatch.immutableClassDef.getVideoIdMethodMatch().let { videoIdMethod = it.method + val index = it.indices.first() - videoIdRegister = videoIdMethod.getInstruction(index + 1).registerA + videoIdRegister = it.method.getInstruction(index + 1).registerA videoIdInsertIndex = index + 2 } videoIdBackgroundPlayMethodMatch.let { backgroundPlaybackMethod = it.method + val index = it.indices.first() - backgroundPlaybackVideoIdRegister = backgroundPlaybackMethod.getInstruction(index + 1).registerA + backgroundPlaybackVideoIdRegister = it.method.getInstruction(index + 1).registerA backgroundPlaybackInsertIndex = index + 2 } }