fix
This commit is contained in:
parent
8c0c3b44e5
commit
50f95543f1
81 changed files with 393 additions and 588 deletions
|
|
@ -2,13 +2,11 @@ package app.revanced.patches.finanzonline.detection.root
|
|||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_REMOVE_ROOT_DETECTION
|
||||
import app.revanced.patches.shared.PATCH_NAME_REMOVE_ROOT_DETECTION
|
||||
|
||||
@Suppress("unused")
|
||||
val rootDetectionPatch = bytecodePatch(
|
||||
name = PATCH_NAME_REMOVE_ROOT_DETECTION,
|
||||
description = PATCH_DESCRIPTION_REMOVE_ROOT_DETECTION,
|
||||
name = "Remove root detection",
|
||||
description = "Removes the check for root permissions and unlocked bootloader.",
|
||||
) {
|
||||
compatibleWith("at.gv.bmf.bmf2go")
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import app.revanced.patcher.fingerprint
|
|||
import app.revanced.patcher.patch.booleanOption
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.instagram.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.shared.PATCH_NAME_HIDE_NAVIGATION_BUTTONS
|
||||
import app.revanced.util.addInstructionsAtControlFlowLabel
|
||||
import app.revanced.util.findFreeRegister
|
||||
import app.revanced.util.getReference
|
||||
|
|
@ -21,7 +20,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
|||
|
||||
@Suppress("unused")
|
||||
val hideNavigationButtonsPatch = bytecodePatch(
|
||||
name = PATCH_NAME_HIDE_NAVIGATION_BUTTONS,
|
||||
name = "Hide navigation buttons",
|
||||
description = "Hides navigation bar buttons, such as the Reels and Create button.",
|
||||
use = false
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import app.revanced.patcher.patch.bytecodePatch
|
|||
import app.revanced.patcher.patch.stringOption
|
||||
import app.revanced.patches.instagram.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.instagram.misc.share.editShareLinksPatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_CHANGE_LINK_SHARING_DOMAIN
|
||||
import app.revanced.patches.shared.PATCH_NAME_CHANGE_LINK_SHARING_DOMAIN
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
internal const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
|
|
@ -14,8 +12,8 @@ internal const val EXTENSION_CLASS_DESCRIPTOR =
|
|||
|
||||
@Suppress("unused")
|
||||
val changeLinkSharingDomainPatch = bytecodePatch(
|
||||
name = PATCH_NAME_CHANGE_LINK_SHARING_DOMAIN,
|
||||
description = PATCH_DESCRIPTION_CHANGE_LINK_SHARING_DOMAIN,
|
||||
name = "Change link sharing domain",
|
||||
description = "Replaces the domain name of shared links.",
|
||||
use = false
|
||||
) {
|
||||
compatibleWith("com.instagram.android")
|
||||
|
|
|
|||
|
|
@ -4,16 +4,14 @@ import app.revanced.patcher.extensions.addInstructions
|
|||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.instagram.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.instagram.misc.share.editShareLinksPatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.shared.PATCH_NAME_SANITIZE_SHARING_LINKS
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/instagram/misc/share/privacy/SanitizeSharingLinksPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
val sanitizeSharingLinksPatch = bytecodePatch(
|
||||
name = PATCH_NAME_SANITIZE_SHARING_LINKS,
|
||||
description = PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS,
|
||||
name = "Sanitize sharing links",
|
||||
description = "Removes the tracking query parameters from shared links.",
|
||||
) {
|
||||
compatibleWith("com.instagram.android")
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import app.revanced.util.returnEarly
|
|||
val signatureCheckPatch = bytecodePatch(
|
||||
name = "Disable signature check",
|
||||
description = "Disables the signature check that can cause the app to crash on startup. " +
|
||||
"Including this patch may cause issues with sharing or opening external Instagram links.",
|
||||
"Using this patch may cause issues with sharing or opening external Instagram links.",
|
||||
use = false
|
||||
) {
|
||||
compatibleWith("com.instagram.android")
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import app.revanced.patcher.patch.BytecodePatchContext
|
|||
import app.revanced.patcher.returnType
|
||||
|
||||
internal val BytecodePatchContext.googleApiActivityMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("onCreate")
|
||||
definingClass("GoogleApiActivity;"::endsWith)
|
||||
returnType("V")
|
||||
parameterTypes("Landroid/os/Bundle;")
|
||||
definingClass("GoogleApiActivity;"::endsWith)
|
||||
name("onCreate")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package app.revanced.patches.music.misc.settings
|
||||
|
||||
import app.revanced.patcher.classDef
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
|
|
@ -65,7 +65,7 @@ private val settingsResourcePatch = resourcePatch {
|
|||
}
|
||||
}
|
||||
|
||||
val Settings by creatingBytecodePatch(
|
||||
val settingsPatch = bytecodePatch(
|
||||
description = "Adds settings for ReVanced to YouTube Music."
|
||||
) {
|
||||
dependsOn(
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
package app.revanced.patches.music.playservice
|
||||
|
||||
import app.revanced.patcher.patch.creatingResourcePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.util.findPlayStoreServicesVersion
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
|
|
@ -21,8 +21,8 @@ var is_8_11_or_greater: Boolean by Delegates.notNull()
|
|||
var is_8_15_or_greater: Boolean by Delegates.notNull()
|
||||
private set
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Version check` by creatingResourcePatch(
|
||||
@Suppress("unused")
|
||||
val versionCheckPatch = resourcePatch(
|
||||
description = "Uses the Play Store service version to find the major/minor version of the YouTube Music target app."
|
||||
) {
|
||||
apply {
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ import app.revanced.patcher.returnType
|
|||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.isPremiumUseCaseImplMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
definingClass("IsPremiumUseCaseImpl;")
|
||||
name("doWork")
|
||||
definingClass("IsPremiumUseCaseImpl;"::endsWith)
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.mainActivityNavigateToNativePremiumUpsellMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("navigateToNativePremiumUpsell")
|
||||
definingClass("MainActivity;"::endsWith)
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
definingClass("MainActivity;")
|
||||
name("navigateToNativePremiumUpsell")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,23 @@
|
|||
package app.revanced.patches.nunl.ads
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.jwPlayerConfigMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
definingClass($$"Lcom/jwplayer/pub/api/configuration/PlayerConfig$Builder;")
|
||||
name("advertisingConfig")
|
||||
definingClass($$"Lcom/jwplayer/pub/api/configuration/PlayerConfig$Builder;")
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
}
|
||||
|
||||
internal val screenMapperMethodMatch = firstMethodComposite {
|
||||
name("map")
|
||||
definingClass("Lnl/nu/android/bff/data/mappers/ScreenMapper;")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Lnl/nu/android/bff/domain/models/screen/ScreenEntity;")
|
||||
parameterTypes("Lnl/nu/performance/api/client/objects/Screen;")
|
||||
|
||||
definingClass("Lnl/nu/android/bff/data/mappers/ScreenMapper;")
|
||||
name("map")
|
||||
|
||||
instructions(
|
||||
Opcode.MOVE_RESULT_OBJECT(),
|
||||
Opcode.IF_EQZ(),
|
||||
|
|
|
|||
|
|
@ -27,19 +27,17 @@ val `Hide ads` by creatingBytecodePatch(
|
|||
arrayOf(screenMapperMethodMatch, nextPageRepositoryImplMethodMatch).forEach { match ->
|
||||
// Index of instruction moving result of BlockPage;->getBlocks(...).
|
||||
val moveGetBlocksResultObjectIndex = match.indices.first()
|
||||
match.method.apply {
|
||||
val moveInstruction = getInstruction<OneRegisterInstruction>(moveGetBlocksResultObjectIndex)
|
||||
val moveInstruction = match.method.getInstruction<OneRegisterInstruction>(moveGetBlocksResultObjectIndex)
|
||||
|
||||
val listRegister = moveInstruction.registerA
|
||||
val listRegister = moveInstruction.registerA
|
||||
|
||||
// Add instruction after moving List<Block> to register and then filter this List<Block> in place.
|
||||
addInstructions(
|
||||
moveGetBlocksResultObjectIndex + 1,
|
||||
"""
|
||||
// Add instruction after moving List<Block> to register and then filter this List<Block> in place.
|
||||
match.method.addInstructions(
|
||||
moveGetBlocksResultObjectIndex + 1,
|
||||
"""
|
||||
invoke-static { v$listRegister }, Lapp/revanced/extension/nunl/ads/HideAdsPatch;->filterAds(Ljava/util/List;)V
|
||||
""",
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,20 @@
|
|||
package app.revanced.patches.nunl.firebase
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val firebaseClasses = arrayOf(
|
||||
internal fun BytecodePatchContext.getFingerprintHashForPackageMethods() = arrayOf(
|
||||
"Lcom/google/firebase/installations/remote/FirebaseInstallationServiceClient;",
|
||||
"Lcom/google/firebase/remoteconfig/internal/ConfigFetchHttpClient;",
|
||||
"Lcom/google/firebase/remoteconfig/internal/ConfigRealtimeHttpClient;"
|
||||
)
|
||||
|
||||
internal fun BytecodePatchContext.getFingerprintHashForPackageMethod(className: String) = firstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PRIVATE)
|
||||
definingClass(className)
|
||||
name("getFingerprintHashForPackage")
|
||||
returnType("Ljava/lang/String;")
|
||||
parameterTypes()
|
||||
).map {
|
||||
firstMutableMethodDeclaratively {
|
||||
name("getFingerprintHashForPackage")
|
||||
definingClass(it)
|
||||
accessFlags(AccessFlags.PRIVATE)
|
||||
returnType("Ljava/lang/String;")
|
||||
parameterTypes()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ val `Spoof certificate` by creatingBytecodePatch(
|
|||
compatibleWith("nl.sanomamedia.android.nu")
|
||||
|
||||
apply {
|
||||
firebaseClasses.forEach { className ->
|
||||
getFingerprintHashForPackageMethod(className).returnEarly("eae41fc018df2731a9b6ae1ac327da44a288667b")
|
||||
getFingerprintHashForPackageMethods().forEach {
|
||||
it.returnEarly("eae41fc018df2731a9b6ae1ac327da44a288667b")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import app.revanced.patcher.returnType
|
|||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.isDeviceRootedMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
name("isDeviceRooted")
|
||||
definingClass("/RootChecker;"::endsWith)
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
returnType("Z")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
package app.revanced.patches.orfon.detection.root
|
||||
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_REMOVE_ROOT_DETECTION
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Remove root detection` by creatingBytecodePatch(
|
||||
description = PATCH_DESCRIPTION_REMOVE_ROOT_DETECTION
|
||||
description = "Removes the check for root permissions and unlocked bootloader."
|
||||
) {
|
||||
compatibleWith("com.nousguide.android.orftvthek")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@ import app.revanced.patcher.patch.creatingBytecodePatch
|
|||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Enable Unlimited Skips` by creatingBytecodePatch(
|
||||
description = "Enable unlimited skips"
|
||||
) {
|
||||
val `Enable Unlimited Skips` by creatingBytecodePatch {
|
||||
compatibleWith("com.pandora.android")
|
||||
|
||||
apply {
|
||||
skipLimitBehaviorMethod.returnEarly("unlimited")
|
||||
getSkipLimitBehaviorMethod.returnEarly("unlimited")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import app.revanced.patcher.definingClass
|
|||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val BytecodePatchContext.skipLimitBehaviorMethod by gettingFirstMutableMethodDeclaratively {
|
||||
internal val BytecodePatchContext.getSkipLimitBehaviorMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("getSkipLimitBehavior")
|
||||
definingClass("UserData;"::endsWith)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import app.revanced.patcher.patch.creatingBytecodePatch
|
|||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Hide Ads` by creatingBytecodePatch(
|
||||
val `Hide ads` by creatingBytecodePatch(
|
||||
description = "Hides all video ads."
|
||||
) {
|
||||
compatibleWith("com.peacocktv.peacockandroid")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package app.revanced.patches.photomath.detection.signature
|
||||
|
||||
import app.revanced.patcher.allOf
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
|
|
@ -8,7 +7,7 @@ import com.android.tools.smali.dexlib2.Opcode
|
|||
|
||||
internal val checkSignatureMethodMatch = firstMethodComposite("SHA") {
|
||||
instructions(
|
||||
allOf(Opcode.CONST_STRING(), "SHA"()),
|
||||
Opcode.CONST_STRING(),
|
||||
Opcode.INVOKE_STATIC(),
|
||||
Opcode.INVOKE_STATIC(),
|
||||
Opcode.MOVE_RESULT_OBJECT(),
|
||||
|
|
|
|||
|
|
@ -12,9 +12,8 @@ val `Signature detection` by creatingBytecodePatch(
|
|||
apply {
|
||||
val replacementIndex = checkSignatureMethodMatch.indices.last()
|
||||
|
||||
checkSignatureMethodMatch.method.apply {
|
||||
val checkRegister = getInstruction<OneRegisterInstruction>(replacementIndex).registerA
|
||||
replaceInstruction(replacementIndex, "const/4 v$checkRegister, 0x1")
|
||||
}
|
||||
val checkRegister = checkSignatureMethodMatch.method.getInstruction<OneRegisterInstruction>(replacementIndex)
|
||||
.registerA
|
||||
checkSignatureMethodMatch.method.replaceInstruction(replacementIndex, "const/4 v$checkRegister, 0x1")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,15 @@
|
|||
package app.revanced.patches.photomath.misc.annoyances
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.hideUpdatePopupMethod by gettingFirstMutableMethodDeclaratively {
|
||||
definingClass("Lcom/microblink/photomath/main/activity/MainActivity;")
|
||||
accessFlags(AccessFlags.FINAL, AccessFlags.PUBLIC)
|
||||
returnType("V")
|
||||
definingClass("Lcom/microblink/photomath/main/activity/MainActivity;")
|
||||
instructions(
|
||||
Opcode.CONST_HIGH16(),
|
||||
Opcode.INVOKE_VIRTUAL(), // ViewPropertyAnimator.alpha(1.0f)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package app.revanced.patches.photomath.misc.unlock.bookpoint
|
||||
|
||||
import app.revanced.patcher.extensions.replaceInstructions
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
|
||||
@Suppress("unused")
|
||||
val `Enable bookpoint` by creatingBytecodePatch(
|
||||
val enableBookpointPatch = bytecodePatch(
|
||||
description = "Enables textbook access",
|
||||
) {
|
||||
|
||||
|
|
|
|||
|
|
@ -2,21 +2,18 @@ package app.revanced.patches.photomath.misc.unlock.bookpoint
|
|||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.isBookpointEnabledMethod by gettingFirstMutableMethodDeclaratively {
|
||||
internal val BytecodePatchContext.isBookpointEnabledMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"NoGeoData",
|
||||
"NoCountryInGeo",
|
||||
"RemoteConfig",
|
||||
"GeoRCMismatch"
|
||||
) {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
"NoGeoData"(),
|
||||
"NoCountryInGeo"(),
|
||||
"RemoteConfig"(),
|
||||
"GeoRCMismatch"()
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,10 @@ import app.revanced.patcher.accessFlags
|
|||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.patcher.string
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.isPlusUnlockedMethod by gettingFirstMutableMethodDeclaratively {
|
||||
internal val BytecodePatchContext.isPlusUnlockedMethod by gettingFirstMutableMethodDeclaratively("genius") {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
string("genius")
|
||||
definingClass("/User;"::endsWith)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ package app.revanced.patches.photomath.misc.unlock.plus
|
|||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patches.photomath.detection.signature.`Signature detection`
|
||||
import app.revanced.patches.photomath.misc.unlock.bookpoint.`Enable bookpoint`
|
||||
import app.revanced.patches.photomath.misc.unlock.bookpoint.enableBookpointPatch
|
||||
|
||||
@Suppress("unused")
|
||||
val `Unlock plus` by creatingBytecodePatch {
|
||||
dependsOn(`Signature detection`, `Enable bookpoint`)
|
||||
dependsOn(`Signature detection`, enableBookpointPatch)
|
||||
|
||||
compatibleWith("com.microblink.photomath")
|
||||
|
||||
|
|
|
|||
|
|
@ -33,34 +33,31 @@ val `Disable tracking` by creatingBytecodePatch(
|
|||
)
|
||||
|
||||
apply {
|
||||
facebookSDKMethod.apply {
|
||||
instructions.filter { instruction ->
|
||||
instruction.opcode == Opcode.CONST_STRING
|
||||
}.forEach { instruction ->
|
||||
instruction as OneRegisterInstruction
|
||||
facebookSDKMethod.instructions.filter { instruction ->
|
||||
instruction.opcode == Opcode.CONST_STRING
|
||||
}.forEach { instruction ->
|
||||
instruction as OneRegisterInstruction
|
||||
|
||||
replaceInstruction(
|
||||
instruction.location.index,
|
||||
"const-string v${instruction.registerA}, \"example.com\"",
|
||||
)
|
||||
}
|
||||
facebookSDKMethod.replaceInstruction(
|
||||
instruction.location.index,
|
||||
"const-string v${instruction.registerA}, \"example.com\"",
|
||||
)
|
||||
}
|
||||
|
||||
firebaseInstallMethod.apply {
|
||||
instructions.filter {
|
||||
it.opcode == Opcode.CONST_STRING
|
||||
}.filter {
|
||||
it.getReference<StringReference>()?.string == "firebaseinstallations.googleapis.com"
|
||||
}.forEach { instruction ->
|
||||
instruction as OneRegisterInstruction
|
||||
firebaseInstallMethod.instructions.filter {
|
||||
it.opcode == Opcode.CONST_STRING
|
||||
}.filter {
|
||||
it.getReference<StringReference>()?.string == "firebaseinstallations.googleapis.com"
|
||||
}.forEach { instruction ->
|
||||
instruction as OneRegisterInstruction
|
||||
|
||||
replaceInstruction(
|
||||
instruction.location.index,
|
||||
"const-string v${instruction.registerA}, \"example.com\"",
|
||||
)
|
||||
}
|
||||
firebaseInstallMethod.replaceInstruction(
|
||||
instruction.location.index,
|
||||
"const-string v${instruction.registerA}, \"example.com\"",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
appMeasurementMethod.addInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ internal val BytecodePatchContext.appMeasurementMethod by gettingFirstMutableMet
|
|||
}
|
||||
|
||||
internal val BytecodePatchContext.facebookSDKMethod by gettingFirstMutableMethodDeclaratively("instagram.com", "facebook.com") {
|
||||
accessFlags(AccessFlags.PRIVATE, AccessFlags.CONSTRUCTOR)
|
||||
accessFlags(AccessFlags.STATIC, AccessFlags.CONSTRUCTOR)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.firebaseInstallMethod by gettingFirstMutableMethodDeclaratively("https://%s/%s/%s", "firebaseinstallations.googleapis.com") {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import app.revanced.patcher.returnType
|
|||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.shouldShowAdsMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
definingClass("AdUtils;"::endsWith)
|
||||
name("shouldShowAds")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("Z")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,14 @@
|
|||
package app.revanced.patches.primevideo.ads
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.enterServerInsertedAdBreakStateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("enter")
|
||||
definingClass("Lcom/amazon/avod/media/ads/internal/state/ServerInsertedAdBreakState;")
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
parameterTypes("Lcom/amazon/avod/fsm/Trigger;")
|
||||
returnType("V")
|
||||
|
|
@ -22,11 +18,11 @@ internal val BytecodePatchContext.enterServerInsertedAdBreakStateMethod by getti
|
|||
Opcode.CONST_4(),
|
||||
Opcode.CONST_4()
|
||||
)
|
||||
name("enter")
|
||||
definingClass("Lcom/amazon/avod/media/ads/internal/state/ServerInsertedAdBreakState;")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.doTriggerMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("doTrigger")
|
||||
definingClass("Lcom/amazon/avod/fsm/StateBase;")
|
||||
accessFlags(AccessFlags.PROTECTED)
|
||||
returnType("V")
|
||||
instructions(
|
||||
|
|
@ -34,6 +30,4 @@ internal val BytecodePatchContext.doTriggerMethod by gettingFirstMutableMethodDe
|
|||
Opcode.INVOKE_INTERFACE(),
|
||||
Opcode.RETURN_VOID()
|
||||
)
|
||||
name("doTrigger")
|
||||
definingClass("Lcom/amazon/avod/fsm/StateBase;")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,22 @@
|
|||
package app.revanced.patches.primevideo.video.speed
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.playbackUserControlsInitializeMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("initialize")
|
||||
definingClass("Lcom/amazon/avod/playbackclient/activity/feature/PlaybackUserControlsFeature;")
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
parameterTypes("Lcom/amazon/avod/playbackclient/PlaybackInitializationContext;")
|
||||
returnType("V")
|
||||
name("initialize")
|
||||
definingClass("Lcom/amazon/avod/playbackclient/activity/feature/PlaybackUserControlsFeature;")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.playbackUserControlsPrepareForPlaybackMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("prepareForPlayback")
|
||||
definingClass("Lcom/amazon/avod/playbackclient/activity/feature/PlaybackUserControlsFeature;")
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
parameterTypes("Lcom/amazon/avod/playbackclient/PlaybackContext;")
|
||||
returnType("V")
|
||||
name("prepareForPlayback")
|
||||
definingClass("Lcom/amazon/avod/playbackclient/activity/feature/PlaybackUserControlsFeature;")
|
||||
}
|
||||
|
|
@ -9,8 +9,8 @@ import app.revanced.patcher.returnType
|
|||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.showReminderMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returnType("V")
|
||||
definingClass("AdsNotify;"::endsWith)
|
||||
name("show")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returnType("V")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
package app.revanced.patches.reddit.ad.banner
|
||||
|
||||
import app.revanced.patcher.patch.creatingResourcePatch
|
||||
|
||||
// Note that for now, this patch and anything using it will only work on
|
||||
// Reddit 2024.17.0 or older. Newer versions will crash during patching.
|
||||
// See https://github.com/ReVanced/revanced-patches/issues/3099
|
||||
@Suppress("unused")
|
||||
val `Hide banner` = creatingResourcePatch(
|
||||
description = "Hides banner ads from comments on subreddits.",
|
||||
) {
|
||||
apply {
|
||||
val resourceFilePath = "res/layout/merge_listheader_link_detail.xml"
|
||||
|
||||
document(resourceFilePath).use { document ->
|
||||
document.getElementsByTagName("merge").item(0).childNodes.apply {
|
||||
val attributes = arrayOf("height", "width")
|
||||
|
||||
for (i in 1 until length) {
|
||||
val view = item(i)
|
||||
if (
|
||||
view.hasAttributes() &&
|
||||
view.attributes.getNamedItem("android:id").nodeValue.endsWith("ad_view_stub")
|
||||
) {
|
||||
attributes.forEach { attribute ->
|
||||
view.attributes.getNamedItem("android:layout_$attribute").nodeValue = "0.0dip"
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package app.revanced.patches.nunl.ads
|
||||
package app.revanced.patches.reddit.ad.general
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.definingClass
|
||||
|
|
@ -9,16 +9,13 @@ import app.revanced.patcher.returnType
|
|||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.adPostMethod by gettingFirstMutableMethodDeclaratively("children") {
|
||||
definingClass("Listing;"::endsWith)
|
||||
returnType("V")
|
||||
// "children" are present throughout multiple versions
|
||||
instructions("children"())
|
||||
definingClass { endsWith("Listing;") }
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.newAdPostMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"feedElement", "com.reddit.cookie"
|
||||
"feedElement",
|
||||
"com.reddit.cookie"
|
||||
) {
|
||||
instructions(Opcode.INVOKE_VIRTUAL())
|
||||
instructions("feedElement"())
|
||||
instructions("com.reddit.cookie"())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ package app.revanced.patches.reddit.ad.general
|
|||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.removeInstruction
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patches.nunl.ads.adPostMethod
|
||||
import app.revanced.patches.nunl.ads.newAdPostMethod
|
||||
import app.revanced.patches.reddit.ad.comments.`Hide comment ads`
|
||||
import app.revanced.patches.reddit.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
|
||||
|
|
@ -14,9 +14,7 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
|||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Hide ads` by creatingBytecodePatch(
|
||||
description = "Hide ads"
|
||||
) {
|
||||
val `Hide ads` by creatingBytecodePatch {
|
||||
dependsOn(`Hide comment ads`, sharedExtensionPatch)
|
||||
|
||||
compatibleWith("com.reddit.frontpage")
|
||||
|
|
@ -26,32 +24,30 @@ val `Hide ads` by creatingBytecodePatch(
|
|||
|
||||
val filterMethodDescriptor =
|
||||
"Lapp/revanced/extension/reddit/patches/FilterPromotedLinksPatch;" +
|
||||
"->filterChildren(Ljava/lang/Iterable;)Ljava/util/List;"
|
||||
"->filterChildren(Ljava/lang/Iterable;)Ljava/util/List;"
|
||||
|
||||
adPostMethod.apply {
|
||||
val setPostsListChildren = implementation!!.instructions.first { instruction ->
|
||||
if (instruction.opcode != Opcode.IPUT_OBJECT) return@first false
|
||||
val setPostsListChildren = adPostMethod.implementation!!.instructions.first { instruction ->
|
||||
if (instruction.opcode != Opcode.IPUT_OBJECT) return@first false
|
||||
|
||||
val reference = (instruction as ReferenceInstruction).reference as FieldReference
|
||||
reference.name == "children"
|
||||
}
|
||||
|
||||
val castedInstruction = setPostsListChildren as Instruction22c
|
||||
val itemsRegister = castedInstruction.registerA
|
||||
val listInstanceRegister = castedInstruction.registerB
|
||||
|
||||
// postsList.children = filterChildren(postListItems)
|
||||
removeInstruction(setPostsListChildren.location.index)
|
||||
addInstructions(
|
||||
setPostsListChildren.location.index,
|
||||
"""
|
||||
invoke-static {v$itemsRegister}, $filterMethodDescriptor
|
||||
move-result-object v0
|
||||
iput-object v0, v$listInstanceRegister, ${castedInstruction.reference}
|
||||
""",
|
||||
)
|
||||
val reference = (instruction as ReferenceInstruction).reference as FieldReference
|
||||
reference.name == "children"
|
||||
}
|
||||
|
||||
val castedInstruction = setPostsListChildren as Instruction22c
|
||||
val itemsRegister = castedInstruction.registerA
|
||||
val listInstanceRegister = castedInstruction.registerB
|
||||
|
||||
// postsList.children = filterChildren(postListItems)
|
||||
adPostMethod.removeInstruction(setPostsListChildren.location.index)
|
||||
adPostMethod.addInstructions(
|
||||
setPostsListChildren.location.index,
|
||||
"""
|
||||
invoke-static {v$itemsRegister}, $filterMethodDescriptor
|
||||
move-result-object v0
|
||||
iput-object v0, v$listInstanceRegister, ${castedInstruction.reference}
|
||||
""",
|
||||
)
|
||||
|
||||
// endregion
|
||||
|
||||
// region Remove ads from popular and latest feed
|
||||
|
|
@ -60,10 +56,8 @@ val `Hide ads` by creatingBytecodePatch(
|
|||
// AdElementConverter is conveniently responsible for inserting all feed ads.
|
||||
// By removing the appending instruction no ad posts gets appended to the feed.
|
||||
|
||||
val index = newAdPostMethod.implementation!!.instructions.indexOfFirst {
|
||||
if (it.opcode != Opcode.INVOKE_VIRTUAL) return@indexOfFirst false
|
||||
|
||||
val reference = (it as ReferenceInstruction).reference as MethodReference
|
||||
val index = newAdPostMethod.indexOfFirstInstruction {
|
||||
val reference = getReference<MethodReference>() ?: return@indexOfFirstInstruction false
|
||||
|
||||
reference.name == "add" && reference.definingClass == "Ljava/util/ArrayList;"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@ package app.revanced.patches.reddit.customclients
|
|||
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
|
||||
const val INSTALL_NEW_CLIENT_METHOD = "install(Lokhttp3/OkHttpClient${'$'}Builder;)Lokhttp3/OkHttpClient;"
|
||||
const val CREATE_NEW_CLIENT_METHOD = "createClient()Lokhttp3/OkHttpClient;"
|
||||
|
||||
fun `Fix Redgifs API`(
|
||||
fun fixRedgifsApi(
|
||||
extensionPatch: Patch,
|
||||
block: BytecodePatchBuilder.() -> Unit = {},
|
||||
) = creatingBytecodePatch {
|
||||
) = bytecodePatch("Fix Redgifs API") {
|
||||
dependsOn(extensionPatch)
|
||||
|
||||
block()
|
||||
|
|
|
|||
|
|
@ -2,15 +2,17 @@ package app.revanced.patches.reddit.customclients
|
|||
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
|
||||
const val RESOLVE_S_LINK_METHOD = "patchResolveSLink(Ljava/lang/String;)Z"
|
||||
const val SET_ACCESS_TOKEN_METHOD = "patchSetAccessToken(Ljava/lang/String;)V"
|
||||
|
||||
fun `Fix s links`(
|
||||
fun fixSLinksPatch(
|
||||
extensionPatch: Patch,
|
||||
block: BytecodePatchBuilder.() -> Unit = {},
|
||||
) = creatingBytecodePatch {
|
||||
) = bytecodePatch(
|
||||
"Fix /s/ links",
|
||||
) {
|
||||
dependsOn(extensionPatch)
|
||||
|
||||
block()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package app.revanced.patches.reddit.customclients
|
|||
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.Option
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.stringOption
|
||||
|
||||
/**
|
||||
|
|
@ -11,10 +11,11 @@ import app.revanced.patcher.patch.stringOption
|
|||
* @param redirectUri The redirect URI of the Reddit OAuth client.
|
||||
* @param block The patch block. It is called with the client ID option.
|
||||
*/
|
||||
fun `Spoof client`(
|
||||
fun spoofClientPatch(
|
||||
redirectUri: String,
|
||||
block: BytecodePatchBuilder.(Option<String>) -> Unit = {},
|
||||
) = creatingBytecodePatch(
|
||||
) = bytecodePatch(
|
||||
name = "Spoof client",
|
||||
description = "Restores functionality of the app by using custom client ID.",
|
||||
) {
|
||||
block(
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
package app.revanced.patches.reddit.customclients.baconreader.api
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
|
||||
internal val BytecodePatchContext.getAuthorizationUrlMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"client_id=zACVn0dSFGdWqQ"
|
||||
)
|
||||
|
||||
internal val BytecodePatchContext.getClientIdMethod by gettingFirstMutableMethodDeclaratively("client_id=zACVn0dSFGdWqQ") {
|
||||
name("getAuthorizeUrl")
|
||||
definingClass { endsWith("RedditOAuth;") }
|
||||
internal val getAuthorizationUrlMethodMatch = firstMethodComposite {
|
||||
instructions("client_id=zACVn0dSFGdWqQ"())
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.requestTokenMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"zACVn0dSFGdWqQ",
|
||||
"kDm2tYpu9DqyWFFyPlNcXGEni4k"
|
||||
)
|
||||
internal val requestTokenMethodMatch = firstMethodComposite {
|
||||
instructions(
|
||||
"zACVn0dSFGdWqQ"(),
|
||||
"kDm2tYpu9DqyWFFyPlNcXGEni4k"(String::contains)
|
||||
)
|
||||
}
|
||||
|
|
@ -1,17 +1,13 @@
|
|||
package app.revanced.patches.reddit.customclients.baconreader.api
|
||||
|
||||
import app.revanced.patcher.MatchBuilder
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.`Spoof client`
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.patches.shared.misc.string.replaceStringPatch
|
||||
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.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
|
||||
val spoofClientPatch = `Spoof client`(redirectUri = "http://baconreader.com/auth") { clientIdOption ->
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "http://baconreader.com/auth") { clientIdOption ->
|
||||
dependsOn(
|
||||
// Redirects from SSL to WWW domain are bugged causing auth problems.
|
||||
// Manually rewrite the URLs to fix this.
|
||||
|
|
@ -26,22 +22,20 @@ val spoofClientPatch = `Spoof client`(redirectUri = "http://baconreader.com/auth
|
|||
val clientId by clientIdOption
|
||||
|
||||
apply {
|
||||
fun MutableMethod.patch(targetString: String, replacementString: String) {
|
||||
val clientIdIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_STRING && getReference<StringReference>()?.string == targetString
|
||||
}
|
||||
fun MatchBuilder.patch(replacementString: String) {
|
||||
val clientIdIndex = indices.first()
|
||||
|
||||
val clientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
|
||||
replaceInstruction(
|
||||
val clientIdRegister = method.getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
|
||||
method.replaceInstruction(
|
||||
clientIdIndex,
|
||||
"const-string v$clientIdRegister, \"$replacementString\"",
|
||||
)
|
||||
}
|
||||
|
||||
// Patch client id in authorization url.
|
||||
getAuthorizationUrlMethod.patch("client_id=zACVn0dSFGdWqQ", "client_id=$clientId")
|
||||
getAuthorizationUrlMethodMatch.patch("client_id=$clientId")
|
||||
|
||||
// Patch client id for access token request.
|
||||
requestTokenMethod.patch("zACVn0dSFGdWqQ", clientId!!)
|
||||
requestTokenMethodMatch.patch(clientId!!)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import app.revanced.patcher.patch.BytecodePatchContext
|
|||
import app.revanced.patcher.returnType
|
||||
|
||||
internal val BytecodePatchContext.getOkHttpClientMethod by gettingFirstMutableMethodDeclaratively {
|
||||
returnType("Lokhttp3/OkHttpClient;")
|
||||
parameterTypes()
|
||||
definingClass("Lcom/onelouder/baconreader/media/gfycat/RedGifsManager;")
|
||||
name("getOkhttpClient")
|
||||
returnType("Lokhttp3/OkHttpClient;")
|
||||
parameterTypes()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package app.revanced.patches.reddit.customclients.baconreader.fix.redgifs
|
|||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.removeInstructions
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.fixRedgifsApi
|
||||
import app.revanced.patches.reddit.customclients.INSTALL_NEW_CLIENT_METHOD
|
||||
import app.revanced.patches.reddit.customclients.baconreader.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.reddit.customclients.`Fix Redgifs API`
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
|
@ -16,7 +16,7 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
|||
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/baconreader/FixRedgifsApiPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
val fixRedgifsApi = `Fix Redgifs API`(
|
||||
val fixRedgifsApi = fixRedgifsApi(
|
||||
extensionPatch = sharedExtensionPatch
|
||||
) {
|
||||
compatibleWith(
|
||||
|
|
@ -27,26 +27,25 @@ val fixRedgifsApi = `Fix Redgifs API`(
|
|||
apply {
|
||||
// region Patch Redgifs OkHttp3 client.
|
||||
|
||||
getOkHttpClientMethod.apply {
|
||||
// Remove conflicting OkHttp interceptors.
|
||||
val originalInterceptorInstallIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.NEW_INSTANCE && getReference<TypeReference>()?.type == "Lcom/onelouder/baconreader/media/gfycat/RedGifsManager\$HeaderInterceptor;"
|
||||
}
|
||||
removeInstructions(originalInterceptorInstallIndex, 5)
|
||||
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
val reference = getReference<MethodReference>()
|
||||
reference?.name == "build" && reference.definingClass == "Lokhttp3/OkHttpClient\$Builder;"
|
||||
}
|
||||
val register = getInstruction<FiveRegisterInstruction>(index).registerC
|
||||
replaceInstruction(
|
||||
index,
|
||||
"""
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$INSTALL_NEW_CLIENT_METHOD
|
||||
"""
|
||||
)
|
||||
// Remove conflicting OkHttp interceptors.
|
||||
val originalInterceptorInstallIndex = getOkHttpClientMethod.indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.NEW_INSTANCE && getReference<TypeReference>()?.type == "Lcom/onelouder/baconreader/media/gfycat/RedGifsManager\$HeaderInterceptor;"
|
||||
}
|
||||
getOkHttpClientMethod.removeInstructions(originalInterceptorInstallIndex, 5)
|
||||
|
||||
// endregion
|
||||
val index = getOkHttpClientMethod.indexOfFirstInstructionOrThrow {
|
||||
val reference = getReference<MethodReference>()
|
||||
reference?.name == "build" && reference.definingClass == "Lokhttp3/OkHttpClient\$Builder;"
|
||||
}
|
||||
val register = getOkHttpClientMethod.getInstruction<FiveRegisterInstruction>(index).registerC
|
||||
getOkHttpClientMethod.replaceInstruction(
|
||||
index,
|
||||
"""
|
||||
invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->$INSTALL_NEW_CLIENT_METHOD
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
package app.revanced.patches.reddit.customclients.boostforreddit.ads
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Disable ads` by creatingBytecodePatch {
|
||||
compatibleWith("com.rubenmayayo.reddit")
|
||||
|
||||
apply {
|
||||
arrayOf(maxMediationMethod, admobMediationMethod).forEach { method ->
|
||||
method.addInstructions(0, "return-void")
|
||||
}
|
||||
maxMediationMethod.returnEarly()
|
||||
admobMediationMethod.returnEarly()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ internal val BytecodePatchContext.buildUserAgentMethod by gettingFirstMutableMet
|
|||
|
||||
internal val BytecodePatchContext.getClientIdMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("getClientId")
|
||||
definingClass { endsWith("Credentials;") }
|
||||
definingClass("Credentials;"::endsWith)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package app.revanced.patches.reddit.customclients.boostforreddit.api
|
|||
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.`Spoof client`
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.returnEarly
|
||||
|
|
@ -11,7 +11,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofClientPatch = `Spoof client`(redirectUri = "http://rubenmayayo.com") { clientIdOption ->
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com") { clientIdOption ->
|
||||
compatibleWith("com.rubenmayayo.reddit")
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
|
@ -29,14 +29,12 @@ val spoofClientPatch = `Spoof client`(redirectUri = "http://rubenmayayo.com") {
|
|||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
buildUserAgentMethod.apply {
|
||||
val userAgentTemplateIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_STRING && getReference<StringReference>()?.string == "%s:%s:%s (by /u/%s)"
|
||||
}
|
||||
val register = getInstruction<OneRegisterInstruction>(userAgentTemplateIndex).registerA
|
||||
|
||||
replaceInstruction(userAgentTemplateIndex, "const-string v$register, \"$userAgent\"")
|
||||
val userAgentTemplateIndex = buildUserAgentMethod.indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_STRING && getReference<StringReference>()?.string == "%s:%s:%s (by /u/%s)"
|
||||
}
|
||||
val register = buildUserAgentMethod.getInstruction<OneRegisterInstruction>(userAgentTemplateIndex).registerA
|
||||
|
||||
buildUserAgentMethod.replaceInstruction(userAgentTemplateIndex, "const-string v$register, \"$userAgent\"")
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
package app.revanced.patches.reddit.customclients.boostforreddit.fix.downloads
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.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.downloadAudioMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"/DASH_audio.mp4",
|
||||
"/audio"
|
||||
)
|
||||
internal val downloadAudioMethodMatch = firstMethodComposite {
|
||||
instructions(
|
||||
"/DASH_audio.mp4"(),
|
||||
"/audio"()
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,7 @@ package app.revanced.patches.reddit.customclients.boostforreddit.fix.downloads
|
|||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.util.findInstructionIndicesReversed
|
||||
import app.revanced.util.getReference
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Fix missing audio in video downloads` by creatingBytecodePatch(
|
||||
|
|
@ -16,21 +12,16 @@ val `Fix missing audio in video downloads` by creatingBytecodePatch(
|
|||
compatibleWith("com.rubenmayayo.reddit")
|
||||
|
||||
apply {
|
||||
val endpointReplacements = mapOf(
|
||||
"/DASH_audio.mp4" to "/DASH_AUDIO_128.mp4",
|
||||
"/audio" to "/DASH_AUDIO_64.mp4",
|
||||
val endpointReplacements = arrayOf(
|
||||
"/DASH_AUDIO_128.mp4",
|
||||
"/DASH_AUDIO_64.mp4",
|
||||
)
|
||||
|
||||
downloadAudioMethod.apply {
|
||||
endpointReplacements.forEach { (target, replacement) ->
|
||||
// Find all occurrences of the target string in the method
|
||||
findInstructionIndicesReversed {
|
||||
opcode == Opcode.CONST_STRING && getReference<StringReference>()?.string == target
|
||||
}.forEach { index ->
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
replaceInstruction(index, "const-string v$register, \"$replacement\"")
|
||||
}
|
||||
}
|
||||
downloadAudioMethodMatch.indices.forEachIndexed { index, i ->
|
||||
val replacement = endpointReplacements[i]
|
||||
val register = downloadAudioMethodMatch.method.getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
downloadAudioMethodMatch.method.replaceInstruction(index, "const-string v$register, \"$replacement\"")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
package app.revanced.patches.reddit.customclients.boostforreddit.fix.redgifs
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.classDef
|
||||
import app.revanced.patcher.custom
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
|
||||
internal val BytecodePatchContext.createOkHttpClientMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PRIVATE)
|
||||
|
|
@ -23,8 +18,5 @@ internal val BytecodePatchContext.createOkHttpClientMethod by gettingFirstMutabl
|
|||
Opcode.INVOKE_VIRTUAL(),
|
||||
Opcode.MOVE_RESULT_OBJECT()
|
||||
)
|
||||
|
||||
// Helper to capture the BytecodePatchContext for classDef access
|
||||
fun Method.isTargetSourceFile() = classDef.sourceFile == "RedGifsAPIv2.java"
|
||||
custom { isTargetSourceFile() }
|
||||
custom { immutableClassDef.sourceFile == "RedGifsAPIv2.java" }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
package app.revanced.patches.reddit.customclients.boostforreddit.fix.redgifs
|
||||
|
||||
import app.revanced.patcher.extensions.methodReference
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.CREATE_NEW_CLIENT_METHOD
|
||||
import app.revanced.patches.reddit.customclients.fixRedgifsApi
|
||||
import app.revanced.patches.reddit.customclients.boostforreddit.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.reddit.customclients.`Fix Redgifs API`
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/boostforreddit/FixRedgifsApiPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
val fixRedgifsApi = `Fix Redgifs API`(
|
||||
val fixRedgifsApi = fixRedgifsApi(
|
||||
extensionPatch = sharedExtensionPatch
|
||||
) {
|
||||
compatibleWith("com.rubenmayayo.reddit")
|
||||
|
|
@ -19,16 +18,14 @@ val fixRedgifsApi = `Fix Redgifs API`(
|
|||
apply {
|
||||
// region Patch Redgifs OkHttp3 client.
|
||||
|
||||
createOkHttpClientMethod.apply {
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
val reference = getReference<MethodReference>()
|
||||
reference?.name == "build" && reference.definingClass == "Lokhttp3/OkHttpClient\$Builder;"
|
||||
}
|
||||
replaceInstruction(
|
||||
index,
|
||||
"invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->$CREATE_NEW_CLIENT_METHOD"
|
||||
)
|
||||
val index = createOkHttpClientMethod.indexOfFirstInstructionOrThrow {
|
||||
val reference = methodReference
|
||||
reference?.name == "build" && reference.definingClass == "Lokhttp3/OkHttpClient\$Builder;"
|
||||
}
|
||||
createOkHttpClientMethod.replaceInstruction(
|
||||
index,
|
||||
"invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->$CREATE_NEW_CLIENT_METHOD"
|
||||
)
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import app.revanced.patcher.returnType
|
|||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.getOAuthAccessTokenMethod by gettingFirstMutableMethodDeclaratively("access_token") {
|
||||
definingClass("Lnet/dean/jraw/http/oauth/OAuthData;")
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
returnType("Ljava/lang/String;")
|
||||
definingClass("Lnet/dean/jraw/http/oauth/OAuthData;")
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.handleNavigationMethod by gettingFirstMutableMethodDeclaratively(
|
||||
|
|
|
|||
|
|
@ -20,21 +20,20 @@ val fixSlinksPatch = fixSLinksPatch(
|
|||
apply {
|
||||
// region Patch navigation handler.
|
||||
|
||||
handleNavigationMethod.apply {
|
||||
val urlRegister = "p1"
|
||||
val tempRegister = "v1"
|
||||
val urlRegister = "p1"
|
||||
val tempRegister = "v1"
|
||||
|
||||
handleNavigationMethod.addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { $urlRegister }, $EXTENSION_CLASS_DESCRIPTOR->$RESOLVE_S_LINK_METHOD
|
||||
move-result $tempRegister
|
||||
if-eqz $tempRegister, :continue
|
||||
return $tempRegister
|
||||
""",
|
||||
ExternalLabel("continue", handleNavigationMethod.getInstruction(0)),
|
||||
)
|
||||
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
"""
|
||||
invoke-static { $urlRegister }, $EXTENSION_CLASS_DESCRIPTOR->$RESOLVE_S_LINK_METHOD
|
||||
move-result $tempRegister
|
||||
if-eqz $tempRegister, :continue
|
||||
return $tempRegister
|
||||
""",
|
||||
ExternalLabel("continue", getInstruction(0)),
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package app.revanced.patches.reddit.customclients.infinityforreddit.api
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethod
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val apiUtilsFingerprint = fingerprint {
|
||||
strings("native-lib")
|
||||
}
|
||||
internal val BytecodePatchContext.apiUtilsMethod by gettingFirstMutableMethod("native-lib")
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
package app.revanced.patches.reddit.customclients.infinityforreddit.api
|
||||
|
||||
import app.revanced.patcher.extensions.toInstructions
|
||||
import app.revanced.patches.reddit.customclients.`Spoof client`
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
||||
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable
|
||||
|
||||
val spoofClientPatch = `Spoof client`(redirectUri = "infinity://localhost") { clientIdOption ->
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "infinity://localhost") { clientIdOption ->
|
||||
compatibleWith(
|
||||
"ml.docilealligator.infinityforreddit",
|
||||
"ml.docilealligator.infinityforreddit.plus",
|
||||
|
|
@ -17,7 +17,7 @@ val spoofClientPatch = `Spoof client`(redirectUri = "infinity://localhost") { cl
|
|||
val clientId by clientIdOption
|
||||
|
||||
apply {
|
||||
apiUtilsFingerprint.classDef.methods.apply {
|
||||
apiUtilsMethod.classDef.methods.apply {
|
||||
val getClientIdMethod = single { it.name == "getId" }.also(::remove)
|
||||
|
||||
val newGetClientIdMethod = ImmutableMethod(
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
package app.revanced.patches.reddit.customclients.infinityforreddit.subscription
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethod
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.literal
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val BytecodePatchContext.billingClientOnServiceConnectedMethod by gettingFirstMutableMethodDeclaratively("Billing service connected")
|
||||
internal val BytecodePatchContext.billingClientOnServiceConnectedMethod by gettingFirstMutableMethod("Billing service connected")
|
||||
|
||||
internal val BytecodePatchContext.startSubscriptionActivityMethod by gettingFirstMutableMethodDeclaratively {
|
||||
instructions(
|
||||
literal(0x10008000)
|
||||
)
|
||||
instructions(0x10008000L())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@ val `Unlock subscription` by creatingBytecodePatch(
|
|||
)
|
||||
|
||||
apply {
|
||||
setOf(
|
||||
billingClientOnServiceConnectedMethod,
|
||||
startSubscriptionActivityMethod,
|
||||
).forEach { it.returnEarly() }
|
||||
billingClientOnServiceConnectedMethod.returnEarly()
|
||||
startSubscriptionActivityMethod.returnEarly()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package app.revanced.patches.reddit.customclients.joeyforreddit.ads
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy.`Disable piracy detection`
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
@Suppress("unused", "ObjectPropertyName")
|
||||
val `Disable ads` by creatingBytecodePatch {
|
||||
|
|
@ -11,12 +11,6 @@ val `Disable ads` by creatingBytecodePatch {
|
|||
compatibleWith("o.o.joey")
|
||||
|
||||
apply {
|
||||
isAdFreeUserMethod.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
return v0
|
||||
""",
|
||||
)
|
||||
isAdFreeUserMethod.returnEarly(true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,9 @@ import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutab
|
|||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.patcher.string
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
internal val BytecodePatchContext.isAdFreeUserMethod by gettingFirstMutableMethodDeclaratively {
|
||||
internal val BytecodePatchContext.isAdFreeUserMethod by gettingFirstMutableMethodDeclaratively("AD_FREE_USER") {
|
||||
accessFlags(AccessFlags.PUBLIC)
|
||||
returnType("Z")
|
||||
string("AD_FREE_USER")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,8 @@
|
|||
package app.revanced.patches.reddit.customclients.infinity.api
|
||||
package app.revanced.patches.reddit.customclients.joeyforreddit.api
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.classDef
|
||||
import app.revanced.patcher.custom
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
|
|
@ -15,7 +10,7 @@ internal val BytecodePatchContext.authUtilityUserAgentMethod by gettingFirstMuta
|
|||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returnType("Ljava/lang/String;")
|
||||
instructions(Opcode.APUT_OBJECT())
|
||||
custom { classDef.sourceFile == "AuthUtility.java" }
|
||||
custom { immutableClassDef.sourceFile == "AuthUtility.java" }
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.getClientIdMethod by gettingFirstMutableMethodDeclaratively {
|
||||
|
|
@ -27,5 +22,5 @@ internal val BytecodePatchContext.getClientIdMethod by gettingFirstMutableMethod
|
|||
Opcode.MOVE_RESULT_OBJECT(),
|
||||
Opcode.RETURN_OBJECT(),
|
||||
)
|
||||
custom { classDef.sourceFile == "AuthUtility.java" }
|
||||
custom { immutableClassDef.sourceFile == "AuthUtility.java" }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
package app.revanced.patches.reddit.customclients.joeyforreddit.api
|
||||
|
||||
import app.revanced.patches.reddit.customclients.infinity.api.authUtilityUserAgentMethod
|
||||
import app.revanced.patches.reddit.customclients.infinity.api.getClientIdMethod
|
||||
import app.revanced.patches.reddit.customclients.`Spoof client`
|
||||
import app.revanced.patches.reddit.customclients.sync.detection.piracy.`Disable piracy detection`
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.patches.reddit.customclients.sync.detection.piracy.disablePiracyDetectionPatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
val spoofClientPatch = `Spoof client`(redirectUri = "https://127.0.0.1:65023/authorize_callback") { clientIdOption ->
|
||||
dependsOn(`Disable piracy detection`)
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "https://127.0.0.1:65023/authorize_callback") { clientIdOption ->
|
||||
dependsOn(disablePiracyDetectionPatch)
|
||||
|
||||
compatibleWith(
|
||||
"o.o.joey",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
package app.revanced.patches.reddit.customclients.joeyforreddit.detection.piracy
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
package app.revanced.patches.reddit.customclients.redditisfun.api
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.basicAuthorizationMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"yyOCBp.RHJhDKd",
|
||||
"fJOxVwBUyo*=f:<OoejWs:AqmIJ" // Encrypted basic authorization string.
|
||||
)
|
||||
internal val basicAuthorizationMethodMatch = firstMethodComposite {
|
||||
instructions(
|
||||
"yyOCBp.RHJhDKd"(),
|
||||
"fJOxVwBUyo*=f:<OoejWs:AqmIJ"() // Encrypted basic authorization string.
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.buildAuthorizationStringMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"yyOCBp.RHJhDKd",
|
||||
"client_id"
|
||||
)
|
||||
internal val buildAuthorizationStringMethodMatch = firstMethodComposite {
|
||||
instructions(
|
||||
"yyOCBp.RHJhDKd"(),
|
||||
"client_id"()
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.getUserAgentMethod by gettingFirstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
package app.revanced.patches.reddit.customclients.redditisfun.api
|
||||
|
||||
import app.revanced.patcher.Match
|
||||
import app.revanced.patcher.MatchBuilder
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.`Spoof client`
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofClientPatch = `Spoof client`(redirectUri = "redditisfun://auth") { clientIdOption ->
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { clientIdOption ->
|
||||
compatibleWith(
|
||||
"com.andrewshu.android.reddit",
|
||||
"com.andrewshu.android.redditdonation",
|
||||
|
|
@ -29,36 +29,23 @@ val spoofClientPatch = `Spoof client`(redirectUri = "redditisfun://auth") { clie
|
|||
*
|
||||
* @param string The string to replace the instruction with.
|
||||
* @param getReplacementIndex A function that returns the index of the instruction to replace
|
||||
* using the [Match.StringMatch] list from the [Match].
|
||||
* using the [Match.indices] list from the [Match].
|
||||
*/
|
||||
fun MutableMethod.replaceWith(
|
||||
fun MatchBuilder.replaceWith(
|
||||
string: String,
|
||||
offset: Int,
|
||||
getReplacementIndex: String
|
||||
) {
|
||||
val anchorIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_STRING && getReference<StringReference>()?.string == string
|
||||
}
|
||||
getReplacementIndex: List<Int>.() -> Int,
|
||||
) = method.apply {
|
||||
val replacementIndex = indices.getReplacementIndex()
|
||||
val clientIdRegister = getInstruction<OneRegisterInstruction>(replacementIndex).registerA
|
||||
|
||||
val targetIndex = anchorIndex + offset
|
||||
val clientIdRegister = getInstruction<OneRegisterInstruction>(targetIndex).registerA
|
||||
|
||||
replaceInstruction(targetIndex, "const-string v$clientIdRegister, \"$getReplacementIndex\"")
|
||||
replaceInstruction(replacementIndex, "const-string v$clientIdRegister, \"$string\"")
|
||||
}
|
||||
|
||||
// Patch OAuth authorization.
|
||||
buildAuthorizationStringMethod.replaceWith(
|
||||
string = "yyOCBp.RHJhDKd",
|
||||
offset = 4,
|
||||
getReplacementIndex = clientId!!
|
||||
)
|
||||
buildAuthorizationStringMethodMatch.replaceWith(clientId!!) { first() + 4 }
|
||||
|
||||
// Path basic authorization.
|
||||
basicAuthorizationMethod.replaceWith(
|
||||
string = "fJOxVwBUyo*=f:<OoejWs:AqmIJ",
|
||||
offset = 7,
|
||||
getReplacementIndex = "$clientId:"
|
||||
)
|
||||
basicAuthorizationMethodMatch.replaceWith("$clientId:") { last() + 7 }
|
||||
|
||||
// endregion
|
||||
|
||||
|
|
@ -76,9 +63,9 @@ val spoofClientPatch = `Spoof client`(redirectUri = "redditisfun://auth") { clie
|
|||
|
||||
// Reddit messed up and does not append a redirect uri to the authorization url to old.reddit.com/login.
|
||||
// Replace old.reddit.com with www.reddit.com to fix this.
|
||||
buildAuthorizationStringMethod.apply {
|
||||
buildAuthorizationStringMethodMatch.method.apply {
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
getReference<StringReference>()?.string?.contains("old.reddit.com") == true
|
||||
getReference<StringReference>()?.contains("old.reddit.com") == true
|
||||
}
|
||||
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
|
|
|||
|
|
@ -1,27 +1,28 @@
|
|||
package app.revanced.patches.reddit.customclients.relayforreddit.api
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
internal val BytecodePatchContext.getLoggedInBearerTokenMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"dj-xCIZQYiLbEg", "authorization_code"
|
||||
)
|
||||
|
||||
internal val BytecodePatchContext.getLoggedOutBearerTokenMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"dj-xCIZQYiLbEg", "https://oauth.reddit.com/grants/installed_client"
|
||||
)
|
||||
internal fun baseClientIdMethod(string: String) = firstMethodComposite {
|
||||
instructions(
|
||||
"dj-xCIZQYiLbEg"(),
|
||||
string()
|
||||
)
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.getRefreshTokenMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"dj-xCIZQYiLbEg", "refresh_token"
|
||||
)
|
||||
internal val getLoggedInBearerTokenMethodMatch = baseClientIdMethod("authorization_code")
|
||||
|
||||
internal val BytecodePatchContext.loginActivityClientIdMethod by gettingFirstMutableMethodDeclaratively(
|
||||
"dj-xCIZQYiLbEg", "&duration=permanent"
|
||||
)
|
||||
internal val getLoggedOutBearerTokenMethodMatch = baseClientIdMethod("https://oauth.reddit.com/grants/installed_client")
|
||||
|
||||
internal val getRefreshTokenMethodMatch = baseClientIdMethod("refresh_token")
|
||||
|
||||
internal val loginActivityClientIdMethodMatch = baseClientIdMethod("&duration=permanent")
|
||||
|
||||
internal val BytecodePatchContext.redditCheckDisableAPIMethod by gettingFirstMutableMethodDeclaratively("Reddit Disabled") {
|
||||
instructions(Opcode.IF_EQZ())
|
||||
|
|
|
|||
|
|
@ -1,19 +1,17 @@
|
|||
package app.revanced.patches.reddit.customclients.relayforreddit.api
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.`Spoof client`
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction10t
|
||||
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21t
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofClientPatch = `Spoof client`(redirectUri = "dbrady://relay") { clientIdOption ->
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") { clientIdOption ->
|
||||
compatibleWith(
|
||||
"free.reddit.news",
|
||||
"reddit.news",
|
||||
|
|
@ -25,22 +23,15 @@ val spoofClientPatch = `Spoof client`(redirectUri = "dbrady://relay") { clientId
|
|||
// region Patch client id.
|
||||
|
||||
listOf(
|
||||
loginActivityClientIdMethod,
|
||||
getLoggedInBearerTokenMethod,
|
||||
getLoggedOutBearerTokenMethod,
|
||||
getRefreshTokenMethod,
|
||||
).forEach { method ->
|
||||
method.apply {
|
||||
val clientIdIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_STRING && getReference<StringReference>()?.string == "dj-xCIZQYiLbEg"
|
||||
}
|
||||
val clientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
|
||||
loginActivityClientIdMethodMatch,
|
||||
getLoggedInBearerTokenMethodMatch,
|
||||
getLoggedOutBearerTokenMethodMatch,
|
||||
getRefreshTokenMethodMatch,
|
||||
).forEach { match ->
|
||||
val clientIdIndex = match.indices.first()
|
||||
val clientIdRegister = match.method.getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
|
||||
|
||||
replaceInstruction(
|
||||
clientIdIndex,
|
||||
"const-string v$clientIdRegister, \"$clientId\"",
|
||||
)
|
||||
}
|
||||
match.method.replaceInstruction(clientIdIndex, "const-string v$clientIdRegister, \"$clientId\"")
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
|
@ -48,7 +39,7 @@ val spoofClientPatch = `Spoof client`(redirectUri = "dbrady://relay") { clientId
|
|||
// region Patch miscellaneous.
|
||||
|
||||
// Do not load remote config which disables OAuth login remotely.
|
||||
setRemoteConfigMethod.addInstructions(0, "return-void")
|
||||
setRemoteConfigMethod.returnEarly()
|
||||
|
||||
// Prevent OAuth login being disabled remotely.
|
||||
redditCheckDisableAPIMethod.apply {
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ import app.revanced.patcher.patch.BytecodePatchContext
|
|||
|
||||
internal val BytecodePatchContext.getClientIdMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("getClientId")
|
||||
definingClass { endsWith("Credentials;") }
|
||||
definingClass("Credentials;"::endsWith)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package app.revanced.patches.reddit.customclients.slide.api
|
||||
|
||||
import app.revanced.patches.reddit.customclients.`Spoof client`
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.util.returnEarly
|
||||
|
||||
val spoofClientPatch = `Spoof client`(redirectUri = "http://www.ccrama.me") { clientIdOption ->
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "http://www.ccrama.me") { clientIdOption ->
|
||||
compatibleWith("me.ccrama.redditslide")
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package app.revanced.patches.reddit.customclients.sync.detection.piracy
|
||||
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.patch.creatingBytecodePatch
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
|
||||
val `Disable piracy detection` by creatingBytecodePatch(
|
||||
val disablePiracyDetectionPatch = bytecodePatch(
|
||||
description = "Disables detection of modified versions.",
|
||||
) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
package app.revanced.patches.reddit.customclients.sync.detection.piracy
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.extensions.reference
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
|
||||
|
|
@ -21,4 +20,10 @@ internal val BytecodePatchContext.piracyDetectionMethod by gettingFirstMutableMe
|
|||
Opcode.INVOKE_DIRECT(),
|
||||
Opcode.INVOKE_VIRTUAL(),
|
||||
)
|
||||
}
|
||||
// TODO: Convert to instructions() extension.
|
||||
custom {
|
||||
instructions.any {
|
||||
it.reference.toString() == "Lcom/github/javiersantos/piracychecker/PiracyChecker;"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package app.revanced.patches.reddit.customclients.sync.syncforlemmy.ads
|
||||
|
||||
import app.revanced.patches.reddit.customclients.sync.ads.disableAdsPatch
|
||||
import app.revanced.patches.reddit.customclients.sync.detection.piracy.`Disable piracy detection`
|
||||
import app.revanced.patches.reddit.customclients.sync.detection.piracy.disablePiracyDetectionPatch
|
||||
|
||||
@Suppress("unused")
|
||||
val disableAdsPatch = disableAdsPatch {
|
||||
dependsOn(`Disable piracy detection`)
|
||||
dependsOn(disablePiracyDetectionPatch)
|
||||
|
||||
compatibleWith("com.laurencedawson.reddit_sync")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@ import app.revanced.patcher.name
|
|||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val BytecodePatchContext.mainActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
definingClass("MainActivity;")
|
||||
name("onCreate")
|
||||
definingClass("MainActivity;"::endsWith)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,24 @@
|
|||
package app.revanced.patches.reddit.customclients.sync.syncforreddit.api
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethod
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.string
|
||||
|
||||
internal val BytecodePatchContext.getAuthorizationStringMethod by gettingFirstMutableMethodDeclaratively("authorize.compact?client_id")
|
||||
internal val getAuthorizationStringMethodMatch = firstMethodComposite {
|
||||
instructions(string("authorize.compact?client_id"::startsWith))
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.getBearerTokenMethod by gettingFirstMutableMethodDeclaratively("Basic")
|
||||
internal val getBearerTokenMethodMatch = firstMethodComposite {
|
||||
instructions(string("Basic"::startsWith))
|
||||
}
|
||||
|
||||
internal val BytecodePatchContext.getUserAgentMethod by gettingFirstMutableMethodDeclaratively("android:com.laurencedawson.reddit_sync")
|
||||
internal val BytecodePatchContext.getUserAgentMethod by gettingFirstMutableMethod(
|
||||
"android:com.laurencedawson.reddit_sync"
|
||||
)
|
||||
|
||||
internal val BytecodePatchContext.imgurImageAPIMethod by gettingFirstMutableMethodDeclaratively("https://imgur-apiv3.p.rapidapi.com/3/image")
|
||||
internal val imgurImageAPIMethodMatch = firstMethodComposite {
|
||||
instructions("https://imgur-apiv3.p.rapidapi.com/3/image"())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,20 @@ package app.revanced.patches.reddit.customclients.sync.syncforreddit.api
|
|||
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.`Spoof client`
|
||||
import app.revanced.patches.reddit.customclients.sync.detection.piracy.`Disable piracy detection`
|
||||
import app.revanced.patcher.extensions.stringReference
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.patches.reddit.customclients.sync.detection.piracy.disablePiracyDetectionPatch
|
||||
import app.revanced.patches.shared.misc.string.replaceStringPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.returnEarly
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
import java.util.Base64
|
||||
import java.util.*
|
||||
|
||||
@Suppress("unused")
|
||||
val spoofClientPatch = `Spoof client`(
|
||||
val spoofClientPatch = spoofClientPatch(
|
||||
redirectUri = "http://redditsync/auth",
|
||||
) { clientIdOption ->
|
||||
dependsOn(
|
||||
`Disable piracy detection`,
|
||||
disablePiracyDetectionPatch,
|
||||
// Redirects from SSL to WWW domain are bugged causing auth problems.
|
||||
// Manually rewrite the URLs to fix this.
|
||||
replaceStringPatch("ssl.reddit.com", "www.reddit.com")
|
||||
|
|
@ -35,30 +32,26 @@ val spoofClientPatch = `Spoof client`(
|
|||
apply {
|
||||
// region Patch client id.
|
||||
|
||||
getBearerTokenMethod.apply {
|
||||
getBearerTokenMethodMatch.match(getAuthorizationStringMethodMatch.immutableClassDef).method.apply {
|
||||
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
|
||||
returnEarly("Basic $auth")
|
||||
}
|
||||
|
||||
getAuthorizationStringMethod.apply {
|
||||
val occurrenceIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_STRING &&
|
||||
getReference<StringReference>()?.string?.contains("client_id=") == true
|
||||
val occurrenceIndex = getAuthorizationStringMethodMatch.indices.first()
|
||||
|
||||
getAuthorizationStringMethodMatch.method.apply {
|
||||
val authorizationStringInstruction = getInstruction<OneRegisterInstruction>(occurrenceIndex)
|
||||
val targetRegister = authorizationStringInstruction.registerA
|
||||
|
||||
val newAuthorizationUrl = authorizationStringInstruction.stringReference!!.string.replace(
|
||||
"client_id=.*?&".toRegex(),
|
||||
"client_id=$clientId&",
|
||||
)
|
||||
|
||||
replaceInstruction(
|
||||
occurrenceIndex,
|
||||
"const-string v$targetRegister, \"$newAuthorizationUrl\"",
|
||||
)
|
||||
}
|
||||
|
||||
val authorizationStringInstruction = getInstruction<OneRegisterInstruction>(occurrenceIndex)
|
||||
val targetRegister = authorizationStringInstruction.registerA
|
||||
val reference = authorizationStringInstruction.getReference<StringReference>()!!
|
||||
|
||||
val newAuthorizationUrl = reference.string.replace(
|
||||
"client_id=.*?&".toRegex(),
|
||||
"client_id=$clientId&",
|
||||
)
|
||||
|
||||
replaceInstruction(
|
||||
occurrenceIndex,
|
||||
"const-string v$targetRegister, \"$newAuthorizationUrl\"",
|
||||
)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
|
@ -75,17 +68,11 @@ val spoofClientPatch = `Spoof client`(
|
|||
|
||||
// region Patch Imgur API URL.
|
||||
|
||||
imgurImageAPIMethod.apply {
|
||||
val apiUrlIndex = indexOfFirstInstructionOrThrow {
|
||||
opcode == Opcode.CONST_STRING &&
|
||||
getReference<StringReference>()?.string == "https://api.imgur.com/3/image"
|
||||
}
|
||||
|
||||
replaceInstruction(
|
||||
apiUrlIndex,
|
||||
"const-string v1, \"https://api.imgur.com/3/image\"",
|
||||
)
|
||||
}
|
||||
val apiUrlIndex = imgurImageAPIMethodMatch.indices.first()
|
||||
imgurImageAPIMethodMatch.method.replaceInstruction(
|
||||
apiUrlIndex,
|
||||
"const-string v1, \"https://api.imgur.com/3/image\"",
|
||||
)
|
||||
|
||||
// endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import app.revanced.patcher.extensions.addInstructions
|
|||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.INSTALL_NEW_CLIENT_METHOD
|
||||
import app.revanced.patches.reddit.customclients.`Fix Redgifs API`
|
||||
import app.revanced.patches.reddit.customclients.fixRedgifsApi
|
||||
import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
|
|
@ -14,7 +14,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||
internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/syncforreddit/FixRedgifsApiPatch;"
|
||||
|
||||
@Suppress("unused")
|
||||
val fixRedgifsApi = `Fix Redgifs API`(
|
||||
val fixRedgifsApi = fixRedgifsApi(
|
||||
extensionPatch = sharedExtensionPatch
|
||||
) {
|
||||
compatibleWith(
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@ package app.revanced.patches.reddit.misc.tracking.url
|
|||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.shared.PATCH_NAME_SANITIZE_SHARING_LINKS
|
||||
|
||||
@Suppress("unused")
|
||||
val sanitizeUrlQueryPatch = bytecodePatch(
|
||||
name = PATCH_NAME_SANITIZE_SHARING_LINKS,
|
||||
description = PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS,
|
||||
name = "Sanitize sharing links",
|
||||
description = "Removes the tracking query parameters from shared links.",
|
||||
) {
|
||||
compatibleWith("com.reddit.frontpage")
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@ package app.revanced.patches.serviceportalbund.detection.root
|
|||
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_REMOVE_ROOT_DETECTION
|
||||
import app.revanced.patches.shared.PATCH_NAME_REMOVE_ROOT_DETECTION
|
||||
|
||||
@Suppress("unused")
|
||||
val rootDetectionPatch = bytecodePatch(
|
||||
name = PATCH_NAME_REMOVE_ROOT_DETECTION,
|
||||
description = PATCH_DESCRIPTION_REMOVE_ROOT_DETECTION
|
||||
name = "Remove root detection",
|
||||
description = "Removes the check for root permissions and unlocked bootloader."
|
||||
) {
|
||||
compatibleWith("at.gv.bka.serviceportal")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
package app.revanced.patches.shared
|
||||
|
||||
//
|
||||
// Names and descriptions used by different patches implementing the same feature.
|
||||
//
|
||||
|
||||
internal const val PATCH_NAME_REMOVE_ROOT_DETECTION = "Remove root detection"
|
||||
internal const val PATCH_DESCRIPTION_REMOVE_ROOT_DETECTION = "Removes the check for root permissions and unlocked bootloader."
|
||||
|
||||
internal const val PATCH_NAME_SANITIZE_SHARING_LINKS = "Sanitize sharing links"
|
||||
internal const val PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS = "Removes the tracking query parameters from shared links."
|
||||
|
||||
internal const val PATCH_NAME_CHANGE_LINK_SHARING_DOMAIN = "Change link sharing domain"
|
||||
internal const val PATCH_DESCRIPTION_CHANGE_LINK_SHARING_DOMAIN = "Replaces the domain name of shared links."
|
||||
|
||||
internal const val PATCH_NAME_HIDE_NAVIGATION_BUTTONS = "Hide navigation buttons"
|
||||
|
|
@ -8,8 +8,6 @@ import app.revanced.patcher.patch.BytecodePatchContext
|
|||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.shared.PATCH_NAME_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||
|
|
@ -30,8 +28,8 @@ internal fun sanitizeSharingLinksPatch(
|
|||
preferenceScreen: BasePreferenceScreen.Screen,
|
||||
replaceMusicLinksWithYouTube: Boolean = false
|
||||
) = bytecodePatch(
|
||||
name = PATCH_NAME_SANITIZE_SHARING_LINKS,
|
||||
description = PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS,
|
||||
name = "Sanitize sharing links",
|
||||
description = "Removes the tracking query parameters from shared links.",
|
||||
) {
|
||||
block()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ package app.revanced.patches.spotify.misc.privacy
|
|||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.shared.PATCH_NAME_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
|
|
@ -17,8 +15,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
|||
|
||||
@Suppress("unused")
|
||||
val sanitizeSharingLinksPatch = bytecodePatch(
|
||||
name = PATCH_NAME_SANITIZE_SHARING_LINKS,
|
||||
description = PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS,
|
||||
name = "Sanitize sharing links",
|
||||
description = "Removes the tracking query parameters from shared links.",
|
||||
) {
|
||||
compatibleWith("com.spotify.music")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
package app.revanced.patches.tiktok.misc.share
|
||||
|
||||
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.patches.shared.PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.shared.PATCH_NAME_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.tiktok.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.util.findFreeRegister
|
||||
import app.revanced.util.getReference
|
||||
|
|
@ -20,8 +17,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
|||
|
||||
@Suppress("unused")
|
||||
val sanitizeShareUrlsPatch = bytecodePatch(
|
||||
name = PATCH_NAME_SANITIZE_SHARING_LINKS,
|
||||
description = PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS,
|
||||
name = "Sanitize sharing links",
|
||||
description = "Removes the tracking query parameters from shared links.",
|
||||
) {
|
||||
dependsOn(sharedExtensionPatch)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import app.revanced.patcher.extensions.getInstruction
|
|||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.stringOption
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_CHANGE_LINK_SHARING_DOMAIN
|
||||
import app.revanced.patches.shared.PATCH_NAME_CHANGE_LINK_SHARING_DOMAIN
|
||||
import app.revanced.patches.twitter.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.returnEarly
|
||||
|
|
@ -62,8 +60,8 @@ internal val changeLinkSharingDomainResourcePatch = resourcePatch {
|
|||
|
||||
@Suppress("unused")
|
||||
val changeLinkSharingDomainPatch = bytecodePatch(
|
||||
name = PATCH_NAME_CHANGE_LINK_SHARING_DOMAIN,
|
||||
description = "$PATCH_DESCRIPTION_CHANGE_LINK_SHARING_DOMAIN Including this patch can prevent making posts that quote other posts.",
|
||||
name = "Change link sharing domain",
|
||||
description = "Replaces the domain name of shared links. Using this patch can prevent making posts that quote other posts.",
|
||||
use = false
|
||||
) {
|
||||
dependsOn(
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@ package app.revanced.patches.twitter.misc.links
|
|||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS
|
||||
import app.revanced.patches.shared.PATCH_NAME_SANITIZE_SHARING_LINKS
|
||||
|
||||
@Suppress("unused")
|
||||
val sanitizeSharingLinksPatch = bytecodePatch(
|
||||
name = PATCH_NAME_SANITIZE_SHARING_LINKS,
|
||||
description = PATCH_DESCRIPTION_SANITIZE_SHARING_LINKS,
|
||||
name = "Sanitize sharing links",
|
||||
description = "Removes the tracking query parameters from shared links.",
|
||||
) {
|
||||
compatibleWith(
|
||||
"com.twitter.android"(
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@ package app.revanced.patches.viber.misc.navbar
|
|||
import app.revanced.patcher.extensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.patch.booleanOption
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.shared.PATCH_NAME_HIDE_NAVIGATION_BUTTONS
|
||||
import java.util.logging.Logger
|
||||
|
||||
@Suppress("unused")
|
||||
val hideNavigationButtonsPatch = bytecodePatch(
|
||||
name = PATCH_NAME_HIDE_NAVIGATION_BUTTONS,
|
||||
name = "Hide navigation buttons",
|
||||
description = "Permanently hides navigation bar buttons, such as Explore and Marketplace.",
|
||||
use = false
|
||||
) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue