diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/AdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/AdsPatch.kt index 9b8d4d5b8..4f43b2fe4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/AdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/AdsPatch.kt @@ -17,6 +17,7 @@ import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.indexOfFirstStringInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction @@ -113,9 +114,10 @@ val adsPatch = bytecodePatch( // AdElementConverter is conveniently responsible for inserting all feed ads. // By removing the appending instruction no ad posts gets appended to the feed. newAdPostFingerprint.methodOrThrow().apply { - val targetIndex = indexOfFirstInstructionOrThrow { - opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.toString() == "Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z" + val stringIndex = indexOfFirstStringInstructionOrThrow("android_feed_freeform_render_variant") + val targetIndex = indexOfFirstInstructionOrThrow(stringIndex) { + opcode == Opcode.INVOKE_VIRTUAL + && getReference()?.toString() == "Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z" } val targetInstruction = getInstruction(targetIndex) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/Fingerprints.kt index c4218a431..726e76933 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/Fingerprints.kt @@ -1,9 +1,12 @@ package app.revanced.patches.reddit.ad import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val commentAdsFingerprint = legacyFingerprint( name = "commentAdsFingerprint", @@ -35,9 +38,7 @@ internal val adPostFingerprint = legacyFingerprint( "uxExperiences" ), customFingerprint = { method, classDef -> - method.definingClass.endsWith("/Listing;") && - method.name == "" && - classDef.sourceFile == "Listing.kt" + classDef.type.endsWith("/Listing;") }, ) @@ -45,10 +46,14 @@ internal val newAdPostFingerprint = legacyFingerprint( name = "newAdPostFingerprint", returnType = "L", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - opcodes = listOf(Opcode.INVOKE_VIRTUAL), strings = listOf( - "chain", - "feedElement" + "feedElement", + "android_feed_freeform_render_variant", ), - customFingerprint = { _, classDef -> classDef.sourceFile == "AdElementConverter.kt" }, + customFingerprint = { method, _ -> + method.indexOfFirstInstruction { + getReference()?.toString() == "Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z" + } >= 0 + }, ) + diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/communities/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/communities/Fingerprints.kt index eeb7f8051..8bc9c4084 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/communities/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/communities/Fingerprints.kt @@ -8,7 +8,17 @@ internal val communityRecommendationSectionFingerprint = legacyFingerprint( name = "communityRecommendationSectionFingerprint", returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - customFingerprint = { method, _ -> - method.definingClass.endsWith("/CommunityRecommendationSection;") - } + strings = listOf("feedContext"), ) + +internal val communityRecommendationSectionParentFingerprint = legacyFingerprint( + name = "communityRecommendationSectionParentFingerprint", + returnType = "Ljava/lang/String;", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + strings = listOf("community_recomendation_section_"), + customFingerprint = { method, _ -> + method.definingClass.startsWith("Lcom/reddit/onboardingfeedscomponents/communityrecommendation/impl/") && + method.name == "key" + } +) \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/communities/RecommendedCommunitiesPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/communities/RecommendedCommunitiesPatch.kt index e0cc431d7..e56d6b747 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/communities/RecommendedCommunitiesPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/communities/RecommendedCommunitiesPatch.kt @@ -24,7 +24,7 @@ val recommendedCommunitiesPatch = bytecodePatch( dependsOn(settingsPatch) execute { - communityRecommendationSectionFingerprint.methodOrThrow().apply { + communityRecommendationSectionFingerprint.methodOrThrow(communityRecommendationSectionParentFingerprint).apply { addInstructionsWithLabels( 0, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/Fingerprints.kt index 7316791b7..cd80daa09 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/Fingerprints.kt @@ -1,12 +1,55 @@ package app.revanced.patches.reddit.layout.navigation import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or 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 bottomNavScreenFingerprint = legacyFingerprint( name = "bottomNavScreenFingerprint", + returnType = "Landroid/view/View;", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + customFingerprint = { method, _ -> + method.definingClass == "Lcom/reddit/launch/bottomnav/BottomNavScreen;" && + indexOfGetDimensionPixelSizeInstruction(method) >= 0 + } +) + +fun indexOfGetDimensionPixelSizeInstruction(methodDef: Method) = + methodDef.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.toString() == "Landroid/content/res/Resources;->getDimensionPixelSize(I)I" + } + +internal val bottomNavScreenHandlerFingerprint = legacyFingerprint( + name = "bottomNavScreenHandlerFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "L", "Z", "Landroid/view/ViewGroup;", "L"), + customFingerprint = { method, _ -> + indexOfGetItemsInstruction(method) >= 0 && + indexOfSetSelectedItemTypeInstruction(method) >= 0 + } +) + +fun indexOfGetItemsInstruction(method: Method) = + method.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "getItems" + } + +fun indexOfSetSelectedItemTypeInstruction(method: Method) = + method.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "setSelectedItemType" + } + +internal val bottomNavScreenOnGlobalLayoutFingerprint = legacyFingerprint( + name = "bottomNavScreenOnGlobalLayoutFingerprint", returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = emptyList(), @@ -14,8 +57,7 @@ internal val bottomNavScreenFingerprint = legacyFingerprint( Opcode.INVOKE_VIRTUAL, Opcode.RETURN_VOID ), - customFingerprint = { method, classDef -> - method.name == "onGlobalLayout" && - classDef.type.startsWith("Lcom/reddit/launch/bottomnav/BottomNavScreen\$") + customFingerprint = { methodDef, _ -> + methodDef.name == "onGlobalLayout" } ) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt index e517df7ec..ecb867e28 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt @@ -1,38 +1,77 @@ package app.revanced.patches.reddit.layout.navigation import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.HIDE_NAVIGATION_BUTTONS +import app.revanced.patches.reddit.utils.settings.is_2024_26_or_greater import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus -import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.fingerprint.resolvable +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -private const val EXTENSION_METHOD_DESCRIPTOR = - "$PATCHES_PATH/NavigationButtonsPatch;->hideNavigationButtons(Landroid/view/ViewGroup;)V" +private const val EXTENSION_CLASS_DESCRIPTOR = + "$PATCHES_PATH/NavigationButtonsPatch;" @Suppress("unused") val navigationButtonsPatch = bytecodePatch( HIDE_NAVIGATION_BUTTONS.title, HIDE_NAVIGATION_BUTTONS.summary, + false, ) { compatibleWith(COMPATIBLE_PACKAGE) dependsOn(settingsPatch) execute { - bottomNavScreenFingerprint.matchOrThrow().let { - it.method.apply { - val startIndex = it.patternMatch!!.startIndex - val targetRegister = - getInstruction(startIndex).registerC - addInstruction( - startIndex + 1, - "invoke-static {v$targetRegister}, $EXTENSION_METHOD_DESCRIPTOR" + if (is_2024_26_or_greater) { + println("WARNING: \"Hide navigation buttons\" patch is not supported in this version. Use Reddit 2024.25.3 or earlier.") + return@execute + } + + if (bottomNavScreenFingerprint.resolvable()) { + val bottomNavScreenMutableClass = with (bottomNavScreenFingerprint.methodOrThrow()) { + val startIndex = indexOfGetDimensionPixelSizeInstruction(this) + val targetIndex = indexOfFirstInstructionOrThrow(startIndex, Opcode.NEW_INSTANCE) + val targetReference = getInstruction(targetIndex).reference.toString() + + classBy { it.type == targetReference } + ?.mutableClass + ?: throw ClassNotFoundException("Failed to find class $targetReference") + } + + bottomNavScreenOnGlobalLayoutFingerprint.second.matchOrNull(bottomNavScreenMutableClass)?.let { + it.method.apply { + val startIndex = it.patternMatch!!.startIndex + val targetRegister = + getInstruction(startIndex).registerC + + addInstruction( + startIndex + 1, + "invoke-static {v$targetRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons(Landroid/view/ViewGroup;)V" + ) + } + } + } else { + // Legacy method. + bottomNavScreenHandlerFingerprint.methodOrThrow().apply { + val targetIndex = indexOfGetItemsInstruction(this) + 1 + val targetRegister = getInstruction(targetIndex).registerA + + addInstructions( + targetIndex + 1, """ + invoke-static {v$targetRegister}, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButtons(Ljava/util/List;)Ljava/util/List; + move-result-object v$targetRegister + """ ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/Fingerprints.kt index 899ceb2fe..a6d308a07 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/premiumicon/Fingerprints.kt @@ -5,9 +5,8 @@ import app.revanced.util.fingerprint.legacyFingerprint internal val premiumIconFingerprint = legacyFingerprint( name = "premiumIconFingerprint", returnType = "Z", - customFingerprint = { method, classDef -> - method.definingClass.endsWith("/MyAccount;") && - method.name == "isPremiumSubscriber" && - classDef.sourceFile == "MyAccount.kt" + customFingerprint = { method, _ -> + method.definingClass == "Lcom/reddit/domain/model/MyAccount;" && + method.name == "isPremiumSubscriber" } ) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/Fingerprints.kt index f057a104e..a1c24dd0f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/Fingerprints.kt @@ -1,17 +1,37 @@ package app.revanced.patches.reddit.layout.recentlyvisited import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or 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.FieldReference + +internal val communityDrawerPresenterConstructorFingerprint = legacyFingerprint( + name = "communityDrawerPresenterConstructorFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + strings = listOf("matureFeedFeatures", "communityDrawerSettings"), + customFingerprint = { method, _ -> + indexOfHeaderItemInstruction(method) >= 0 + } +) + +fun indexOfHeaderItemInstruction(method: Method) = + method.indexOfFirstInstruction { + getReference()?.name == "RECENTLY_VISITED" + } internal val communityDrawerPresenterFingerprint = legacyFingerprint( name = "communityDrawerPresenterFingerprint", returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = emptyList(), - opcodes = listOf(Opcode.AGET), - customFingerprint = { method, _ -> - method.definingClass.endsWith("/CommunityDrawerPresenter;") - } + opcodes = listOf( + Opcode.XOR_INT_2ADDR, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + ) ) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt index 1981cb894..2c23ae2ef 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/recentlyvisited/RecentlyVisitedShelfPatch.kt @@ -8,15 +8,12 @@ import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.HIDE_RECENTLY_VISITED_SHELF import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus -import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.methodOrThrow -import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference private const val EXTENSION_METHOD_DESCRIPTOR = "$PATCHES_PATH/RecentlyVisitedShelfPatch;" + @@ -33,23 +30,21 @@ val recentlyVisitedShelfPatch = bytecodePatch( dependsOn(settingsPatch) execute { - val communityDrawerPresenterMethod = communityDrawerPresenterFingerprint.methodOrThrow() - val constructorMethod = findMethodOrThrow(communityDrawerPresenterMethod.definingClass) - val recentlyVisitedReference = with(constructorMethod) { - val recentlyVisitedFieldIndex = indexOfFirstInstructionOrThrow { - getReference()?.name == "RECENTLY_VISITED" - } + + val recentlyVisitedReference = with (communityDrawerPresenterConstructorFingerprint.methodOrThrow()) { + val recentlyVisitedFieldIndex = indexOfHeaderItemInstruction(this) val recentlyVisitedObjectIndex = - indexOfFirstInstructionOrThrow( - recentlyVisitedFieldIndex, - Opcode.IPUT_OBJECT - ) - getInstruction(recentlyVisitedObjectIndex).reference + indexOfFirstInstructionOrThrow(recentlyVisitedFieldIndex, Opcode.IPUT_OBJECT) + + getInstruction(recentlyVisitedObjectIndex).reference.toString() } - communityDrawerPresenterMethod.apply { - val recentlyVisitedObjectIndex = indexOfFirstInstructionOrThrow { - getReference()?.toString() == recentlyVisitedReference.toString() - } + + communityDrawerPresenterFingerprint.methodOrThrow(communityDrawerPresenterConstructorFingerprint).apply { + val recentlyVisitedObjectIndex = + indexOfFirstInstructionOrThrow { + (this as? ReferenceInstruction)?.reference?.toString() == recentlyVisitedReference + } + arrayOf( indexOfFirstInstructionOrThrow( recentlyVisitedObjectIndex, @@ -65,9 +60,9 @@ val recentlyVisitedShelfPatch = bytecodePatch( addInstructions( staticIndex + 2, """ - invoke-static {v$insertRegister}, $EXTENSION_METHOD_DESCRIPTOR - move-result-object v$insertRegister - """ + invoke-static {v$insertRegister}, $EXTENSION_METHOD_DESCRIPTOR + move-result-object v$insertRegister + """ ) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt index e5bc11a19..13767b47b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt @@ -1,16 +1,13 @@ package app.revanced.patches.reddit.layout.screenshotpopup -import app.revanced.patches.reddit.utils.resourceid.screenShotShareBanner import app.revanced.util.fingerprint.legacyFingerprint -import app.revanced.util.or -import com.android.tools.smali.dexlib2.AccessFlags internal val screenshotTakenBannerFingerprint = legacyFingerprint( name = "screenshotTakenBannerFingerprint", returnType = "V", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - literals = listOf(screenShotShareBanner), - customFingerprint = { _, classDef -> - classDef.sourceFile == "ScreenshotTakenBanner.kt" + parameters = listOf("Landroidx/compose/runtime/", "I"), + customFingerprint = { method, classDef -> + classDef.type.endsWith("\$ScreenshotTakenBannerKt\$lambda-1\$1;") && + method.name == "invoke" } ) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt index cf8f02664..48f009c59 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt @@ -7,7 +7,6 @@ import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.DISABLE_SCREENSHOT_POPUP -import app.revanced.patches.reddit.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus import app.revanced.util.fingerprint.methodOrThrow @@ -22,10 +21,7 @@ val screenshotPopupPatch = bytecodePatch( ) { compatibleWith(COMPATIBLE_PACKAGE) - dependsOn( - sharedResourceIdPatch, - settingsPatch - ) + dependsOn(settingsPatch) execute { screenshotTakenBannerFingerprint.methodOrThrow().apply { diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt index e4810f9b8..bebd879c6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/Fingerprints.kt @@ -1,18 +1,27 @@ package app.revanced.patches.reddit.layout.subredditdialog -import app.revanced.patches.reddit.utils.resourceid.cancelButton -import app.revanced.patches.reddit.utils.resourceid.textAppearanceRedditBaseOldButtonColored import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or 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 frequentUpdatesSheetScreenFingerprint = legacyFingerprint( name = "frequentUpdatesSheetScreenFingerprint", returnType = "Landroid/view/View;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - literals = listOf(cancelButton), + opcodes = listOf( + Opcode.CONST, + Opcode.INVOKE_STATIC, + Opcode.MOVE_RESULT_OBJECT, + Opcode.CHECK_CAST, + Opcode.IF_EQZ + ), customFingerprint = { _, classDef -> - classDef.sourceFile == "FrequentUpdatesSheetScreen.kt" + classDef.type == "Lcom/reddit/screens/pager/FrequentUpdatesSheetScreen;" } ) @@ -20,8 +29,14 @@ internal val redditAlertDialogsFingerprint = legacyFingerprint( name = "redditAlertDialogsFingerprint", returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - literals = listOf(textAppearanceRedditBaseOldButtonColored), - customFingerprint = { _, classDef -> - classDef.sourceFile == "RedditAlertDialogs.kt" + customFingerprint = { method, _ -> + method.definingClass.startsWith("Lcom/reddit/screen/dialog/") && + indexOfSetBackgroundTintListInstruction(method) >= 0 } -) \ No newline at end of file +) + +fun indexOfSetBackgroundTintListInstruction(method: Method) = + method.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "setBackgroundTintList" + } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt index 2684e5fbc..fa57ecabe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt @@ -6,15 +6,16 @@ import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.REMOVE_SUBREDDIT_DIALOG -import app.revanced.patches.reddit.utils.resourceid.cancelButton -import app.revanced.patches.reddit.utils.resourceid.sharedResourceIdPatch -import app.revanced.patches.reddit.utils.resourceid.textAppearanceRedditBaseOldButtonColored import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus +import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow -import app.revanced.util.indexOfFirstLiteralInstructionOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_CLASS_DESCRIPTOR = "$PATCHES_PATH/RemoveSubRedditDialogPatch;" @@ -26,29 +27,29 @@ val subRedditDialogPatch = bytecodePatch( ) { compatibleWith(COMPATIBLE_PACKAGE) - dependsOn( - sharedResourceIdPatch, - settingsPatch - ) + dependsOn(settingsPatch) execute { - frequentUpdatesSheetScreenFingerprint.methodOrThrow().apply { - val cancelButtonViewIndex = - indexOfFirstLiteralInstructionOrThrow(cancelButton) + 2 - val cancelButtonViewRegister = - getInstruction(cancelButtonViewIndex).registerA + frequentUpdatesSheetScreenFingerprint.matchOrThrow().let { + it.method.apply { + val cancelButtonViewIndex = it.patternMatch!!.startIndex + 2 + val cancelButtonViewRegister = + getInstruction(cancelButtonViewIndex).registerA - addInstruction( - cancelButtonViewIndex + 1, - "invoke-static {v$cancelButtonViewRegister}, $EXTENSION_CLASS_DESCRIPTOR->dismissDialog(Landroid/view/View;)V" - ) + addInstruction( + cancelButtonViewIndex + 1, + "invoke-static {v$cancelButtonViewRegister}, $EXTENSION_CLASS_DESCRIPTOR->dismissDialog(Landroid/view/View;)V" + ) + } } redditAlertDialogsFingerprint.methodOrThrow().apply { + val backgroundTintIndex = indexOfSetBackgroundTintListInstruction(this) val insertIndex = - indexOfFirstLiteralInstructionOrThrow( - textAppearanceRedditBaseOldButtonColored - ) + 1 + indexOfFirstInstructionOrThrow(backgroundTintIndex) { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "setTextAppearance" + } val insertRegister = getInstruction(insertIndex).registerC addInstruction( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/Fingerprints.kt index 79b69ffb4..a6ae79283 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/Fingerprints.kt @@ -1,6 +1,5 @@ package app.revanced.patches.reddit.layout.toolbar -import app.revanced.patches.reddit.utils.resourceid.toolBarNavSearchCtaContainer import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags @@ -10,7 +9,7 @@ internal val homePagerScreenFingerprint = legacyFingerprint( returnType = "Landroid/view/View;", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("Landroid/view/LayoutInflater;", "Landroid/view/ViewGroup;"), - literals = listOf(toolBarNavSearchCtaContainer), + strings = listOf("recapNavEntryPointDelegate"), customFingerprint = { method, _ -> method.definingClass.endsWith("/HomePagerScreen;") } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/ToolBarButtonPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/ToolBarButtonPatch.kt index 29c0b517a..0ddab6e57 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/ToolBarButtonPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/toolbar/ToolBarButtonPatch.kt @@ -5,12 +5,11 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.HIDE_TOOLBAR_BUTTON -import app.revanced.patches.reddit.utils.resourceid.sharedResourceIdPatch -import app.revanced.patches.reddit.utils.resourceid.toolBarNavSearchCtaContainer import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus -import app.revanced.util.fingerprint.methodOrThrow -import app.revanced.util.indexOfFirstLiteralInstructionOrThrow +import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction private const val EXTENSION_METHOD_DESCRIPTOR = @@ -21,22 +20,21 @@ private const val EXTENSION_METHOD_DESCRIPTOR = val toolBarButtonPatch = bytecodePatch { // compatibleWith(COMPATIBLE_PACKAGE) - dependsOn( - sharedResourceIdPatch, - settingsPatch - ) + dependsOn(settingsPatch) execute { - homePagerScreenFingerprint.methodOrThrow().apply { - val targetIndex = - indexOfFirstLiteralInstructionOrThrow(toolBarNavSearchCtaContainer) + 3 - val targetRegister = - getInstruction(targetIndex - 1).registerA + homePagerScreenFingerprint.matchOrThrow().let { + it.method.apply { + val stringIndex = it.stringMatches!!.first().index + val insertIndex = indexOfFirstInstructionOrThrow(stringIndex, Opcode.CHECK_CAST) + val insertRegister = + getInstruction(insertIndex).registerA - addInstruction( - targetIndex, - "invoke-static {v$targetRegister}, $EXTENSION_METHOD_DESCRIPTOR" - ) + addInstruction( + insertIndex, + "invoke-static {v$insertRegister}, $EXTENSION_METHOD_DESCRIPTOR" + ) + } } updatePatchStatus( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/Fingerprints.kt index 108e0d742..9779c5f99 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/Fingerprints.kt @@ -1,9 +1,26 @@ package app.revanced.patches.reddit.misc.openlink import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or 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.instruction.ReferenceInstruction + +internal val customReportsFingerprint = legacyFingerprint( + name = "customReportsFingerprint", + returnType = "V", + strings = listOf("https://www.crisistextline.org/", "screenNavigator"), + customFingerprint = { method, _ -> + indexOfScreenNavigatorInstruction(method) >= 0 + } +) + +fun indexOfScreenNavigatorInstruction(method: Method) = + method.indexOfFirstInstruction { + (this as? ReferenceInstruction)?.reference?.toString()?.contains("Landroid/app/Activity;Landroid/net/Uri;") == true + } internal val screenNavigatorFingerprint = legacyFingerprint( name = "screenNavigatorFingerprint", diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksDirectlyPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksDirectlyPatch.kt index d9b0e6728..d346ac29c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksDirectlyPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksDirectlyPatch.kt @@ -7,7 +7,6 @@ import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.OPEN_LINKS_DIRECTLY import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus -import app.revanced.util.fingerprint.methodOrThrow private const val EXTENSION_METHOD_DESCRIPTOR = "$PATCHES_PATH/OpenLinksDirectlyPatch;" + @@ -21,10 +20,13 @@ val openLinksDirectlyPatch = bytecodePatch( ) { compatibleWith(COMPATIBLE_PACKAGE) - dependsOn(settingsPatch) + dependsOn( + settingsPatch, + screenNavigatorMethodResolverPatch + ) execute { - screenNavigatorFingerprint.methodOrThrow().addInstructions( + screenNavigatorMethod.addInstructions( 0, """ invoke-static {p2}, $EXTENSION_METHOD_DESCRIPTOR move-result-object p2 diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksExternallyPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksExternallyPatch.kt index 781c0e48c..81e3f8e29 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksExternallyPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/OpenLinksExternallyPatch.kt @@ -24,10 +24,13 @@ val openLinksExternallyPatch = bytecodePatch( ) { compatibleWith(COMPATIBLE_PACKAGE) - dependsOn(settingsPatch) + dependsOn( + settingsPatch, + screenNavigatorMethodResolverPatch + ) execute { - screenNavigatorFingerprint.methodOrThrow().apply { + screenNavigatorMethod.apply { val insertIndex = indexOfFirstStringInstructionOrThrow("uri") + 2 addInstructionsWithLabels( diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/ScreenNavigatorMethodResolverPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/ScreenNavigatorMethodResolverPatch.kt new file mode 100644 index 000000000..b764fcfee --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/openlink/ScreenNavigatorMethodResolverPatch.kt @@ -0,0 +1,22 @@ +package app.revanced.patches.reddit.misc.openlink + +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getWalkerMethod + +lateinit var screenNavigatorMethod: MutableMethod + +val screenNavigatorMethodResolverPatch = bytecodePatch( + description = "screenNavigatorMethodResolverPatch" +) { + execute { + screenNavigatorMethod = + // ~ Reddit 2024.25.3 + screenNavigatorFingerprint.second.methodOrNull + // Reddit 2024.26.1 ~ + ?: with (customReportsFingerprint.methodOrThrow()) { + getWalkerMethod(indexOfScreenNavigatorInstruction(this)) + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/Fingerprints.kt index 739c84cf3..41ecdb04f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/Fingerprints.kt @@ -1,13 +1,21 @@ package app.revanced.patches.reddit.misc.tracking.url import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val shareLinkFormatterFingerprint = legacyFingerprint( name = "shareLinkFormatterFingerprint", returnType = "Ljava/lang/String;", parameters = listOf("Ljava/lang/String;", "Ljava/util/Map;"), - customFingerprint = { method, classDef -> - method.definingClass.startsWith("Lcom/reddit/sharing/") && - classDef.sourceFile == "UrlUtil.kt" + customFingerprint = { method, _ -> + indexOfClearQueryInstruction(method) >= 0 } ) + +fun indexOfClearQueryInstruction(method: Method) = + method.indexOfFirstInstruction { + getReference()?.toString() == "Landroid/net/Uri${'$'}Builder;->clearQuery()Landroid/net/Uri${'$'}Builder;" + } diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt index 450b2521f..7ef039926 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt @@ -4,11 +4,10 @@ import app.revanced.patcher.patch.PackageName import app.revanced.patcher.patch.VersionName internal object Constants { + internal const val REDDIT_PACKAGE_NAME = "com.reddit.frontpage" + val COMPATIBLE_PACKAGE: Pair?> = Pair( - "com.reddit.frontpage", - setOf( - "2023.12.0", - "2024.17.0" - ) + REDDIT_PACKAGE_NAME, + null ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt deleted file mode 100644 index 45fc71eba..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt +++ /dev/null @@ -1,49 +0,0 @@ -package app.revanced.patches.reddit.utils.resourceid - -import app.revanced.patcher.patch.resourcePatch -import app.revanced.patches.shared.mapping.ResourceType.ID -import app.revanced.patches.shared.mapping.ResourceType.STRING -import app.revanced.patches.shared.mapping.ResourceType.STYLE -import app.revanced.patches.shared.mapping.get -import app.revanced.patches.shared.mapping.resourceMappingPatch -import app.revanced.patches.shared.mapping.resourceMappings - -var cancelButton = -1L - private set -var labelAcknowledgements = -1L - private set -var screenShotShareBanner = -1L - private set -var textAppearanceRedditBaseOldButtonColored = -1L - private set -var toolBarNavSearchCtaContainer = -1L - private set - -internal val sharedResourceIdPatch = resourcePatch( - description = "sharedResourceIdPatch" -) { - dependsOn(resourceMappingPatch) - - execute { - cancelButton = resourceMappings[ - ID, - "cancel_button", - ] - labelAcknowledgements = resourceMappings[ - STRING, - "label_acknowledgements" - ] - screenShotShareBanner = resourceMappings[ - STRING, - "screenshot_share_banner_title" - ] - textAppearanceRedditBaseOldButtonColored = resourceMappings[ - STYLE, - "TextAppearance.RedditBase.OldButton.Colored" - ] - toolBarNavSearchCtaContainer = resourceMappings[ - ID, - "toolbar_nav_search_cta_container" - ] - } -} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/Fingerprints.kt index f5d7a9772..8390f47b4 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/Fingerprints.kt @@ -1,7 +1,6 @@ package app.revanced.patches.reddit.utils.settings import app.revanced.patches.reddit.utils.extension.Constants.EXTENSION_PATH -import app.revanced.patches.reddit.utils.resourceid.labelAcknowledgements import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags @@ -10,9 +9,8 @@ import com.android.tools.smali.dexlib2.Opcode internal val acknowledgementsLabelBuilderFingerprint = legacyFingerprint( name = "acknowledgementsLabelBuilderFingerprint", returnType = "Z", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("Landroidx/preference/Preference;"), - literals = listOf(labelAcknowledgements), + strings = listOf("onboardingAnalytics"), customFingerprint = { method, _ -> method.definingClass.startsWith("Lcom/reddit/screen/settings/preferences/") } @@ -32,6 +30,16 @@ internal val ossLicensesMenuActivityOnCreateFingerprint = legacyFingerprint( } ) +internal val redditInternalFeaturesFingerprint = legacyFingerprint( + name = "redditInternalFeaturesFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + strings = listOf("RELEASE"), + customFingerprint = { methodDef, _ -> + !methodDef.definingClass.startsWith("Lcom/") + } +) + internal val settingsStatusLoadFingerprint = legacyFingerprint( name = "settingsStatusLoadFingerprint", customFingerprint = { method, _ -> diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt index e872e637c..02948a413 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/settings/SettingsPatch.kt @@ -4,7 +4,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.stringOption @@ -14,15 +13,18 @@ import app.revanced.patches.reddit.utils.extension.Constants.EXTENSION_PATH import app.revanced.patches.reddit.utils.extension.sharedExtensionPatch import app.revanced.patches.reddit.utils.patch.PatchList import app.revanced.patches.reddit.utils.patch.PatchList.SETTINGS_FOR_REDDIT -import app.revanced.patches.reddit.utils.resourceid.labelAcknowledgements import app.revanced.patches.shared.sharedSettingFingerprint import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow -import app.revanced.util.indexOfFirstLiteralInstructionOrThrow +import app.revanced.util.indexOfFirstInstructionReversedOrThrow +import app.revanced.util.indexOfFirstStringInstructionOrThrow import app.revanced.util.valueOrThrow import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference import kotlin.io.path.exists private const val EXTENSION_METHOD_DESCRIPTOR = @@ -31,11 +33,29 @@ private const val EXTENSION_METHOD_DESCRIPTOR = private lateinit var acknowledgementsLabelBuilderMethod: MutableMethod private lateinit var settingsStatusLoadMethod: MutableMethod +var is_2024_26_or_greater = false + private set + private val settingsBytecodePatch = bytecodePatch( description = "settingsBytecodePatch" ) { execute { + + /** + * Set version info + */ + redditInternalFeaturesFingerprint.methodOrThrow().apply { + val versionIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.CONST_STRING + && (this as? BuilderInstruction21c)?.reference.toString().startsWith("202") + } + + val versionNumber = getInstruction(versionIndex).reference.toString().replace(".", "").toInt() + + is_2024_26_or_greater = 2024260 <= versionNumber + } + /** * Set SharedPrefCategory */ @@ -52,8 +72,8 @@ private val settingsBytecodePatch = bytecodePatch( /** * Replace settings label */ - acknowledgementsLabelBuilderMethod = acknowledgementsLabelBuilderFingerprint - .methodOrThrow() + acknowledgementsLabelBuilderMethod = + acknowledgementsLabelBuilderFingerprint.methodOrThrow() /** * Initialize settings activity @@ -77,8 +97,11 @@ private val settingsBytecodePatch = bytecodePatch( internal fun updateSettingsLabel(label: String) = acknowledgementsLabelBuilderMethod.apply { - val insertIndex = - indexOfFirstLiteralInstructionOrThrow(labelAcknowledgements) + 3 + val stringIndex = indexOfFirstStringInstructionOrThrow("onboardingAnalytics") + val insertIndex = indexOfFirstInstructionReversedOrThrow(stringIndex) { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "getString" + } + 2 val insertRegister = getInstruction(insertIndex - 1).registerA @@ -134,22 +157,25 @@ val settingsPatch = resourcePatch( val settingsLabel = settingsLabelOption .valueOrThrow() - arrayOf("preferences.xml", "preferences_logged_in.xml").forEach { targetXML -> + arrayOf( + "preferences.xml", + "preferences_logged_in.xml", + "preferences_logged_in_old.xml", + ).forEach { targetXML -> val resDirectory = get("res") val targetXml = resDirectory.resolve("xml").resolve(targetXML).toPath() - if (!targetXml.exists()) - throw PatchException("The preferences can not be found.") + if (targetXml.exists()) { + val preference = get("res/xml/$targetXML") - val preference = get("res/xml/$targetXML") - - preference.writeText( - preference.readText() - .replace( - "\"@drawable/icon_text_post\" android:title=\"@string/label_acknowledgements\"", - "\"@drawable/icon_beta_planet\" android:title=\"$settingsLabel\"" - ) - ) + preference.writeText( + preference.readText() + .replace( + "\"@drawable/icon_text_post\" android:title=\"@string/label_acknowledgements\"", + "\"@drawable/icon_beta_planet\" android:title=\"$settingsLabel\"" + ) + ) + } } updateSettingsLabel(settingsLabel)