From 8c72146bb9713b670cac506c157ae0393ba37fd3 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 23 Jan 2026 23:00:57 +0100 Subject: [PATCH] progress --- .../OverrideCertificatePinningPatch.kt | 8 +- .../misc/spoof/EnableRomSignatureSpoofing.kt | 28 +++--- .../patches/crunchyroll/ads/Fingerprints.kt | 11 ++- .../patches/crunchyroll/ads/HideAdsPatch.kt | 21 ++-- .../patches/duolingo/energy/Fingerprints.kt | 5 +- .../energy/SkipEnergyRechargeAdsPatch.kt | 29 +++--- .../facebook/ads/mainfeed/Fingerprints.kt | 9 +- .../ads/mainfeed/HideSponsoredStoriesPatch.kt | 13 ++- .../restrictions/Fingerprints.kt | 13 +-- .../restrictions/RemoveDeviceRestrictions.kt | 6 +- .../instagram/hide/explore/Fingerprints.kt | 14 +-- .../instagram/hide/explore/HideExploreFeed.kt | 29 ++---- .../instagram/hide/stories/Fingerprints.kt | 25 +++-- .../instagram/hide/stories/HideStories.kt | 11 +-- .../hide/suggestions/Fingerprints.kt | 14 ++- .../hide/suggestions/HideSuggestedContent.kt | 14 ++- .../music/layout/buttons/Fingerprints.kt | 47 ++++----- .../misc/unlock/plus/UnlockPlusPatch.kt | 2 +- .../infinityforreddit/api/SpoofClientPatch.kt | 3 +- .../misc/mapping/ResourceMappingPatch.kt | 15 +-- .../DisablePreciseSeekingGesturePatch.kt | 11 +-- .../interaction/seekbar/Fingerprints.kt | 81 ++++++++------- .../interaction/seekbar/HideSeekbarPatch.kt | 9 +- .../seekbar/SeekbarThumbnailsPatch.kt | 13 ++- .../interaction/swipecontrols/Fingerprints.kt | 2 +- .../layout/buttons/navigation/Fingerprints.kt | 12 +-- .../layout/buttons/overlay/Fingerprints.kt | 39 ++++---- .../overlay/HidePlayerOverlayButtonsPatch.kt | 59 +++++------ .../layout/hide/shorts/Fingerprints.kt | 4 +- .../youtube/layout/miniplayer/Fingerprints.kt | 10 +- .../returnyoutubedislike/Fingerprints.kt | 24 ++--- .../youtube/layout/seekbar/Fingerprints.kt | 4 +- .../layout/shortsplayer/Fingerprints.kt | 94 +++++++++--------- .../OpenShortsInRegularPlayerPatch.kt | 33 +++---- .../layout/sponsorblock/Fingerprints.kt | 69 +++++-------- .../layout/sponsorblock/SponsorBlockPatch.kt | 66 ++++++------- .../youtube/layout/startpage/Fingerprints.kt | 10 +- .../layout/startupshortsreset/Fingerprints.kt | 8 +- .../youtube/layout/theme/Fingerprints.kt | 8 +- .../youtube/misc/litho/filter/Fingerprints.kt | 18 ++-- .../misc/playercontrols/Fingerprints.kt | 10 +- .../youtube/misc/settings/Fingerprints.kt | 4 +- .../patches/youtube/shared/Fingerprints.kt | 44 +++++---- .../video/speed/custom/Fingerprints.kt | 8 +- .../youtube/video/videoid/Fingerprints.kt | 14 +-- .../kotlin/app/revanced/util/BytecodeUtils.kt | 98 +++++++++---------- 46 files changed, 514 insertions(+), 555 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt index b79c09d6a..50e23eefd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch.kt @@ -1,19 +1,17 @@ -@file:Suppress("ObjectPropertyName") - package app.revanced.patches.all.misc.network import app.revanced.patcher.patch.creatingResourcePatch -import app.revanced.patches.all.misc.debugging.enableAndroidDebuggingPatch +import app.revanced.patches.all.misc.debugging.`Enable Android debugging` import app.revanced.util.Utils.trimIndentMultiline import org.w3c.dom.Element import java.io.File -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Override certificate pinning` by creatingResourcePatch( description = "Overrides certificate pinning, allowing to inspect traffic via a proxy.", use = false, ) { - dependsOn(enableAndroidDebuggingPatch) + dependsOn(`Enable Android debugging`) apply { val resXmlDirectory = get("res/xml") diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/spoof/EnableRomSignatureSpoofing.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/spoof/EnableRomSignatureSpoofing.kt index 71792b2a4..d29081968 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/spoof/EnableRomSignatureSpoofing.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/spoof/EnableRomSignatureSpoofing.kt @@ -13,11 +13,10 @@ import java.security.cert.CertificateException import java.security.cert.CertificateFactory import java.util.* -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Enable ROM signature spoofing` = creatingResourcePatch( - name = "", description = "Spoofs the signature via the manifest meta-data \"fake-signature\". " + - "This patch only works with ROMs that support signature spoofing.", + "This patch only works with ROMs that support signature spoofing.", use = false, ) { val signatureOrPath by stringOption( @@ -37,7 +36,6 @@ val `Enable ROM signature spoofing` = creatingResourcePatch( } val manifest = document.getNode("manifest").appendChild(permission) - val fakeSignatureMetadata = document.createElement("meta-data").apply { setAttribute("android:name", "fake-signature") setAttribute("android:value", parseSignature(signatureOrPath!!)) @@ -68,15 +66,17 @@ private fun parseSignature(optionValue: String): String? { val hexFormat = HexFormat.of() - val signature = (if (result.isVerifiedUsingV3Scheme) { - result.v3SchemeSigners[0].certificate - } else if (result.isVerifiedUsingV2Scheme) { - result.v2SchemeSigners[0].certificate - } else if (result.isVerifiedUsingV1Scheme) { - result.v1SchemeSigners[0].certificate - } else { - return null - }).encoded + val signature = ( + if (result.isVerifiedUsingV3Scheme) { + result.v3SchemeSigners[0].certificate + } else if (result.isVerifiedUsingV2Scheme) { + result.v2SchemeSigners[0].certificate + } else if (result.isVerifiedUsingV1Scheme) { + result.v1SchemeSigners[0].certificate + } else { + return null + } + ).encoded return hexFormat.formatHex(signature) } catch (_: IOException) { @@ -87,4 +87,4 @@ private fun parseSignature(optionValue: String): String? { } return null -} \ No newline at end of file +} diff --git a/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/Fingerprints.kt index ea66fd257..98250799f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/Fingerprints.kt @@ -1,8 +1,9 @@ package app.revanced.patches.crunchyroll.ads -import app.revanced.patcher.gettingFirstMutableMethodDeclaratively -import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.firstMethodComposite +import app.revanced.patcher.instructions +import app.revanced.patcher.invoke -internal val BytecodePatchContext.videoUrlReadyToStringMethod by gettingFirstMutableMethodDeclaratively( - "VideoUrlReady(url=", ", enableAds=" -) +internal val videoUrlReadyToStringMethodMatch = firstMethodComposite { + instructions("VideoUrlReady(url="(), ", enableAds="()) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/HideAdsPatch.kt index 55602cd55..ce0f9597c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/HideAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/crunchyroll/ads/HideAdsPatch.kt @@ -1,6 +1,5 @@ package app.revanced.patches.crunchyroll.ads -import app.revanced.patcher.classDef import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.getInstruction import app.revanced.patcher.extensions.instructions @@ -13,34 +12,36 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Hide ads` by creatingBytecodePatch { compatibleWith("com.crunchyroll.crunchyroid") apply { // Get obfuscated "enableAds" field from toString method. - val enableAdsField = videoUrlReadyToStringMethod.let { - val strIndex = videoUrlReadyToStringMethod.stringMatches.last().index // TODO - val fieldIndex = it.indexOfFirstInstruction(strIndex, Opcode.IGET_BOOLEAN) - it.getInstruction(fieldIndex).getReference()!! + val enableAdsField = videoUrlReadyToStringMethodMatch.method.apply { + val stringIndex = videoUrlReadyToStringMethodMatch.indices.last() + val fieldIndex = indexOfFirstInstruction(stringIndex, Opcode.IGET_BOOLEAN) + + getInstruction(fieldIndex).getReference()!! } // Remove final access flag on field. - videoUrlReadyToStringMethod.classDef.fields + videoUrlReadyToStringMethodMatch.classDef.fields .first { it.name == enableAdsField.name } .removeFlags(AccessFlags.FINAL) // Override enableAds field in non-default constructor. - val constructor = videoUrlReadyToStringMethod.classDef.methods.first { + val constructor = videoUrlReadyToStringMethodMatch.classDef.methods.first { AccessFlags.CONSTRUCTOR.isSet(it.accessFlags) && it.parameters.isNotEmpty() } + constructor.addInstructions( constructor.instructions.count() - 1, """ move-object/from16 v0, p0 const/4 v1, 0x0 iput-boolean v1, v0, $enableAdsField - """ + """, ) } -} \ No newline at end of file +} diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt index b455cd7dd..abdd634eb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/Fingerprints.kt @@ -5,10 +5,7 @@ import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -/** - * Matches the class found in [initializeEnergyConfigMethod]. - */ -internal val BytecodePatchContext.initializeEnergyConfigMethod by gettingFirstMutableMethodDeclaratively { +internal val initializeEnergyConfigMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) opcodes(Opcode.RETURN_VOID) } diff --git a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt index abc20a427..3999b25ea 100644 --- a/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/duolingo/energy/SkipEnergyRechargeAdsPatch.kt @@ -5,27 +5,24 @@ import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.util.findFieldFromToString -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Skip energy recharge ads` by creatingBytecodePatch( - description = "Skips watching ads to recharge energy." + description = "Skips watching ads to recharge energy.", ) { compatibleWith("com.duolingo") apply { - initializeEnergyConfigMethod - .match(energyConfigToStringMethod.classDef) // TODO - .method.apply { - val energyField = energyConfigToStringMethod - .findFieldFromToString("energy=") - val insertIndex = initializeEnergyConfigMethod.patternMatch.startIndex // TODO + initializeEnergyConfigMethodMatch.match(energyConfigToStringMethod.classDef).method.apply { + val energyField = energyConfigToStringMethod.findFieldFromToString("energy=") + val insertIndex = initializeEnergyConfigMethodMatch.indices.first() // TODO - addInstructions( - insertIndex, - """ - const/16 v0, 99 - iput v0, p0, $energyField - """ - ) - } + addInstructions( + insertIndex, + """ + const/16 v0, 99 + iput v0, p0, $energyField + """, + ) + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt index 78704fd1c..3ec53872b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/Fingerprints.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal val BytecodePatchContext.baseModelMapperMethod by gettingFirstMutableMethodDeclaratively { +internal val BytecodePatchContext.baseModelMapperMethod by gettingFirstMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("Lcom/facebook/graphql/modelutil/BaseModelWithTree;") parameterTypes("Ljava/lang/Class", "I", "I") @@ -17,7 +17,7 @@ internal val BytecodePatchContext.baseModelMapperMethod by gettingFirstMutableMe Opcode.IF_EQ, ) } -internal val BytecodePatchContext.getSponsoredDataModelTemplateMethod by gettingFirstMutableMethodDeclaratively { +internal val BytecodePatchContext.getSponsoredDataModelTemplateMethod by gettingFirstMethodDeclaratively { definingClass("Lcom/facebook/graphql/model/GraphQLFBMultiAdsFeedUnit;") accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returnType("L") @@ -29,9 +29,8 @@ internal val BytecodePatchContext.getSponsoredDataModelTemplateMethod by getting Opcode.MOVE_RESULT_OBJECT, Opcode.RETURN_OBJECT, ) - } -internal val BytecodePatchContext.getStoryVisibilityMethod by gettingFirstMutableMethodDeclaratively("This should not be called for base class object") { +internal val getStoryVisibilityMethodMatch = firstMethodComposite("This should not be called for base class object") { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returnType("Ljava/lang/String;") opcodes( @@ -43,4 +42,4 @@ internal val BytecodePatchContext.getStoryVisibilityMethod by gettingFirstMutabl Opcode.IF_NEZ, Opcode.CONST, ) -} \ No newline at end of file +} diff --git a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt index 5fa2d1072..f8d3593cc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/facebook/ads/mainfeed/HideSponsoredStoriesPatch.kt @@ -10,13 +10,12 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Hide 'Sponsored Stories'` by creatingBytecodePatch { compatibleWith("com.facebook.katana"("490.0.0.63.82")) apply { - val sponsoredDataModelTemplateMethod = getSponsoredDataModelTemplateFingerprint.originalMethod - val baseModelMapperMethod = baseModelMapperFingerprint.originalMethod + val sponsoredDataModelTemplateMethod = getSponsoredDataModelTemplateMethod val baseModelWithTreeType = baseModelMapperMethod.returnType val graphQlStoryClassDescriptor = "Lcom/facebook/graphql/model/GraphQLStory;" @@ -26,7 +25,7 @@ val `Hide 'Sponsored Stories'` by creatingBytecodePatch { // could change in future version, we need to extract them and call the base implementation directly. val getSponsoredDataHelperMethod = ImmutableMethod( - getStoryVisibilityFingerprint.originalClassDef.type, + getStoryVisibilityMethodMatch.immutableClassDef.type, "getSponsoredData", listOf(ImmutableMethodParameter(graphQlStoryClassDescriptor, null, null)), baseModelWithTreeType, @@ -60,12 +59,12 @@ val `Hide 'Sponsored Stories'` by creatingBytecodePatch { ) } - getStoryVisibilityFingerprint.classDef.methods.add(getSponsoredDataHelperMethod) + getStoryVisibilityMethodMatch.classDef.methods.add(getSponsoredDataHelperMethod) // Check if the parameter type is GraphQLStory and if sponsoredDataModelGetter returns a non-null value. // If so, hide the story by setting the visibility to StoryVisibility.GONE. - getStoryVisibilityFingerprint.method.addInstructionsWithLabels( - getStoryVisibilityFingerprint.instructionMatches.first().index, + getStoryVisibilityMethodMatch.method.addInstructionsWithLabels( + getStoryVisibilityMethodMatch.indices.first(), """ instance-of v0, p0, $graphQlStoryClassDescriptor if-eqz v0, :resume_normal diff --git a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt index 62e1e5f16..8f4734bfc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/Fingerprints.kt @@ -1,12 +1,9 @@ package app.revanced.patches.googlerecorder.restrictions -import app.revanced.patcher.fingerprint +import app.revanced.patcher.* -internal val onApplicationCreateFingerprint = fingerprint { - strings("com.google.android.feature.PIXEL_2017_EXPERIENCE") - custom { method, classDef -> - if (method.name != "onCreate") return@custom false - - classDef.endsWith("RecorderApplication;") - } +internal val onApplicationCreateMethodMatch = firstMethodComposite { + name("onCreate") + definingClass("RecorderApplication"::endsWith) + instructions("com.google.android.feature.PIXEL_2017_EXPERIENCE"()) } diff --git a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt index 0f9285474..96db5ec27 100644 --- a/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt +++ b/patches/src/main/kotlin/app/revanced/patches/googlerecorder/restrictions/RemoveDeviceRestrictions.kt @@ -6,16 +6,16 @@ import app.revanced.patcher.extensions.removeInstructions import app.revanced.patcher.patch.creatingBytecodePatch import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Remove device restrictions` by creatingBytecodePatch( description = "Removes restrictions from using the app on any device. Requires mounting patched app over original.", ) { compatibleWith("com.google.android.apps.recorder") apply { - val featureStringIndex = onApplicationCreateFingerprint.stringMatches.first().index + val featureStringIndex = onApplicationCreateMethodMatch.indices.first() - onApplicationCreateFingerprint.method.apply { + onApplicationCreateMethodMatch.method.apply { // Remove check for device restrictions. removeInstructions(featureStringIndex - 2, 5) diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt index a85e8eb30..cfaaa2604 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/Fingerprints.kt @@ -1,11 +1,11 @@ - package app.revanced.patches.instagram.hide.explore -import app.revanced.patcher.fingerprint +import app.revanced.patcher.firstMethodComposite +import app.revanced.patcher.instructions +import app.revanced.patcher.invoke +import app.revanced.patcher.name -internal const val EXPLORE_KEY_TO_BE_HIDDEN = "sectional_items" - -internal val exploreResponseJsonParserFingerprint = fingerprint { - strings(EXPLORE_KEY_TO_BE_HIDDEN, "ExploreTopicalFeedResponse") - custom { method, _ -> method.name == "parseFromJson" } +internal val exploreResponseJsonParserMethodMatch = firstMethodComposite("ExploreTopicalFeedResponse") { + name("parseFromJson") + instructions("sectional_items"()) } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt index da5eb3b7d..aef1e893a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/explore/HideExploreFeed.kt @@ -1,31 +1,11 @@ package app.revanced.patches.instagram.hide.explore -import app.revanced.patcher.Fingerprint import app.revanced.patcher.extensions.getInstruction import app.revanced.patcher.extensions.replaceInstruction -import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.patch.creatingBytecodePatch import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -context(BytecodePatchContext) -internal fun Fingerprint.replaceJsonFieldWithBogus( - key: String, -) { - val targetStringIndex = stringMatches.first { match -> match.string == key }.index - val targetStringRegister = method.getInstruction(targetStringIndex).registerA - - /** - * Replacing the JSON key we want to skip with a random string that is not a valid JSON key. - * This way the feeds array will never be populated. - * Received JSON keys that are not handled are simply ignored, so there are no side effects. - */ - method.replaceInstruction( - targetStringIndex, - "const-string v$targetStringRegister, \"BOGUS\"", - ) -} - -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Hide explore feed` by creatingBytecodePatch( description = "Hides posts and reels from the explore/search page.", use = false, @@ -33,6 +13,11 @@ val `Hide explore feed` by creatingBytecodePatch( compatibleWith("com.instagram.android") apply { - exploreResponseJsonParserFingerprint.replaceJsonFieldWithBogus(EXPLORE_KEY_TO_BE_HIDDEN) + exploreResponseJsonParserMethodMatch.method.apply { + val targetStringIndex = exploreResponseJsonParserMethodMatch.indices.first() + val targetStringRegister = getInstruction(targetStringIndex).registerA + + replaceInstruction(targetStringIndex, "const-string v$targetStringRegister, \"BOGUS\"") + } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/Fingerprints.kt index b39cd7b83..54ed1888d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/Fingerprints.kt @@ -1,16 +1,15 @@ package app.revanced.patches.instagram.hide.stories -import app.revanced.patcher.fingerprint + +import app.revanced.patcher.* import com.android.tools.smali.dexlib2.Opcode -internal val getOrCreateAvatarViewFingerprint = fingerprint { - parameters() - returns("L") - custom { method, classDef -> - classDef.type == "Lcom/instagram/reels/ui/views/reelavatar/RecyclerReelAvatarView;" - } - opcodes( - Opcode.INVOKE_VIRTUAL, - Opcode.IPUT_OBJECT, - Opcode.INVOKE_VIRTUAL // Add View (Story) - ) - } +internal val getOrCreateAvatarViewMethod = firstMethodComposite { + definingClass("Lcom/instagram/reels/ui/views/reelavatar/RecyclerReelAvatarView;") + parameterTypes() + returnType("L") + opcodes( + Opcode.INVOKE_VIRTUAL, + Opcode.IPUT_OBJECT, + Opcode.INVOKE_VIRTUAL, // Add View (Story). + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/HideStories.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/HideStories.kt index 66af06e8a..1c3d23b7a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/HideStories.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/stories/HideStories.kt @@ -3,18 +3,17 @@ package app.revanced.patches.instagram.hide.stories import app.revanced.patcher.extensions.removeInstruction import app.revanced.patcher.patch.creatingBytecodePatch -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Hide Stories from Home` by creatingBytecodePatch( description = "Hides Stories from the main page, by removing the buttons.", - use = false + use = false, ) { compatibleWith("com.instagram.android") apply { - val addStoryMethod = getOrCreateAvatarViewFingerprint.method // Creates Story - val addStoryEndIndex = getOrCreateAvatarViewFingerprint.patternMatch.endIndex + val addStoryEndIndex = getOrCreateAvatarViewMethod.indices.last() // Remove addView of Story. - addStoryMethod.removeInstruction(addStoryEndIndex) + getOrCreateAvatarViewMethod.method.removeInstruction(addStoryEndIndex) } -} \ No newline at end of file +} diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/Fingerprints.kt index 0f731b4f4..5093f7aba 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/Fingerprints.kt @@ -1,6 +1,9 @@ package app.revanced.patches.instagram.hide.suggestions -import app.revanced.patcher.fingerprint +import app.revanced.patcher.firstMethodComposite +import app.revanced.patcher.instructions +import app.revanced.patcher.invoke +import app.revanced.patcher.unorderedAllOf internal val FEED_ITEM_KEYS_TO_BE_HIDDEN = arrayOf( "clips_netego", @@ -12,6 +15,11 @@ internal val FEED_ITEM_KEYS_TO_BE_HIDDEN = arrayOf( "suggested_users", ) -internal val feedItemParseFromJsonFingerprint = fingerprint { - strings(*FEED_ITEM_KEYS_TO_BE_HIDDEN, "FeedItem") +internal val feedItemParseFromJsonMethodMatch = firstMethodComposite("FeedItem") { + instructions( + predicates = unorderedAllOf( + predicates = + FEED_ITEM_KEYS_TO_BE_HIDDEN.map { it.invoke() }.toTypedArray(), + ), + ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/HideSuggestedContent.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/HideSuggestedContent.kt index f0970858a..fd95359b3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/HideSuggestedContent.kt +++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/suggestions/HideSuggestedContent.kt @@ -1,9 +1,11 @@ package app.revanced.patches.instagram.hide.suggestions +import app.revanced.patcher.extensions.getInstruction +import app.revanced.patcher.extensions.replaceInstruction import app.revanced.patcher.patch.creatingBytecodePatch -import app.revanced.patches.instagram.hide.explore.replaceJsonFieldWithBogus +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Hide suggested content` by creatingBytecodePatch( description = "Hides suggested stories, reels, threads and survey from feed (Suggested posts will still be shown).", use = false, @@ -11,8 +13,12 @@ val `Hide suggested content` by creatingBytecodePatch( compatibleWith("com.instagram.android") apply { - FEED_ITEM_KEYS_TO_BE_HIDDEN.forEach { key -> - feedItemParseFromJsonFingerprint.replaceJsonFieldWithBogus(key) + feedItemParseFromJsonMethodMatch.method.apply { + feedItemParseFromJsonMethodMatch.indices.forEach { targetStringIndex -> + val targetStringRegister = getInstruction(targetStringIndex).registerA + + replaceInstruction(targetStringIndex, "const-string v$targetStringRegister, \"BOGUS\"") + } } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/Fingerprints.kt index 31c844aea..bb097c00f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/buttons/Fingerprints.kt @@ -18,47 +18,48 @@ internal val playerOverlayChipFingerprint = fingerprint { literal { playerOverlayChip } } -internal val historyMenuItemFingerprint = fingerprint { +internal val BytecodePatchContext.historyMenuItemMethod by gettingFirstMutableMethodDeclaratively { + definingClass { + it.methods.count() + methods.count() + } accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters("Landroid/view/Menu;") + returnType("V") + parameterTypes("Landroid/view/Menu;") opcodes( Opcode.INVOKE_INTERFACE, - Opcode.RETURN_VOID + Opcode.RETURN_VOID, ) - literal { historyMenuItem } + historyMenuItem() custom { _, classDef -> classDef.methods.count() == 5 } } -internal val historyMenuItemOfflineTabFingerprint = fingerprint { +internal val BytecodePatchContext.historyMenuItemOfflineTabMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters("Landroid/view/Menu;") + returnType("V") + parameterTypes("Landroid/view/Menu;") opcodes( Opcode.INVOKE_INTERFACE, - Opcode.RETURN_VOID + Opcode.RETURN_VOID, ) - custom { method, _ -> - method.containsLiteralInstruction(historyMenuItem) && - method.containsLiteralInstruction(offlineSettingsMenuItem) + custom { + instructions.matchIndexed("literals", items = unorderedAllOf(historyMenuItem(), offlineSettingsMenuItem())) } } -internal val searchActionViewFingerprint = fingerprint { +internal val BytecodePatchContext.searchActionViewMethod by gettingFirstMutableMethodDeclaratively { + definingClass("/SearchActionProvider;"::endsWith) accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Landroid/view/View;") - parameters() - literal { searchButton } - custom { _, classDef -> - classDef.type.endsWith("/SearchActionProvider;") - } + returnType("Landroid/view/View;") + parameterTypes() + searchButton() } -internal val topBarMenuItemImageViewFingerprint = fingerprint { +internal val BytecodePatchContext.topBarMenuItemImageViewMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Landroid/view/View;") - parameters() - literal { topBarMenuItemImageView } + returnType("Landroid/view/View;") + parameterTypes() + topBarMenuItemImageView() } diff --git a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/UnlockPlusPatch.kt b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/UnlockPlusPatch.kt index 77d32d815..f113bed25 100644 --- a/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/UnlockPlusPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/photomath/misc/unlock/plus/UnlockPlusPatch.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.photomath.detection.signature.signatureDetectionPatch import app.revanced.patches.photomath.misc.unlock.bookpoint.enableBookpointPatch -@Suppress("unused") +@Suppress("unused", "ObjectPropertyName") val `Unlock plus` by creatingBytecodePatch { dependsOn(signatureDetectionPatch, enableBookpointPatch) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch.kt index c027bfef8..3ec6a11d1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/customclients/infinityforreddit/api/SpoofClientPatch.kt @@ -1,5 +1,6 @@ package app.revanced.patches.reddit.customclients.infinityforreddit.api +import app.revanced.patcher.classDef import app.revanced.patcher.extensions.toInstructions import app.revanced.patches.reddit.customclients.spoofClientPatch import com.android.tools.smali.dexlib2.AccessFlags @@ -11,7 +12,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "infinity://localhost") { compatibleWith( "ml.docilealligator.infinityforreddit", "ml.docilealligator.infinityforreddit.plus", - "ml.docilealligator.infinityforreddit.patreon" + "ml.docilealligator.infinityforreddit.patreon", ) val clientId by clientIdOption diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt index cba06feda..7c528e1a5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/mapping/ResourceMappingPatch.kt @@ -1,6 +1,6 @@ package app.revanced.patches.shared.misc.mapping -import app.revanced.patcher.Predicate +import app.revanced.patcher.IndexedMatcherPredicate import app.revanced.patcher.extensions.wideLiteral import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.resourcePatch @@ -35,10 +35,10 @@ enum class ResourceType(val value: String) { XML("xml"), ; - operator fun invoke(name: String): Predicate { - val id = getResourceId(this, name) + operator fun invoke(name: String): IndexedMatcherPredicate { + val id = get(name) - return { wideLiteral == id } + return { _, _, _ -> wideLiteral == id } } /** @@ -60,13 +60,6 @@ data class ResourceElement(val type: ResourceType, val name: String, val id: Lon private lateinit var resourceMappings: MutableMap -/** - * @return A resource id of the given resource type and name. - * @throws PatchException if the resource is not found. - */ -fun getResourceId(type: ResourceType, name: String) = resourceMappings[type.value + name]?.id - ?: throw PatchException("Could not find resource type: $type name: $name") - val resourceMappingPatch = resourcePatch { apply { // Use a stream of the file, since no modifications are done diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt index 8114c661f..18af02c1e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt @@ -1,9 +1,10 @@ package app.revanced.patches.youtube.interaction.seekbar +import app.revanced.patcher.extensions.ExternalLabel import app.revanced.patcher.extensions.addInstructionsWithLabels import app.revanced.patcher.extensions.getInstruction +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patcher.extensions.ExternalLabel import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.settings.preference.SwitchPreference @@ -30,9 +31,7 @@ val disablePreciseSeekingGesturePatch = bytecodePatch( SwitchPreference("revanced_disable_precise_seeking_gesture"), ) - allowSwipingUpGestureFingerprint.match( - swipingUpGestureParentFingerprint.originalClassDef, - ).method.apply { + swipingUpGestureParentMethod.immutableClassDef.getAllowSwipingUpGestureMethod().apply { addInstructionsWithLabels( 0, """ @@ -45,9 +44,7 @@ val disablePreciseSeekingGesturePatch = bytecodePatch( ) } - showSwipingUpGuideFingerprint.match( - swipingUpGestureParentFingerprint.originalClassDef, - ).method.apply { + swipingUpGestureParentMethod.immutableClassDef.getShowSwipingUpGuideMethod().apply { addInstructionsWithLabels( 0, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt index 39479e114..397951b35 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/Fingerprints.kt @@ -2,12 +2,21 @@ package app.revanced.patches.youtube.interaction.seekbar import app.revanced.patcher.InstructionLocation.MatchAfterImmediately import app.revanced.patcher.InstructionLocation.MatchAfterWithin +import app.revanced.patcher.accessFlags import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint -import app.revanced.patcher.literal +import app.revanced.patcher.firstMethodComposite +import app.revanced.patcher.firstMutableMethodDeclaratively +import app.revanced.patcher.gettingFirstMethodDeclaratively +import app.revanced.patcher.gettingFirstMutableMethodDeclaratively +import app.revanced.patcher.instructions +import app.revanced.patcher.invoke import app.revanced.patcher.methodCall import app.revanced.patcher.newInstance import app.revanced.patcher.opcode +import app.revanced.patcher.parameterTypes +import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.returnType import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_47_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_19_or_greater @@ -18,35 +27,36 @@ import app.revanced.util.indexOfFirstInstruction 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 import com.android.tools.smali.dexlib2.iface.reference.StringReference -internal val swipingUpGestureParentFingerprint = fingerprint { - returns("Z") - parameters() +internal val BytecodePatchContext.swipingUpGestureParentMethod by gettingFirstMethodDeclaratively { + returnType("Z") + parameterTypes() instructions( - literal(45379021) // Swipe up fullscreen feature flag + 45379021L(), // Swipe up fullscreen feature flag ) } /** - * Resolves using the class found in [swipingUpGestureParentFingerprint]. + * Resolves using the class found in [swipingUpGestureParentMethod]. */ -internal val showSwipingUpGuideFingerprint = fingerprint { +context(_: BytecodePatchContext) +internal fun ClassDef.getShowSwipingUpGuideMethod() = firstMutableMethodDeclaratively { accessFlags(AccessFlags.FINAL) - returns("Z") - parameters() - instructions( - literal(1) - ) + returnType("Z") + parameterTypes() + instructions(1L()) } /** - * Resolves using the class found in [swipingUpGestureParentFingerprint]. + * Resolves using the class found in [swipingUpGestureParentMethod]. */ -internal val allowSwipingUpGestureFingerprint = fingerprint { +context(_: BytecodePatchContext) +internal fun ClassDef.getAllowSwipingUpGestureMethod() = firstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters("L") + returnType("V") + parameterTypes("L") } internal val disableFastForwardLegacyFingerprint = fingerprint { @@ -54,7 +64,7 @@ internal val disableFastForwardLegacyFingerprint = fingerprint { parameters() opcodes(Opcode.MOVE_RESULT) // Intent start flag only used in the subscription activity - literal {45411330} + literal { 45411330 } } internal val disableFastForwardGestureFingerprint = fingerprint { @@ -77,17 +87,17 @@ internal val customTapAndHoldFingerprint = fingerprint { returns("V") parameters() instructions( - literal(2.0f) + 2.0f(), ) custom { method, _ -> // Code is found in different methods with different strings. - val findSearchLandingKey = (is_19_34_or_greater && !is_19_47_or_greater) - || (is_20_19_or_greater && !is_20_20_or_greater) || is_20_31_or_greater + val findSearchLandingKey = (is_19_34_or_greater && !is_19_47_or_greater) || + (is_20_19_or_greater && !is_20_20_or_greater) || is_20_31_or_greater method.name == "run" && method.indexOfFirstInstruction { val string = getReference()?.string - string == "Failed to easy seek haptics vibrate." - || (findSearchLandingKey && string == "search_landing_cache_key") + string == "Failed to easy seek haptics vibrate." || + (findSearchLandingKey && string == "search_landing_cache_key") } >= 0 } } @@ -120,15 +130,18 @@ internal val seekbarTappingFingerprint = fingerprint { returns("Z") parameters("Landroid/view/MotionEvent;") instructions( - literal(Int.MAX_VALUE), + Int.MAX_VALUE(), newInstance("Landroid/graphics/Point;"), methodCall(smali = "Landroid/graphics/Point;->(II)V", location = MatchAfterImmediately()), - methodCall(smali = "Lj\$/util/Optional;->of(Ljava/lang/Object;)Lj\$/util/Optional;", location = MatchAfterImmediately()), + methodCall( + smali = "Lj\$/util/Optional;->of(Ljava/lang/Object;)Lj\$/util/Optional;", + location = MatchAfterImmediately(), + ), opcode(Opcode.MOVE_RESULT_OBJECT, location = MatchAfterImmediately()), fieldAccess(opcode = Opcode.IPUT_OBJECT, type = "Lj\$/util/Optional;", location = MatchAfterImmediately()), - opcode(Opcode.INVOKE_VIRTUAL, location = MatchAfterWithin(10)) + opcode(Opcode.INVOKE_VIRTUAL, location = MatchAfterWithin(10)), ) custom { method, _ -> method.name == "onTouchEvent" } } @@ -146,20 +159,18 @@ internal val slideToSeekFingerprint = fingerprint { literal { 67108864 } } -internal val fullscreenSeekbarThumbnailsQualityFingerprint = fingerprint { +internal val BytecodePatchContext.fullscreenSeekbarThumbnailsQualityMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Z") - parameters() + returnType("Z") + parameterTypes() instructions( - literal(45399684L) // Video stream seekbar thumbnails feature flag. + 45399684L(), // Video stream seekbar thumbnails feature flag. ) } -internal val fullscreenLargeSeekbarFeatureFlagFingerprint = fingerprint { +internal val fullscreenLargeSeekbarFeatureFlagMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Z") - parameters() - instructions( - literal(45691569) - ) + returnType("Z") + parameterTypes() + instructions(45691569L()) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt index 3ca21258e..a9cf4a411 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/HideSeekbarPatch.kt @@ -1,6 +1,7 @@ package app.revanced.patches.youtube.interaction.seekbar import app.revanced.patcher.extensions.addInstructionsWithLabels +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch @@ -11,8 +12,8 @@ import app.revanced.patches.youtube.misc.playservice.is_20_28_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.patches.youtube.shared.seekbarFingerprint -import app.revanced.patches.youtube.shared.seekbarOnDrawFingerprint +import app.revanced.patches.youtube.shared.getSeekbarOnDrawMethodMatch +import app.revanced.patches.youtube.shared.seekbarMethod import app.revanced.util.insertLiteralOverride private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/HideSeekbarPatch;" @@ -37,7 +38,7 @@ val hideSeekbarPatch = bytecodePatch( SwitchPreference("revanced_fullscreen_large_seekbar"), ) - seekbarOnDrawFingerprint.match(seekbarFingerprint.originalClassDef).method.addInstructionsWithLabels( + getSeekbarOnDrawMethodMatch().match(seekbarMethod.immutableClassDef).method.addInstructionsWithLabels( 0, """ const/4 v0, 0x0 @@ -51,7 +52,7 @@ val hideSeekbarPatch = bytecodePatch( ) if (is_20_28_or_greater) { - fullscreenLargeSeekbarFeatureFlagFingerprint.let { + fullscreenLargeSeekbarFeatureFlagMethodMatch.let { it.method.insertLiteralOverride( it.instructionMatches.first().index, "$EXTENSION_CLASS_DESCRIPTOR->useFullscreenLargeSeekbar(Z)Z" diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatch.kt index a2e353a73..6904d9615 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarThumbnailsPatch.kt @@ -13,13 +13,12 @@ import app.revanced.patches.youtube.misc.playservice.is_19_17_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_09_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen -import java.util.logging.Logger private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/SeekbarThumbnailsPatch;" val seekbarThumbnailsPatch = bytecodePatch( - description = "Adds an option to use high quality fullscreen seekbar thumbnails." + description = "Adds an option to use high quality fullscreen seekbar thumbnails.", ) { dependsOn( sharedExtensionPatch, @@ -38,7 +37,7 @@ val seekbarThumbnailsPatch = bytecodePatch( if (is_19_17_or_greater) { PreferenceScreen.SEEKBAR.addPreferences( - SwitchPreference("revanced_seekbar_thumbnails_high_quality") + SwitchPreference("revanced_seekbar_thumbnails_high_quality"), ) } else { PreferenceScreen.SEEKBAR.addPreferences( @@ -46,8 +45,8 @@ val seekbarThumbnailsPatch = bytecodePatch( SwitchPreference( key = "revanced_seekbar_thumbnails_high_quality", summaryOnKey = "revanced_seekbar_thumbnails_high_quality_legacy_summary_on", - summaryOffKey = "revanced_seekbar_thumbnails_high_quality_legacy_summary_on" - ) + summaryOffKey = "revanced_seekbar_thumbnails_high_quality_legacy_summary_on", + ), ) fullscreenSeekbarThumbnailsFingerprint.method.apply { @@ -60,13 +59,13 @@ val seekbarThumbnailsPatch = bytecodePatch( } } - fullscreenSeekbarThumbnailsQualityFingerprint.method.addInstructions( + fullscreenSeekbarThumbnailsQualityMethod.addInstructions( 0, """ invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->useHighQualityFullscreenThumbnails()Z move-result v0 return v0 - """ + """, ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt index 9c6eae324..c2c5fce2d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/Fingerprints.kt @@ -15,6 +15,6 @@ internal val swipeControlsHostActivityFingerprint = fingerprint { internal val swipeChangeVideoFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) instructions( - literal(45631116L) // Swipe to change fullscreen video feature flag. + 45631116L(), // Swipe to change fullscreen video feature flag. ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt index a72ccfd6d..e530f881d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/Fingerprints.kt @@ -1,11 +1,11 @@ package app.revanced.patches.youtube.layout.buttons.navigation import app.revanced.patcher.InstructionLocation.MatchAfterImmediately +import app.revanced.patcher.addString import app.revanced.patcher.fingerprint import app.revanced.patcher.literal import app.revanced.patcher.methodCall import app.revanced.patcher.opcode -import app.revanced.patcher.addString import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -26,7 +26,7 @@ internal val createPivotBarFingerprint = fingerprint { ) instructions( methodCall(definingClass = "Landroid/widget/TextView;", name = "setText"), - opcode(Opcode.RETURN_VOID) + opcode(Opcode.RETURN_VOID), ) } @@ -34,7 +34,7 @@ internal val animatedNavigationTabsFeatureFlagFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") instructions( - literal(45680008L) + 45680008L(), ) } @@ -42,7 +42,7 @@ internal val translucentNavigationStatusBarFeatureFlagFingerprint = fingerprint accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") instructions( - literal(45400535L) // Translucent status bar feature flag. + 45400535L(), // Translucent status bar feature flag. ) } @@ -53,7 +53,7 @@ internal val translucentNavigationButtonsFeatureFlagFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("V") instructions( - literal(45630927L) // Translucent navigation bar buttons feature flag. + 45630927L(), // Translucent navigation bar buttons feature flag. ) } @@ -64,6 +64,6 @@ internal val translucentNavigationButtonsSystemFeatureFlagFingerprint = fingerpr accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") instructions( - literal(45632194L) // Translucent system buttons feature flag. + 45632194L(), // Translucent system buttons feature flag. ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt index 0634220d9..ed9a1eba1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/Fingerprints.kt @@ -1,38 +1,33 @@ package app.revanced.patches.youtube.layout.buttons.overlay -import app.revanced.patcher.fingerprint -import app.revanced.patcher.literal -import app.revanced.patcher.methodCall +import app.revanced.patcher.* +import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patches.shared.misc.mapping.ResourceType +import app.revanced.patches.shared.misc.mapping.ResourceType.IndexedMatcherPredicateExtension.invoke import com.android.tools.smali.dexlib2.AccessFlags -internal val mediaRouteButtonFingerprint = fingerprint { - parameters("I") - custom { methodDef, _ -> - methodDef.definingClass.endsWith("/MediaRouteButton;") && methodDef.name == "setVisibility" - } +internal val BytecodePatchContext.mediaRouteButtonMethod by gettingFirstMutableMethodDeclaratively { + name("setVisibility") + definingClass("/MediaRouteButton;"::endsWith) + parameterTypes("I") } -internal val castButtonPlayerFeatureFlagFingerprint = fingerprint { - returns("Z") - instructions( - literal(45690091), - ) +internal val castButtonPlayerFeatureFlagMethodMatch = firstMethodComposite { + returnType("Z") + instructions(45690091L()) } -internal val castButtonActionFeatureFlagFingerprint = fingerprint { - returns("Z") - instructions( - literal(45690090), - ) +internal val castButtonActionFeatureFlagMethodMatch = firstMethodComposite { + returnType("Z") + instructions(45690090L()) } -internal val inflateControlsGroupLayoutStubFingerprint = fingerprint { +internal val inflateControlsGroupLayoutStubMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - parameters() - returns("V") + parameterTypes() + returnType("V") instructions( ResourceType.ID("youtube_controls_button_group_layout_stub"), - methodCall(name = "inflate"), + method("inflate"), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt index dd18b5c2b..412e51b45 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt @@ -11,7 +11,7 @@ import app.revanced.patches.youtube.misc.playservice.is_20_28_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.patches.youtube.shared.layoutConstructorFingerprint +import app.revanced.patches.youtube.shared.getLayoutConstructorMethodMatch import app.revanced.patches.youtube.shared.subtitleButtonControllerFingerprint import app.revanced.util.* import com.android.tools.smali.dexlib2.Opcode @@ -22,16 +22,17 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/HidePlayerOverlayButtonsPatch;" +@Suppress("ObjectPropertyName") val `Hide player overlay buttons` by creatingBytecodePatch( description = "Adds options to hide the player Cast, Autoplay, Captions, Previous & Next buttons, and the player " + - "control buttons background.", + "control buttons background.", ) { dependsOn( sharedExtensionPatch, settingsPatch, addResourcesPatch, resourceMappingPatch, // Used by fingerprints. - versionCheckPatch + versionCheckPatch, ) compatibleWith( @@ -40,7 +41,7 @@ val `Hide player overlay buttons` by creatingBytecodePatch( "20.14.43", "20.21.37", "20.31.40", - ) + ), ) apply { @@ -56,44 +57,38 @@ val `Hide player overlay buttons` by creatingBytecodePatch( // region Hide player next/previous button. - layoutConstructorFingerprint.let { - it.clearMatch() // Fingerprint is shared with other patches. + getLayoutConstructorMethodMatch().let { + val insertIndex = it.indices.last() + val viewRegister = it.method.getInstruction(insertIndex).registerC - it.method.apply { - val insertIndex = it.instructionMatches.last().index - val viewRegister = getInstruction(insertIndex).registerC - - addInstruction( - insertIndex, - "invoke-static { v$viewRegister }, $EXTENSION_CLASS_DESCRIPTOR" + - "->hidePreviousNextButtons(Landroid/view/View;)V", - ) - } + it.method.addInstruction( + insertIndex, + "invoke-static { v$viewRegister }, $EXTENSION_CLASS_DESCRIPTOR" + + "->hidePreviousNextButtons(Landroid/view/View;)V", + ) } // endregion // region Hide cast button. - mediaRouteButtonFingerprint.method.addInstructions( + mediaRouteButtonMethod.addInstructions( 0, """ invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->getCastButtonOverrideV2(I)I move-result p1 - """ + """, ) if (is_20_28_or_greater) { arrayOf( - castButtonPlayerFeatureFlagFingerprint, - castButtonActionFeatureFlagFingerprint - ).forEach { fingerprint -> - fingerprint.let { - it.method.insertLiteralOverride( - it.instructionMatches.first().index, - "$EXTENSION_CLASS_DESCRIPTOR->getCastButtonOverrideV2(Z)Z" - ) - } + castButtonPlayerFeatureFlagMethodMatch, + castButtonActionFeatureFlagMethodMatch, + ).forEach { match -> + match.method.insertLiteralOverride( + match.indices.first(), + "$EXTENSION_CLASS_DESCRIPTOR->getCastButtonOverrideV2(Z)Z", + ) } } @@ -114,7 +109,7 @@ val `Hide player overlay buttons` by creatingBytecodePatch( // region Hide autoplay button. - layoutConstructorFingerprint.method.apply { + getLayoutConstructorMethodMatch().method.apply { val constIndex = indexOfFirstResourceIdOrThrow("autonav_toggle") val constRegister = getInstruction(constIndex).registerA @@ -122,8 +117,8 @@ val `Hide player overlay buttons` by creatingBytecodePatch( val gotoIndex = indexOfFirstInstructionOrThrow(constIndex) { val parameterTypes = getReference()?.parameterTypes opcode == Opcode.INVOKE_VIRTUAL && - parameterTypes?.size == 2 && - parameterTypes.first() == "Landroid/view/ViewStub;" + parameterTypes?.size == 2 && + parameterTypes.first() == "Landroid/view/ViewStub;" } + 1 addInstructionsWithLabels( @@ -141,7 +136,7 @@ val `Hide player overlay buttons` by creatingBytecodePatch( // region Hide player control buttons background. - inflateControlsGroupLayoutStubFingerprint.let { + inflateControlsGroupLayoutStubMethodMatch.let { it.method.apply { val insertIndex = it.instructionMatches.last().index + 1 val freeRegister = findFreeRegister(insertIndex) @@ -153,7 +148,7 @@ val `Hide player overlay buttons` by creatingBytecodePatch( # The result of the inflate method is by default not moved to a register after the method is called. move-result-object v$freeRegister invoke-static { v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->hidePlayerControlButtonsBackground(Landroid/view/View;)V - """ + """, ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt index 2dd478d63..0705200fd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/Fingerprints.kt @@ -115,7 +115,7 @@ internal val shortsExperimentalPlayerFeatureFlagFingerprint = fingerprint { returns("Z") parameters() instructions( - literal(45677719L), + 45677719L(), ) } @@ -124,6 +124,6 @@ internal val renderNextUIFeatureFlagFingerprint = fingerprint { returns("Z") parameters() instructions( - literal(45649743L), + 45649743L(), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt index 5cbaf9705..d3cab0140 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/Fingerprints.kt @@ -28,7 +28,7 @@ internal const val MINIPLAYER_ANIMATED_EXPAND_FEATURE_KEY = 45644360L internal val miniplayerModernConstructorFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) instructions( - literal(45623000L), // Magic number found in the constructor. + 45623000L(), // Magic number found in the constructor. ) } @@ -93,7 +93,7 @@ internal val miniplayerModernExpandCloseDrawablesFingerprint = fingerprint { returns("V") parameters("L") instructions( - literal(ytOutlinePictureInPictureWhite24), + ytOutlinePictureInPictureWhite24(), ) } @@ -149,8 +149,8 @@ internal val miniplayerMinimumSizeFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) instructions( ResourceType.DIMEN("miniplayer_max_size"), - literal(192), // Default miniplayer width constant. - literal(128), // Default miniplayer height constant. + 192(), // Default miniplayer width constant. + 128(), // Default miniplayer height constant. ) } @@ -196,7 +196,7 @@ internal val miniplayerOnCloseHandlerFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") instructions( - literal(MINIPLAYER_DISABLED_FEATURE_KEY), + MINIPLAYER_DISABLED_FEATURE_KEY(), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt index ac26ef6f5..56af753d4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/Fingerprints.kt @@ -1,29 +1,29 @@ package app.revanced.patches.youtube.layout.returnyoutubedislike +import app.revanced.patcher.addString import app.revanced.patcher.fingerprint import app.revanced.patcher.literal -import app.revanced.patcher.addString import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode internal val dislikeFingerprint = fingerprint { returns("V") instructions( - addString("like/dislike") + addString("like/dislike"), ) } internal val likeFingerprint = fingerprint { returns("V") instructions( - addString("like/like") + addString("like/like"), ) } internal val removeLikeFingerprint = fingerprint { returns("V") instructions( - addString("like/removelike") + addString("like/removelike"), ) } @@ -65,7 +65,7 @@ internal val rollingNumberMeasureStaticLabelParentFingerprint = fingerprint { returns("Ljava/lang/String;") parameters() instructions( - addString("RollingNumberFontProperties{paint=") + addString("RollingNumberFontProperties{paint="), ) } @@ -92,14 +92,14 @@ internal val rollingNumberTextViewFingerprint = fingerprint { ) custom { _, classDef -> classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;" || classDef.superclass == - "Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;" + "Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;" } } internal val textComponentConstructorFingerprint = fingerprint { accessFlags(AccessFlags.CONSTRUCTOR, AccessFlags.PRIVATE) instructions( - addString("TextComponent") + addString("TextComponent"), ) } @@ -107,7 +107,7 @@ internal val textComponentDataFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR) parameters("L", "L") instructions( - addString("text") + addString("text"), ) custom { _, classDef -> classDef.fields.find { it.type == "Ljava/util/BitSet;" } != null @@ -122,7 +122,7 @@ internal val textComponentLookupFingerprint = fingerprint { returns("L") parameters("L") instructions( - addString("…") + addString("…"), ) } @@ -130,7 +130,7 @@ internal val textComponentFeatureFlagFingerprint = fingerprint { accessFlags(AccessFlags.FINAL) returns("Z") parameters() - instructions ( - literal(45675738L) + instructions( + 45675738L(), ) -} \ No newline at end of file +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt index 39d978ad5..ba5b2e5a3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/Fingerprints.kt @@ -17,7 +17,7 @@ internal val fullscreenSeekbarThumbnailsFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters() instructions( - literal(45398577), + 45398577(), ) } @@ -66,7 +66,7 @@ internal val watchHistoryMenuUseProgressDrawableFingerprint = fingerprint { instructions( methodCall("Landroid/widget/ProgressBar;", "setMax"), opcode(Opcode.MOVE_RESULT), - literal(-1712394514), + -1712394514(), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt index 96c00d489..335bf1319 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/Fingerprints.kt @@ -1,11 +1,7 @@ package app.revanced.patches.youtube.layout.shortsplayer -import app.revanced.patcher.addString -import app.revanced.patcher.checkCast -import app.revanced.patcher.fieldAccess -import app.revanced.patcher.fingerprint -import app.revanced.patcher.literal -import app.revanced.patcher.methodCall +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 @@ -15,17 +11,15 @@ import com.android.tools.smali.dexlib2.Opcode * the obfuscated name of the videoId() method in PlaybackStartDescriptor. * 20.38 and lower. */ -internal val playbackStartFeatureFlagFingerprint = fingerprint { - returns("Z") - parameters( - "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;", - ) +internal val playbackStartFeatureFlagMethodMatch = firstMethodComposite { + returnType("Z") + parameterTypes("Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;") instructions( - methodCall( - definingClass = "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;", - returnType = "Ljava/lang/String;", - ), - literal(45380134L), + method { + definingClass == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" && + returnType == "Ljava/lang/String;" + }, + 45380134L(), ) } @@ -34,31 +28,35 @@ internal val playbackStartFeatureFlagFingerprint = fingerprint { * the obfuscated name of the videoId() method in PlaybackStartDescriptor. * 20.39+ */ -internal val watchPanelVideoIdFingerprint = fingerprint { - returns("Ljava/lang/String;") - parameters() +internal val watchPanelVideoIdMethodMatch = firstMethodComposite { + returnType("Ljava/lang/String;") + parameterTypes() instructions( - fieldAccess( - opcode = Opcode.IGET_OBJECT, - type = "Lcom/google/android/apps/youtube/app/common/player/queue/WatchPanelId;", + allOf( + Opcode.IGET_OBJECT(), + field { type == "Lcom/google/android/apps/youtube/app/common/player/queue/WatchPanelId;" }, ), - checkCast("Lcom/google/android/apps/youtube/app/common/player/queue/DefaultWatchPanelId;"), - methodCall( - definingClass = "Lcom/google/android/apps/youtube/app/common/player/queue/DefaultWatchPanelId;", - returnType = "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;", - ), - methodCall( - definingClass = "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;", - returnType = "Ljava/lang/String;", + allOf( + Opcode.CHECK_CAST(), + type("Lcom/google/android/apps/youtube/app/common/player/queue/DefaultWatchPanelId;"), ), + method { + definingClass == "Lcom/google/android/apps/youtube/app/common/player/queue/DefaultWatchPanelId;" && + returnType == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" + }, + method { + definingClass == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" && + returnType == "Ljava/lang/String;" + }, + ) } // Pre 19.25 -internal val shortsPlaybackIntentLegacyFingerprint = fingerprint { +internal val shortsPlaybackIntentLegacyMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters( + returnType("V") + parameterTypes( "L", "Ljava/util/Map;", "J", @@ -67,18 +65,18 @@ internal val shortsPlaybackIntentLegacyFingerprint = fingerprint { "Ljava/util/Map;", ) instructions( - methodCall(returnType = "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;"), + method { returnType == "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;" }, // None of these strings are unique. - addString("com.google.android.apps.youtube.app.endpoint.flags"), - addString("ReelWatchFragmentArgs"), - addString("reels_fragment_descriptor"), + "com.google.android.apps.youtube.app.endpoint.flags"(), + "ReelWatchFragmentArgs"(), + "reels_fragment_descriptor"(), ) } -internal val shortsPlaybackIntentFingerprint = fingerprint { +internal val BytecodePatchContext.shortsPlaybackIntentMethod by gettingFirstMutableMethodDeclaratively { accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL) - returns("V") - parameters( + returnType("V") + parameterTypes( "Lcom/google/android/libraries/youtube/player/model/PlaybackStartDescriptor;", "Ljava/util/Map;", "J", @@ -86,16 +84,14 @@ internal val shortsPlaybackIntentFingerprint = fingerprint { ) instructions( // None of these strings are unique. - addString("com.google.android.apps.youtube.app.endpoint.flags"), - addString("ReelWatchFragmentArgs"), - addString("reels_fragment_descriptor"), + "com.google.android.apps.youtube.app.endpoint.flags"(), + "ReelWatchFragmentArgs"(), + "reels_fragment_descriptor"(), ) } -internal val exitVideoPlayerFingerprint = fingerprint { - returns("V") - parameters() - instructions( - ResourceType.ID("mdx_drawer_layout"), - ) +internal val BytecodePatchContext.exitVideoPlayerMethod by gettingFirstMutableMethodDeclaratively { + returnType("V") + parameterTypes() + instructions(ResourceType.ID("mdx_drawer_layout")) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt index a48cba4e2..03e83fa8a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt @@ -4,7 +4,6 @@ import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructionsWithLabels import app.revanced.patcher.extensions.getInstruction -import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patches.all.misc.resources.addResources import app.revanced.patches.all.misc.resources.addResourcesPatch @@ -41,7 +40,7 @@ val `Open Shorts in regular player` by creatingBytecodePatch( openVideosFullscreenHookPatch, navigationBarHookPatch, versionCheckPatch, - resourceMappingPatch + resourceMappingPatch, ) compatibleWith( @@ -50,31 +49,31 @@ val `Open Shorts in regular player` by creatingBytecodePatch( "20.14.43", "20.21.37", "20.31.40", - ) + ), ) apply { addResources("youtube", "layout.shortsplayer.shortsPlayerTypePatch") PreferenceScreen.SHORTS.addPreferences( - ListPreference("revanced_shorts_player_type") + ListPreference("revanced_shorts_player_type"), ) // Activity is used as the context to launch an Intent. - mainActivityOnCreateMethod.method.addInstruction( + mainActivityOnCreateMethod.addInstruction( 0, "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" + - "setMainActivity(Landroid/app/Activity;)V", + "setMainActivity(Landroid/app/Activity;)V", ) // Find the obfuscated method name for PlaybackStartDescriptor.videoId() val (videoIdStartMethod, videoIdIndex) = if (is_20_39_or_greater) { - watchPanelVideoIdFingerprint.let { - it.method to it.instructionMatches.last().index + watchPanelVideoIdMethodMatch.let { + it.method to it.indices.last() } } else { - playbackStartFeatureFlagFingerprint.let { - it.method to it.instructionMatches.first().index + playbackStartFeatureFlagMethodMatch.let { + it.method to it.indices.first() } } val playbackStartVideoIdMethodName = navigate(videoIdStartMethod).to(videoIdIndex).stop().name @@ -93,24 +92,24 @@ val `Open Shorts in regular player` by creatingBytecodePatch( """ if (is_19_25_or_greater) { - shortsPlaybackIntentFingerprint.method.addInstructionsWithLabels( + shortsPlaybackIntentMethod.addInstructionsWithLabels( 0, """ move-object/from16 v0, p1 ${extensionInstructions(0, 1)} - """ + """, ) } else { - shortsPlaybackIntentLegacyFingerprint.let { + shortsPlaybackIntentLegacyMethodMatch.let { it.method.apply { - val index = it.instructionMatches.first().index + val index = it.indices.first() val playbackStartRegister = getInstruction(index + 1).registerA val insertIndex = index + 2 val freeRegister = findFreeRegister(insertIndex, playbackStartRegister) addInstructionsWithLabels( insertIndex, - extensionInstructions(playbackStartRegister, freeRegister) + extensionInstructions(playbackStartRegister, freeRegister), ) } } @@ -119,7 +118,7 @@ val `Open Shorts in regular player` by creatingBytecodePatch( // Fix issue with back button exiting the app instead of minimizing the player. // Without this change this issue can be difficult to reproduce, but seems to occur // most often with 'open video in regular player' and not open in fullscreen player. - exitVideoPlayerFingerprint.method.apply { + exitVideoPlayerMethod.apply { // Method call for Activity.finish() val finishIndex = indexOfFirstInstructionOrThrow { val reference = getReference() @@ -135,7 +134,7 @@ val `Open Shorts in regular player` by creatingBytecodePatch( """ invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->overrideBackPressToExit(Z)Z move-result v$register - """ + """, ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt index 2a9790b54..c8730824e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/Fingerprints.kt @@ -1,63 +1,48 @@ package app.revanced.patches.youtube.layout.sponsorblock -import app.revanced.patcher.InstructionLocation.* -import app.revanced.patcher.checkCast -import app.revanced.patcher.fingerprint -import app.revanced.patcher.methodCall -import app.revanced.patcher.opcode +import app.revanced.patcher.* import app.revanced.patches.shared.misc.mapping.ResourceType -import app.revanced.patches.youtube.shared.seekbarFingerprint -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionReversed +import app.revanced.patches.youtube.shared.seekbarMethod 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.MethodReference -internal val appendTimeFingerprint = fingerprint { +internal val appendTimeMethodMatch = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters("Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;") + returnType("V") + parameterTypes("Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;", "Ljava/lang/CharSequence;") instructions( ResourceType.STRING("total_time"), - - methodCall(smali = "Landroid/content/res/Resources;->getString(I[Ljava/lang/Object;)Ljava/lang/String;"), - opcode(Opcode.MOVE_RESULT_OBJECT, MatchAfterImmediately()), + method { toString() == "Landroid/content/res/Resources;->getString(I[Ljava/lang/Object;)Ljava/lang/String;" }, + after(Opcode.MOVE_RESULT_OBJECT()), ) } -internal val controlsOverlayFingerprint = fingerprint { - returns("V") - parameters() +internal val controlsOverlayMethodMatch = firstMethodComposite { + returnType("V") + parameterTypes() instructions( - ResourceType.ID("inset_overlay_view_layout"), - checkCast("Landroid/widget/FrameLayout;", MatchAfterWithin(20)), + ResourceType.ID.invoke("inset_overlay_view_layout"), + afterAtMost(20, allOf(Opcode.CHECK_CAST(), type("Landroid/widget/FrameLayout;"))), ) } /** - * Resolves to the class found in [seekbarFingerprint]. + * Resolves to the class found in [seekbarMethod]. */ -internal val rectangleFieldInvalidatorFingerprint = fingerprint { - returns("V") - parameters() +internal val rectangleFieldInvalidatorMethodMatch = firstMethodComposite { + returnType("V") + parameterTypes() + instructions(method("invalidate")) +} + +internal val adProgressTextViewVisibilityMethodMatch = firstMethodComposite { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returnType("V") + parameterTypes("Z") instructions( - methodCall(name = "invalidate"), + method { + name == "setVisibility" && definingClass == + "Lcom/google/android/libraries/youtube/ads/player/ui/AdProgressTextView;" + }, ) } - -internal val adProgressTextViewVisibilityFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") - parameters("Z") - custom { method, _ -> - indexOfAdProgressTextViewVisibilityInstruction(method) >= 0 - } -} - -internal fun indexOfAdProgressTextViewVisibilityInstruction(method: Method) = method.indexOfFirstInstructionReversed { - val reference = getReference() - reference?.definingClass == - "Lcom/google/android/libraries/youtube/ads/player/ui/AdProgressTextView;" && - reference.name == "setVisibility" -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt index 84503108a..0304b3753 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt @@ -3,6 +3,7 @@ package app.revanced.patches.youtube.layout.sponsorblock import app.revanced.patcher.extensions.addInstruction import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.getInstruction +import app.revanced.patcher.immutableClassDef import app.revanced.patcher.patch.creatingBytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.all.misc.resources.addResources @@ -19,9 +20,9 @@ import app.revanced.patches.youtube.misc.playercontrols.playerControlsPatch import app.revanced.patches.youtube.misc.playertype.playerTypeHookPatch import app.revanced.patches.youtube.misc.settings.PreferenceScreen import app.revanced.patches.youtube.misc.settings.settingsPatch -import app.revanced.patches.youtube.shared.layoutConstructorFingerprint -import app.revanced.patches.youtube.shared.seekbarFingerprint -import app.revanced.patches.youtube.shared.seekbarOnDrawFingerprint +import app.revanced.patches.youtube.shared.getLayoutConstructorMethodMatch +import app.revanced.patches.youtube.shared.getSeekbarOnDrawMethodMatch +import app.revanced.patches.youtube.shared.seekbarMethod import app.revanced.patches.youtube.video.information.onCreateHook import app.revanced.patches.youtube.video.information.videoInformationPatch import app.revanced.patches.youtube.video.information.videoTimeHook @@ -52,13 +53,13 @@ private val sponsorBlockResourcePatch = resourcePatch { key = "revanced_settings_screen_10_sponsorblock", sorting = PreferenceScreenPreference.Sorting.UNSORTED, preferences = emptySet(), // Preferences are added by custom class at runtime. - tag = "app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockPreferenceGroup" + tag = "app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockPreferenceGroup", ), PreferenceCategory( key = "revanced_sb_stats", sorting = PreferenceScreenPreference.Sorting.UNSORTED, preferences = emptySet(), // Preferences are added by custom class at runtime. - tag = "app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockStatsPreferenceCategory" + tag = "app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockStatsPreferenceCategory", ), PreferenceCategory( key = "revanced_sb_about", @@ -68,9 +69,9 @@ private val sponsorBlockResourcePatch = resourcePatch { key = "revanced_sb_about_api", tag = "app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockAboutPreference", selectable = true, - ) - ) - ) + ), + ), + ), ) arrayOf( @@ -91,7 +92,7 @@ private val sponsorBlockResourcePatch = resourcePatch { "revanced_sb_logo_bold.xml", "revanced_sb_publish.xml", "revanced_sb_voting.xml", - ) + ), ).forEach { resourceGroup -> copyResources("sponsorblock", resourceGroup) } @@ -131,7 +132,7 @@ val SponsorBlock by creatingBytecodePatch( "20.14.43", "20.21.37", "20.31.40", - ) + ), ) apply { @@ -143,17 +144,15 @@ val SponsorBlock by creatingBytecodePatch( hookBackgroundPlayVideoId( EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR + - "->setCurrentVideoId(Ljava/lang/String;)V", + "->setCurrentVideoId(Ljava/lang/String;)V", ) // Set seekbar draw rectangle. val rectangleFieldName: FieldReference - rectangleFieldInvalidatorFingerprint.match( - seekbarFingerprint.originalClassDef - ).let { + rectangleFieldInvalidatorMethodMatch.match(seekbarMethod.immutableClassDef).let { it.method.apply { val rectangleIndex = indexOfFirstInstructionReversedOrThrow( - it.instructionMatches.first().index + it.indices.first(), ) { getReference()?.type == "Landroid/graphics/Rect;" } @@ -163,19 +162,17 @@ val SponsorBlock by creatingBytecodePatch( // Seekbar drawing. - // Shared fingerprint and indexes may have changed. - seekbarOnDrawFingerprint.clearMatch() // Cannot match using original immutable class because // class may have been modified by other patches - seekbarOnDrawFingerprint.match(seekbarFingerprint.classDef).let { + getSeekbarOnDrawMethodMatch().match(seekbarMethod.immutableClassDef).let { it.method.apply { // Set seekbar thickness. - val thicknessIndex = it.instructionMatches.last().index + val thicknessIndex = it.indices.last() val thicknessRegister = getInstruction(thicknessIndex).registerA addInstruction( thicknessIndex + 1, "invoke-static { v$thicknessRegister }, " + - "$EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSeekbarThickness(I)V", + "$EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSeekbarThickness(I)V", ) // Find the drawCircle call and draw the segment before it. @@ -189,8 +186,8 @@ val SponsorBlock by creatingBytecodePatch( addInstruction( drawCircleIndex, "invoke-static { v$canvasInstanceRegister, v$centerYRegister }, " + - "$EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->" + - "drawSegmentTimeBars(Landroid/graphics/Canvas;F)V", + "$EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->" + + "drawSegmentTimeBars(Landroid/graphics/Canvas;F)V", ) // Set seekbar bounds. @@ -200,7 +197,7 @@ val SponsorBlock by creatingBytecodePatch( move-object/from16 v0, p0 iget-object v0, v0, $rectangleFieldName invoke-static { v0 }, $EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSeekbarRectangle(Landroid/graphics/Rect;)V - """ + """, ) } } @@ -213,9 +210,9 @@ val SponsorBlock by creatingBytecodePatch( injectVisibilityCheckCall(EXTENSION_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR) // Append the new time to the player layout. - appendTimeFingerprint.let { + appendTimeMethodMatch.let { it.method.apply { - val index = it.instructionMatches.last().index + val index = it.indices.last() val register = getInstruction(index).registerA addInstructions( @@ -223,7 +220,7 @@ val SponsorBlock by creatingBytecodePatch( """ invoke-static { v$register }, $EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String; move-result-object v$register - """ + """, ) } } @@ -232,8 +229,9 @@ val SponsorBlock by creatingBytecodePatch( onCreateHook(EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR, "initialize") // Initialize the SponsorBlock view. - controlsOverlayFingerprint.match(layoutConstructorFingerprint.originalClassDef).let { - val checkCastIndex = it.instructionMatches.last().index + controlsOverlayMethodMatch.match(getLayoutConstructorMethodMatch().immutableClassDef).let { + val checkCastIndex = it.indices.last() + it.method.apply { val frameLayoutRegister = getInstruction(checkCastIndex).registerA addInstruction( @@ -243,13 +241,13 @@ val SponsorBlock by creatingBytecodePatch( } } - adProgressTextViewVisibilityFingerprint.method.apply { - val index = indexOfAdProgressTextViewVisibilityInstruction(this) - val register = getInstruction(index).registerD + adProgressTextViewVisibilityMethodMatch.let { + val setVisibilityIndex = it.indices.first() + val register = it.method.getInstruction(setVisibilityIndex).registerD - addInstructionsAtControlFlowLabel( - index, - "invoke-static { v$register }, $EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setAdProgressTextVisibility(I)V" + it.method.addInstructionsAtControlFlowLabel( + setVisibilityIndex, + "invoke-static { v$register }, $EXTENSION_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setAdProgressTextVisibility(I)V", ) } } 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 f2fe480e1..5f48f7edc 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 @@ -1,25 +1,25 @@ package app.revanced.patches.youtube.layout.startpage +import app.revanced.patcher.addString import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint import app.revanced.patcher.literal -import app.revanced.patcher.addString import com.android.tools.smali.dexlib2.Opcode internal val intentActionFingerprint = fingerprint { parameters("Landroid/content/Intent;") instructions( - addString("has_handled_intent") + addString("has_handled_intent"), ) } internal val browseIdFingerprint = fingerprint { returns("Lcom/google/android/apps/youtube/app/common/ui/navigation/PaneDescriptor;") - //parameters() // 20.30 and earlier is no parameters. 20.31+ parameter is L. + // parameters() // 20.30 and earlier is no parameters. 20.31+ parameter is L. instructions( addString("FEwhat_to_watch"), - literal(512), - fieldAccess(opcode = Opcode.IPUT_OBJECT, type = "Ljava/lang/String;") + 512(), + fieldAccess(opcode = Opcode.IPUT_OBJECT, type = "Ljava/lang/String;"), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt index 08faef810..25a7fd723 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/Fingerprints.kt @@ -2,12 +2,12 @@ package app.revanced.patches.youtube.layout.startupshortsreset import app.revanced.patcher.InstructionLocation.* import app.revanced.patcher.StringComparisonType +import app.revanced.patcher.addString import app.revanced.patcher.checkCast import app.revanced.patcher.fingerprint import app.revanced.patcher.literal import app.revanced.patcher.methodCall import app.revanced.patcher.opcode -import app.revanced.patcher.addString import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -23,7 +23,7 @@ internal val userWasInShortsAlternativeFingerprint = fingerprint { methodCall(smali = "Ljava/lang/Boolean;->booleanValue()Z", location = MatchAfterImmediately()), opcode(Opcode.MOVE_RESULT, MatchAfterImmediately()), // 20.40+ string was merged into another string and is a partial match. - addString("userIsInShorts: ", comparison = StringComparisonType.CONTAINS, location = MatchAfterWithin(15)) + addString("userIsInShorts: ", comparison = StringComparisonType.CONTAINS, location = MatchAfterWithin(15)), ) } @@ -35,7 +35,7 @@ internal val userWasInShortsLegacyFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) parameters("Ljava/lang/Object;") instructions( - addString("Failed to read user_was_in_shorts proto after successful warmup") + addString("Failed to read user_was_in_shorts proto after successful warmup"), ) } @@ -47,6 +47,6 @@ internal val userWasInShortsConfigFingerprint = fingerprint { returns("Z") parameters() instructions( - literal(45358360L) + 45358360L(), ) } 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 eca98e822..9d7a65784 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 @@ -7,7 +7,7 @@ import app.revanced.patches.youtube.shared.YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE internal val useGradientLoadingScreenFingerprint = fingerprint { instructions( - literal(45412406L) + 45412406L(), ) } @@ -16,9 +16,9 @@ internal val splashScreenStyleFingerprint = fingerprint { parameters("Landroid/os/Bundle;") instructions( anyInstruction( - literal(1074339245), // 20.30+ - literal(269032877L) // 20.29 and lower. - ) + 1074339245(), // 20.30+ + 269032877L(), // 20.29 and lower. + ), ) custom { method, classDef -> method.name == "onCreate" && classDef.type == YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt index cbe62a3d6..8c877d18a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/Fingerprints.kt @@ -1,18 +1,18 @@ package app.revanced.patches.youtube.misc.litho.filter +import app.revanced.patcher.addString import app.revanced.patcher.fieldAccess import app.revanced.patcher.fingerprint -import app.revanced.util.containsLiteralInstruction import app.revanced.patcher.literal import app.revanced.patcher.methodCall -import app.revanced.patcher.addString +import app.revanced.util.containsLiteralInstruction import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode internal val componentCreateFingerprint = fingerprint { instructions( addString("Element missing correct type extension"), - addString("Element missing type") + addString("Element missing type"), ) } @@ -31,12 +31,12 @@ internal val protobufBufferReferenceFingerprint = fingerprint { fieldAccess( opcode = Opcode.IGET_OBJECT, definingClass = "this", - type = "Lcom/google/android/libraries/elements/adl/UpbMessage;" + type = "Lcom/google/android/libraries/elements/adl/UpbMessage;", ), methodCall( definingClass = "Lcom/google/android/libraries/elements/adl/UpbMessage;", - name = "jniDecode" - ) + name = "jniDecode", + ), ) } @@ -56,7 +56,7 @@ internal val emptyComponentFingerprint = fingerprint { accessFlags(AccessFlags.PRIVATE, AccessFlags.CONSTRUCTOR) parameters() instructions( - addString("EmptyComponent") + addString("EmptyComponent"), ) custom { _, classDef -> classDef.methods.filter { AccessFlags.STATIC.isSet(it.accessFlags) }.size == 1 @@ -77,13 +77,13 @@ internal val lithoComponentNameUpbFeatureFlagFingerprint = fingerprint { returns("Z") parameters() instructions( - literal(45631264L) + 45631264L(), ) } internal val lithoConverterBufferUpbFeatureFlagFingerprint = fingerprint { returns("L") instructions( - literal(45419603L) + 45419603L(), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt index e797705e3..8e1833be1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/playercontrols/Fingerprints.kt @@ -107,7 +107,7 @@ internal val playerBottomControlsExploderFeatureFlagFingerprint = fingerprint { returns("Z") parameters() instructions( - literal(45643739L), + 45643739L(), ) } @@ -116,7 +116,7 @@ internal val playerTopControlsExperimentalLayoutFeatureFlagFingerprint = fingerp returns("I") parameters() instructions( - literal(45629424L), + 45629424L(), ) } @@ -125,7 +125,7 @@ internal val playerControlsLargeOverlayButtonsFeatureFlagFingerprint = fingerpri returns("Z") parameters() instructions( - literal(45709810L), + 45709810L(), ) } @@ -134,7 +134,7 @@ internal val playerControlsFullscreenLargeButtonsFeatureFlagFingerprint = finger returns("Z") parameters() instructions( - literal(45686474L), + 45686474L(), ) } @@ -143,6 +143,6 @@ internal val playerControlsButtonStrokeFeatureFlagFingerprint = fingerprint { returns("Z") parameters() instructions( - literal(45713296), + 45713296(), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt index a278aa611..4d2082569 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/Fingerprints.kt @@ -30,7 +30,7 @@ internal val cairoFragmentConfigFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") instructions( - literal(45532100L), + 45532100L(), opcode(Opcode.MOVE_RESULT, location = MatchAfterWithin(10)), ) } @@ -42,6 +42,6 @@ internal val boldIconsFeatureFlagFingerprint = fingerprint { returns("Z") parameters() instructions( - literal(45685201L), + 45685201L(), ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt index 8bfab1f4a..1f1fed6ff 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shared/Fingerprints.kt @@ -1,26 +1,27 @@ package app.revanced.patches.youtube.shared -import app.revanced.patcher.InstructionLocation.MatchAfterImmediately import app.revanced.patcher.accessFlags -import app.revanced.patcher.addString import app.revanced.patcher.after import app.revanced.patcher.allOf import app.revanced.patcher.definingClass import app.revanced.patcher.field import app.revanced.patcher.fingerprint import app.revanced.patcher.firstMethodComposite +import app.revanced.patcher.firstMethodDeclaratively +import app.revanced.patcher.firstMutableMethodDeclaratively +import app.revanced.patcher.gettingFirstMethodDeclaratively import app.revanced.patcher.gettingFirstMutableMethodDeclaratively +import app.revanced.patcher.instruction import app.revanced.patcher.instructions import app.revanced.patcher.invoke -import app.revanced.patcher.literal -import app.revanced.patcher.methodCall +import app.revanced.patcher.method import app.revanced.patcher.name -import app.revanced.patcher.opcode import app.revanced.patcher.parameterTypes import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.returnType import app.revanced.patcher.type import app.revanced.patches.shared.misc.mapping.ResourceType +import app.revanced.patches.shared.misc.mapping.ResourceType.IndexedMatcherPredicateExtension.invoke import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -41,14 +42,21 @@ internal val conversionContextFingerprintToString = fingerprint { } } -internal val layoutConstructorFingerprint = fingerprint { +internal fun getLayoutConstructorMethodMatch() = firstMethodComposite { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("V") + returnType("V") + parameterTypes() + + val methodParameterTypePrefixes = listOf("Landroid/view/View;", "I") + instructions( - literal(159962), + 159962L(), ResourceType.ID("player_control_previous_button_touch_area"), ResourceType.ID("player_control_next_button_touch_area"), - methodCall(parameters = listOf("Landroid/view/View;", "I")), + method { + parameterTypes.size == 2 && + parameterTypes.zip(methodParameterTypePrefixes).all { (a, b) -> a.startsWith(b) } + }, ) } @@ -102,22 +110,20 @@ internal val rollingNumberTextViewAnimationUpdateFingerprint = fingerprint { } } -internal val seekbarFingerprint = fingerprint { - returns("V") - instructions( - addString("timed_markers_width"), - ) +internal val BytecodePatchContext.seekbarMethod by gettingFirstMethodDeclaratively { + returnType("V") + instructions("timed_markers_width"()) } /** - * Matches to _mutable_ class found in [seekbarFingerprint]. + * Matches to _mutable_ class found in [seekbarMethod]. */ -internal val seekbarOnDrawFingerprint = fingerprint { +internal fun getSeekbarOnDrawMethodMatch() = firstMethodComposite { + name("onDraw") instructions( - methodCall(smali = "Ljava/lang/Math;->round(F)I"), - opcode(Opcode.MOVE_RESULT, location = MatchAfterImmediately()), + method { toString() == "Ljava/lang/Math;->round(F)I" }, + after(Opcode.MOVE_RESULT()), ) - custom { method, _ -> method.name == "onDraw" } } internal val subtitleButtonControllerFingerprint = fingerprint { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt index 305d62fc6..bbe99bf0c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/custom/Fingerprints.kt @@ -30,7 +30,7 @@ internal val serverSideMaxSpeedFeatureFlagFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) returns("Z") instructions( - literal(45719140L), + 45719140L(), ) } @@ -42,7 +42,7 @@ internal val speedArrayGeneratorFingerprint = fingerprint { methodCall(name = "size", returnType = "I"), newInstance("Ljava/text/DecimalFormat;"), addString("0.0#"), - literal(7), + 7(), opcode(Opcode.NEW_ARRAY), fieldAccess(definingClass = "/PlayerConfigModel;", type = "[F"), ) @@ -56,8 +56,8 @@ internal val speedLimiterFingerprint = fingerprint { returns("V") parameters("F", "Lcom/google/android/libraries/youtube/innertube/model/media/PlayerConfigModel;") instructions( - literal(0.25f), - literal(4.0f), + 0.25f(), + 4.0f(), ) } 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 8f5a505b0..10b253fa9 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 @@ -14,7 +14,7 @@ internal val videoIdFingerprint = fingerprint { instructions( methodCall( definingClass = "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;", - returnType = "Ljava/lang/String;" + returnType = "Ljava/lang/String;", ), opcode(Opcode.MOVE_RESULT_OBJECT), ) @@ -27,19 +27,21 @@ internal val videoIdBackgroundPlayFingerprint = fingerprint { instructions( methodCall( definingClass = "Lcom/google/android/libraries/youtube/innertube/model/player/PlayerResponseModel;", - returnType = "Ljava/lang/String;" + returnType = "Ljava/lang/String;", ), opcode(Opcode.MOVE_RESULT_OBJECT), opcode(Opcode.IPUT_OBJECT), opcode(Opcode.MONITOR_EXIT), opcode(Opcode.RETURN_VOID), opcode(Opcode.MONITOR_EXIT), - opcode(Opcode.RETURN_VOID) + opcode(Opcode.RETURN_VOID), ) custom { method, classDef -> method.implementation != null && - (classDef.methods.count() == 17 // 20.39 and lower. - || classDef.methods.count() == 16) // 20.40+ + ( + classDef.methods.count() == 17 || // 20.39 and lower. + classDef.methods.count() == 16 + ) // 20.40+ } } @@ -48,6 +50,6 @@ internal val videoIdParentFingerprint = fingerprint { returns("[L") parameters("L") instructions( - literal(524288L) + 524288L(), ) } diff --git a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 7f858c2aa..c9f4b20c1 100644 --- a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -1,9 +1,9 @@ package app.revanced.util -import app.revanced.patcher.firstMutableClassDef -import app.revanced.patcher.firstMutableClassDefOrNull import app.revanced.patcher.FingerprintBuilder import app.revanced.patcher.extensions.* +import app.revanced.patcher.firstMutableClassDef +import app.revanced.patcher.firstMutableClassDefOrNull import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.patch.PatchException import app.revanced.patches.shared.misc.mapping.ResourceType @@ -91,7 +91,7 @@ fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude: Int): In // This method is simple and does not follow branching. throw IllegalArgumentException( "Encountered a branch statement before " + - "a free register could be found from startIndex: $startIndex" + "a free register could be found from startIndex: $startIndex", ) } @@ -111,7 +111,7 @@ fun Method.findFreeRegister(startIndex: Int, vararg registersToExclude: Int): In // In practice this never occurs. throw IllegalArgumentException( "Could not find a free register from startIndex: " + - "$startIndex excluding: $registersToExclude" + "$startIndex excluding: $registersToExclude", ) } } @@ -139,9 +139,13 @@ internal val Instruction.registersUsed: List } is ThreeRegisterInstruction -> listOf(registerA, registerB, registerC) + is TwoRegisterInstruction -> listOf(registerA, registerB) + is OneRegisterInstruction -> listOf(registerA) + is RegisterRangeInstruction -> (startRegister until (startRegister + registerCount)).toList() + else -> emptyList() } @@ -191,7 +195,7 @@ private fun Method.findInstructionIndexFromToString(fieldName: String): Int { val stringUsageIndex = indexOfFirstInstruction(stringIndex) { val reference = getReference() reference?.definingClass == "Ljava/lang/StringBuilder;" && - (this as? FiveRegisterInstruction)?.registerD == stringRegister + (this as? FiveRegisterInstruction)?.registerD == stringRegister } if (stringUsageIndex < 0) { throw IllegalArgumentException("Could not find StringBuilder usage in: $this") @@ -249,11 +253,9 @@ internal fun Method.findFieldFromToString(fieldName: String): FieldReference { /** * Adds public [AccessFlags] and removes private and protected flags (if present). */ -internal fun Int.toPublicAccessFlags(): Int { - return this.or(AccessFlags.PUBLIC.value) - .and(AccessFlags.PROTECTED.value.inv()) - .and(AccessFlags.PRIVATE.value.inv()) -} +internal fun Int.toPublicAccessFlags(): Int = this.or(AccessFlags.PUBLIC.value) + .and(AccessFlags.PROTECTED.value.inv()) + .and(AccessFlags.PRIVATE.value.inv()) /** * Find the [MutableMethod] from a given [Method] in a [MutableClass]. @@ -294,7 +296,6 @@ fun MutableMethod.injectHideViewCall( "invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V", ) - /** * Inserts instructions at a given index, using the existing control flow label at that index. * Inserted instructions can have it's own control flow labels as well. @@ -311,7 +312,7 @@ fun MutableMethod.injectHideViewCall( // TODO: delete this on next major version bump. fun MutableMethod.addInstructionsAtControlFlowLabel( insertIndex: Int, - instructions: String + instructions: String, ) = addInstructionsAtControlFlowLabel(insertIndex, instructions, *arrayOf()) /** @@ -330,7 +331,7 @@ fun MutableMethod.addInstructionsAtControlFlowLabel( fun MutableMethod.addInstructionsAtControlFlowLabel( insertIndex: Int, instructions: String, - vararg externalLabels: ExternalLabel + vararg externalLabels: ExternalLabel, ) { // Duplicate original instruction and add to +1 index. addInstruction(insertIndex + 1, getInstruction(insertIndex)) @@ -356,9 +357,7 @@ fun MutableMethod.addInstructionsAtControlFlowLabel( * @throws PatchException if the resource cannot be found. * @see [indexOfFirstResourceIdOrThrow], [indexOfFirstLiteralInstructionReversed] */ -fun Method.indexOfFirstResourceId(resourceName: String): Int { - return indexOfFirstLiteralInstruction(ResourceType.ID[resourceName)] -} +fun Method.indexOfFirstResourceId(resourceName: String): Int = indexOfFirstLiteralInstruction(ResourceType.ID[resourceName]) /** * Get the index of the first instruction with the id of the given resource name or throw a [PatchException]. @@ -407,8 +406,7 @@ fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Long): Int { * @return the first literal instruction with the value, or -1 if not found. * @see indexOfFirstLiteralInstructionOrThrow */ -fun Method.indexOfFirstLiteralInstruction(literal: Float) = - indexOfFirstLiteralInstruction(literal.toRawBits().toLong()) +fun Method.indexOfFirstLiteralInstruction(literal: Float) = indexOfFirstLiteralInstruction(literal.toRawBits().toLong()) /** * Find the index of the first literal instruction with the given float value, @@ -428,8 +426,7 @@ fun Method.indexOfFirstLiteralInstructionOrThrow(literal: Float): Int { * @return the first literal instruction with the value, or -1 if not found. * @see indexOfFirstLiteralInstructionOrThrow */ -fun Method.indexOfFirstLiteralInstruction(literal: Double) = - indexOfFirstLiteralInstruction(literal.toRawBits()) +fun Method.indexOfFirstLiteralInstruction(literal: Double) = indexOfFirstLiteralInstruction(literal.toRawBits()) /** * Find the index of the first literal instruction with the given double value, @@ -473,8 +470,7 @@ fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Long): Int { * @return the last literal instruction with the value, or -1 if not found. * @see indexOfFirstLiteralInstructionOrThrow */ -fun Method.indexOfFirstLiteralInstructionReversed(literal: Float) = - indexOfFirstLiteralInstructionReversed(literal.toRawBits().toLong()) +fun Method.indexOfFirstLiteralInstructionReversed(literal: Float) = indexOfFirstLiteralInstructionReversed(literal.toRawBits().toLong()) /** * Find the index of the last wide literal instruction with the given float value, @@ -494,8 +490,7 @@ fun Method.indexOfFirstLiteralInstructionReversedOrThrow(literal: Float): Int { * @return the last literal instruction with the value, or -1 if not found. * @see indexOfFirstLiteralInstructionOrThrow */ -fun Method.indexOfFirstLiteralInstructionReversed(literal: Double) = - indexOfFirstLiteralInstructionReversed(literal.toRawBits()) +fun Method.indexOfFirstLiteralInstructionReversed(literal: Double) = indexOfFirstLiteralInstructionReversed(literal.toRawBits()) /** * Find the index of the last wide literal instruction with the given double value, @@ -567,10 +562,9 @@ fun Method.indexOfFirstInstruction(targetOpcode: Opcode): Int = indexOfFirstInst * @return The index of the first opcode specified, or -1 if not found. * @see indexOfFirstInstructionOrThrow */ -fun Method.indexOfFirstInstruction(startIndex: Int = 0, targetOpcode: Opcode): Int = - indexOfFirstInstruction(startIndex) { - opcode == targetOpcode - } +fun Method.indexOfFirstInstruction(startIndex: Int = 0, targetOpcode: Opcode): Int = indexOfFirstInstruction(startIndex) { + opcode == targetOpcode +} /** * Get the index of the first [Instruction] that matches the predicate, starting from [startIndex]. @@ -605,10 +599,9 @@ fun Method.indexOfFirstInstructionOrThrow(targetOpcode: Opcode): Int = indexOfFi * @throws PatchException * @see indexOfFirstInstruction */ -fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, targetOpcode: Opcode): Int = - indexOfFirstInstructionOrThrow(startIndex) { - opcode == targetOpcode - } +fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, targetOpcode: Opcode): Int = indexOfFirstInstructionOrThrow(startIndex) { + opcode == targetOpcode +} /** * Get the index of the first [Instruction] that matches the predicate, starting from [startIndex]. @@ -634,10 +627,9 @@ fun Method.indexOfFirstInstructionOrThrow(startIndex: Int = 0, filter: Instructi * @return -1 if the instruction is not found. * @see indexOfFirstInstructionReversedOrThrow */ -fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, targetOpcode: Opcode): Int = - indexOfFirstInstructionReversed(startIndex) { - opcode == targetOpcode - } +fun Method.indexOfFirstInstructionReversed(startIndex: Int? = null, targetOpcode: Opcode): Int = indexOfFirstInstructionReversed(startIndex) { + opcode == targetOpcode +} /** * Get the index of matching instruction, @@ -674,10 +666,9 @@ fun Method.indexOfFirstInstructionReversed(targetOpcode: Opcode): Int = indexOfF * @return The index of the instruction. * @see indexOfFirstInstructionReversed */ -fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targetOpcode: Opcode): Int = - indexOfFirstInstructionReversedOrThrow(startIndex) { - opcode == targetOpcode - } +fun Method.indexOfFirstInstructionReversedOrThrow(startIndex: Int? = null, targetOpcode: Opcode): Int = indexOfFirstInstructionReversedOrThrow(startIndex) { + opcode == targetOpcode +} /** * Get the index of matching instruction, @@ -734,8 +725,7 @@ fun Method.findInstructionIndicesReversedOrThrow(filter: Instruction.() -> Boole * _Returns an empty list if no indices are found_ * @see findInstructionIndicesReversedOrThrow */ -fun Method.findInstructionIndicesReversed(opcode: Opcode): List = - findInstructionIndicesReversed { this.opcode == opcode } +fun Method.findInstructionIndicesReversed(opcode: Opcode): List = findInstructionIndicesReversed { this.opcode == opcode } /** * @return An immutable list of indices of the opcode in reverse order. @@ -773,7 +763,7 @@ internal fun MutableMethod.insertLiteralOverride(literalIndex: Int, extensionMet """ $operation, $extensionMethodDescriptor move-result v$register - """ + """, ) } @@ -795,7 +785,7 @@ internal fun MutableMethod.insertLiteralOverride(literalIndex: Int, override: Bo addInstruction( index + 1, - "const v$register, $overrideValue" + "const v$register, $overrideValue", ) } @@ -822,7 +812,7 @@ fun BytecodePatchContext.forEachInstructionAsSequence( mutableClassDef, mutableMethod, instructions.size - 1 - index, - instruction + instruction, ) } // Reverse indices again. } @@ -1230,7 +1220,7 @@ internal fun BytecodePatchContext.addStaticFieldToExtension( methodName: String, fieldName: String, objectClass: String, - smaliInstructions: String + smaliInstructions: String, ) { val mutableClass = firstMutableClassDef(type) val objectCall = "$mutableClass->$fieldName:$objectClass" @@ -1245,15 +1235,15 @@ internal fun BytecodePatchContext.addStaticFieldToExtension( AccessFlags.PUBLIC.value or AccessFlags.STATIC.value, null, annotations, - null - ).toMutable() + null, + ).toMutable(), ) addInstructionsWithLabels( 0, """ sget-object v0, $objectCall - """ + smaliInstructions + """ + smaliInstructions, ) } } @@ -1277,12 +1267,16 @@ private class InstructionUtils { GOTO, GOTO_16, GOTO_32, IF_EQ, IF_NE, IF_LT, IF_GE, IF_GT, IF_LE, IF_EQZ, IF_NEZ, IF_LTZ, IF_GEZ, IF_GTZ, IF_LEZ, - PACKED_SWITCH_PAYLOAD, SPARSE_SWITCH_PAYLOAD + PACKED_SWITCH_PAYLOAD, SPARSE_SWITCH_PAYLOAD, ) val returnOpcodes: EnumSet = EnumSet.of( - RETURN_VOID, RETURN, RETURN_WIDE, RETURN_OBJECT, RETURN_VOID_NO_BARRIER, - THROW + RETURN_VOID, + RETURN, + RETURN_WIDE, + RETURN_OBJECT, + RETURN_VOID_NO_BARRIER, + THROW, ) val writeOpcodes: EnumSet = EnumSet.of(