mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-04-29 22:24:31 +02:00
fix(Reddit - Disable screenshot popup): Screenshot popup not being completely removed https://github.com/inotia00/ReVanced_Extended/issues/1810
This commit is contained in:
parent
15db05c636
commit
bb5964ce98
@ -5,7 +5,7 @@ import app.revanced.extension.reddit.settings.Settings;
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class ScreenshotPopupPatch {
|
public class ScreenshotPopupPatch {
|
||||||
|
|
||||||
public static boolean disableScreenshotPopup() {
|
public static Boolean disableScreenshotPopup(Boolean original) {
|
||||||
return Settings.DISABLE_SCREENSHOT_POPUP.get();
|
return Settings.DISABLE_SCREENSHOT_POPUP.get() ? Boolean.FALSE : original;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
package app.revanced.patches.reddit.layout.screenshotpopup
|
|
||||||
|
|
||||||
import app.revanced.patches.reddit.utils.resourceid.actionShare
|
|
||||||
import app.revanced.patches.reddit.utils.resourceid.screenShotShareBanner
|
|
||||||
import app.revanced.util.containsLiteralInstruction
|
|
||||||
import app.revanced.util.fingerprint.legacyFingerprint
|
|
||||||
import app.revanced.util.or
|
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
|
|
||||||
internal val screenshotBannerContainerFingerprint = legacyFingerprint(
|
|
||||||
name = "screenshotTakenBannerFingerprint",
|
|
||||||
returnType = "V",
|
|
||||||
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
|
||||||
strings = listOf(
|
|
||||||
"bannerContainer",
|
|
||||||
"scope",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reddit 2025.06.0 ~
|
|
||||||
*/
|
|
||||||
internal val screenshotTakenBannerComposableFingerprint = legacyFingerprint(
|
|
||||||
name = "screenshotTakenBannerComposableFingerprint",
|
|
||||||
returnType = "L",
|
|
||||||
customFingerprint = { method, classDef ->
|
|
||||||
method.containsLiteralInstruction(actionShare) &&
|
|
||||||
method.containsLiteralInstruction(screenShotShareBanner) &&
|
|
||||||
classDef.type.startsWith("Lcom/reddit/sharing/screenshot/composables/") &&
|
|
||||||
method.name == "invoke"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ~ Reddit 2025.05.1
|
|
||||||
*/
|
|
||||||
internal val screenshotTakenBannerLambdaActionFingerprint = legacyFingerprint(
|
|
||||||
name = "screenshotTakenBannerLambdaFingerprint",
|
|
||||||
returnType = "V",
|
|
||||||
parameters = listOf("Landroidx/compose/runtime/", "I"),
|
|
||||||
customFingerprint = { method, _ ->
|
|
||||||
method.containsLiteralInstruction(actionShare) &&
|
|
||||||
method.name == "invoke"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ~ Reddit 2025.05.1
|
|
||||||
*/
|
|
||||||
internal val screenshotTakenBannerLambdaBannerFingerprint = legacyFingerprint(
|
|
||||||
name = "screenshotTakenBannerLambdaFingerprint",
|
|
||||||
returnType = "V",
|
|
||||||
parameters = listOf("Landroidx/compose/runtime/", "I"),
|
|
||||||
customFingerprint = { method, _ ->
|
|
||||||
method.containsLiteralInstruction(screenShotShareBanner) &&
|
|
||||||
method.name == "invoke"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
@ -1,37 +1,22 @@
|
|||||||
package app.revanced.patches.reddit.layout.screenshotpopup
|
package app.revanced.patches.reddit.layout.screenshotpopup
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.PatchException
|
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
|
||||||
import app.revanced.patcher.util.smali.ExternalLabel
|
|
||||||
import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE
|
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.extension.Constants.PATCHES_PATH
|
||||||
import app.revanced.patches.reddit.utils.patch.PatchList.DISABLE_SCREENSHOT_POPUP
|
import app.revanced.patches.reddit.utils.patch.PatchList.DISABLE_SCREENSHOT_POPUP
|
||||||
import app.revanced.patches.reddit.utils.resourceid.actionShare
|
|
||||||
import app.revanced.patches.reddit.utils.resourceid.screenShotShareBanner
|
|
||||||
import app.revanced.patches.reddit.utils.resourceid.sharedResourceIdPatch
|
|
||||||
import app.revanced.patches.reddit.utils.settings.is_2025_06_or_greater
|
|
||||||
import app.revanced.patches.reddit.utils.settings.settingsPatch
|
import app.revanced.patches.reddit.utils.settings.settingsPatch
|
||||||
import app.revanced.patches.reddit.utils.settings.updatePatchStatus
|
import app.revanced.patches.reddit.utils.settings.updatePatchStatus
|
||||||
import app.revanced.util.findMutableMethodOf
|
import app.revanced.util.findMutableMethodOf
|
||||||
import app.revanced.util.fingerprint.methodCall
|
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
|
||||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
|
||||||
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
|
|
||||||
import app.revanced.util.indexOfFirstStringInstruction
|
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.Method
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
private const val EXTENSION_METHOD_DESCRIPTOR =
|
|
||||||
"$PATCHES_PATH/ScreenshotPopupPatch;->disableScreenshotPopup()Z"
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val screenshotPopupPatch = bytecodePatch(
|
val screenshotPopupPatch = bytecodePatch(
|
||||||
DISABLE_SCREENSHOT_POPUP.title,
|
DISABLE_SCREENSHOT_POPUP.title,
|
||||||
@ -39,121 +24,62 @@ val screenshotPopupPatch = bytecodePatch(
|
|||||||
) {
|
) {
|
||||||
compatibleWith(COMPATIBLE_PACKAGE)
|
compatibleWith(COMPATIBLE_PACKAGE)
|
||||||
|
|
||||||
dependsOn(
|
dependsOn(settingsPatch)
|
||||||
settingsPatch,
|
|
||||||
sharedResourceIdPatch,
|
|
||||||
)
|
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
|
|
||||||
val screenshotTriggerSharingListenerMethodCall =
|
fun indexOfShowBannerInstruction(method: Method) =
|
||||||
screenshotBannerContainerFingerprint.methodCall()
|
|
||||||
|
|
||||||
fun indexOfScreenshotTriggerInstruction(method: Method) =
|
|
||||||
method.indexOfFirstInstruction {
|
method.indexOfFirstInstruction {
|
||||||
getReference<MethodReference>()?.toString() == screenshotTriggerSharingListenerMethodCall
|
val reference = getReference<FieldReference>()
|
||||||
|
opcode == Opcode.IGET_OBJECT &&
|
||||||
|
reference?.name?.contains("shouldShowBanner") == true &&
|
||||||
|
reference.definingClass.startsWith("Lcom/reddit/sharing/screenshot/") == true
|
||||||
}
|
}
|
||||||
|
|
||||||
val isScreenshotTriggerMethod: Method.() -> Boolean = {
|
fun indexOfSetValueInstruction(method: Method) =
|
||||||
indexOfScreenshotTriggerInstruction(this) >= 0
|
method.indexOfFirstInstruction {
|
||||||
}
|
getReference<MethodReference>()?.name == "setValue"
|
||||||
|
|
||||||
var hookCount = 0
|
|
||||||
|
|
||||||
fun MutableMethod.hook() {
|
|
||||||
if (returnType == "V") {
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
0, """
|
|
||||||
invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR
|
|
||||||
move-result v0
|
|
||||||
if-eqz v0, :shown
|
|
||||||
return-void
|
|
||||||
""", ExternalLabel("shown", getInstruction(0))
|
|
||||||
)
|
|
||||||
|
|
||||||
hookCount++
|
|
||||||
} else if (returnType.startsWith("L")) { // Reddit 2025.06+
|
|
||||||
val insertIndex =
|
|
||||||
indexOfFirstStringInstruction("screenshotTriggerSharingListener")
|
|
||||||
|
|
||||||
if (insertIndex >= 0) {
|
|
||||||
val insertRegister =
|
|
||||||
getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
|
||||||
val triggerIndex =
|
|
||||||
indexOfScreenshotTriggerInstruction(this)
|
|
||||||
val jumpIndex =
|
|
||||||
indexOfFirstInstructionOrThrow(triggerIndex, Opcode.RETURN_OBJECT)
|
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
insertIndex, """
|
|
||||||
invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR
|
|
||||||
move-result v$insertRegister
|
|
||||||
if-nez v$insertRegister, :hidden
|
|
||||||
""", ExternalLabel("hidden", getInstruction(jumpIndex))
|
|
||||||
)
|
|
||||||
|
|
||||||
hookCount++
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
screenshotBannerContainerFingerprint
|
fun indexOfBooleanInstruction(method: Method, startIndex: Int = 0) =
|
||||||
.methodOrThrow()
|
method.indexOfFirstInstruction(startIndex) {
|
||||||
.hook()
|
val reference = getReference<FieldReference>()
|
||||||
|
opcode == Opcode.SGET_OBJECT &&
|
||||||
|
reference?.definingClass == "Ljava/lang/Boolean;" &&
|
||||||
|
reference.type == "Ljava/lang/Boolean;"
|
||||||
|
}
|
||||||
|
|
||||||
|
val isScreenShotMethod: Method.() -> Boolean = {
|
||||||
|
definingClass.startsWith("Lcom/reddit/sharing/screenshot/") &&
|
||||||
|
name == "invokeSuspend" &&
|
||||||
|
indexOfShowBannerInstruction(this) >= 0 &&
|
||||||
|
indexOfBooleanInstruction(this) >= 0 &&
|
||||||
|
indexOfSetValueInstruction(this) >= 0
|
||||||
|
}
|
||||||
|
|
||||||
classes.forEach { classDef ->
|
classes.forEach { classDef ->
|
||||||
classDef.methods.forEach { method ->
|
classDef.methods.forEach { method ->
|
||||||
if (method.isScreenshotTriggerMethod()) {
|
if (method.isScreenShotMethod()) {
|
||||||
proxy(classDef)
|
proxy(classDef)
|
||||||
.mutableClass
|
.mutableClass
|
||||||
.findMutableMethodOf(method)
|
.findMutableMethodOf(method)
|
||||||
.hook()
|
.apply {
|
||||||
|
val showBannerIndex = indexOfShowBannerInstruction(this)
|
||||||
|
val booleanIndex = indexOfBooleanInstruction(this, showBannerIndex)
|
||||||
|
val booleanRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(booleanIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
booleanIndex + 1, """
|
||||||
|
invoke-static {v$booleanRegister}, $PATCHES_PATH/ScreenshotPopupPatch;->disableScreenshotPopup(Ljava/lang/Boolean;)Ljava/lang/Boolean;
|
||||||
|
move-result-object v$booleanRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hookCount == 0) {
|
|
||||||
throw PatchException("Failed to find hook method")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_2025_06_or_greater) {
|
|
||||||
screenshotTakenBannerComposableFingerprint.methodOrThrow().apply {
|
|
||||||
arrayOf(
|
|
||||||
actionShare,
|
|
||||||
screenShotShareBanner
|
|
||||||
).forEach { literal ->
|
|
||||||
val literalIndex = indexOfFirstLiteralInstructionOrThrow(literal)
|
|
||||||
val insertIndex = indexOfFirstInstructionReversedOrThrow(literalIndex, Opcode.CONST_4)
|
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
|
||||||
val jumpIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.SGET_OBJECT)
|
|
||||||
|
|
||||||
addInstructionsWithLabels(
|
|
||||||
insertIndex, """
|
|
||||||
invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR
|
|
||||||
move-result v$insertRegister
|
|
||||||
if-nez v$insertRegister, :hidden
|
|
||||||
""", ExternalLabel("hidden", getInstruction(jumpIndex))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
arrayOf(
|
|
||||||
screenshotTakenBannerLambdaActionFingerprint,
|
|
||||||
screenshotTakenBannerLambdaBannerFingerprint
|
|
||||||
).forEach { fingerprint ->
|
|
||||||
fingerprint.methodOrThrow().addInstructionsWithLabels(
|
|
||||||
0, """
|
|
||||||
invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR
|
|
||||||
move-result v0
|
|
||||||
if-eqz v0, :ignore
|
|
||||||
return-void
|
|
||||||
:ignore
|
|
||||||
nop
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePatchStatus(
|
updatePatchStatus(
|
||||||
"enableScreenshotPopup",
|
"enableScreenshotPopup",
|
||||||
DISABLE_SCREENSHOT_POPUP
|
DISABLE_SCREENSHOT_POPUP
|
||||||
|
@ -5,12 +5,8 @@ import app.revanced.patches.shared.mapping.ResourceType.STRING
|
|||||||
import app.revanced.patches.shared.mapping.getResourceId
|
import app.revanced.patches.shared.mapping.getResourceId
|
||||||
import app.revanced.patches.shared.mapping.resourceMappingPatch
|
import app.revanced.patches.shared.mapping.resourceMappingPatch
|
||||||
|
|
||||||
var actionShare = -1L
|
|
||||||
private set
|
|
||||||
var nsfwDialogTitle = -1L
|
var nsfwDialogTitle = -1L
|
||||||
private set
|
private set
|
||||||
var screenShotShareBanner = -1L
|
|
||||||
private set
|
|
||||||
|
|
||||||
internal val sharedResourceIdPatch = resourcePatch(
|
internal val sharedResourceIdPatch = resourcePatch(
|
||||||
description = "sharedResourceIdPatch"
|
description = "sharedResourceIdPatch"
|
||||||
@ -18,8 +14,6 @@ internal val sharedResourceIdPatch = resourcePatch(
|
|||||||
dependsOn(resourceMappingPatch)
|
dependsOn(resourceMappingPatch)
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
actionShare = getResourceId(STRING, "action_share")
|
|
||||||
nsfwDialogTitle = getResourceId(STRING, "nsfw_dialog_title")
|
nsfwDialogTitle = getResourceId(STRING, "nsfw_dialog_title")
|
||||||
screenShotShareBanner = getResourceId(STRING, "screenshot_share_banner_title")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user