mirror of
https://github.com/revanced/revanced-patches
synced 2024-12-25 08:05:48 +01:00
build: Bump ReVanced Patcher (#3862)
Co-authored-by: Ushie <ushiekane@gmail.com>
This commit is contained in:
parent
e32b19e170
commit
8da05ab46d
@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
revanced-patcher = "20.0.2"
|
||||
revanced-patcher = "21.0.0"
|
||||
# Tracking https://github.com/google/smali/issues/64.
|
||||
#noinspection GradleDependency
|
||||
smali = "3.0.5"
|
||||
@ -7,7 +7,7 @@ gson = "2.11.0"
|
||||
# 8.3.0 causes java verifier error: https://github.com/ReVanced/revanced-patches/issues/2818.
|
||||
#noinspection GradleDependency
|
||||
agp = "8.2.2"
|
||||
annotation = "1.9.0"
|
||||
annotation = "1.9.1"
|
||||
appcompat = "1.7.0"
|
||||
okhttp = "5.0.0-alpha.14"
|
||||
retrofit = "2.11.0"
|
||||
|
@ -533,7 +533,7 @@ public final class app/revanced/patches/shared/misc/checks/BaseCheckEnvironmentP
|
||||
|
||||
public final class app/revanced/patches/shared/misc/extension/ExtensionHook {
|
||||
public final fun getFingerprint ()Lapp/revanced/patcher/Fingerprint;
|
||||
public final fun invoke (Ljava/lang/String;)V
|
||||
public final fun invoke (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/misc/extension/SharedExtensionPatchKt {
|
||||
@ -551,10 +551,10 @@ public final class app/revanced/patches/shared/misc/gms/FingerprintsKt {
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/misc/gms/GmsCoreSupportPatchKt {
|
||||
public static final fun gmsCoreSupportPatch (Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/Fingerprint;Ljava/util/Set;Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static synthetic fun gmsCoreSupportPatch$default (Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/Fingerprint;Ljava/util/Set;Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static final fun gmsCoreSupportResourcePatch (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/patch/Option;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||
public static synthetic fun gmsCoreSupportResourcePatch$default (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/patch/Option;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||
public static final fun gmsCoreSupportPatch (Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/Fingerprint;Ljava/util/Set;Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static synthetic fun gmsCoreSupportPatch$default (Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/Fingerprint;Ljava/util/Set;Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/Patch;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
public static final fun gmsCoreSupportResourcePatch (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/patch/Option;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||
public static synthetic fun gmsCoreSupportResourcePatch$default (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lapp/revanced/patcher/patch/Option;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/shared/misc/hex/HexPatchKt {
|
||||
@ -979,13 +979,8 @@ public final class app/revanced/patches/twitter/misc/hook/json/JsonHook {
|
||||
public fun <init> (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;)V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/twitter/misc/hook/json/JsonHookPatchHook : java/io/Closeable {
|
||||
public fun <init> (Lapp/revanced/patcher/Fingerprint;)V
|
||||
public final fun addHook (Lapp/revanced/patches/twitter/misc/hook/json/JsonHook;)V
|
||||
public fun close ()V
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/twitter/misc/hook/json/JsonHookPatchKt {
|
||||
public static final fun addJsonHook (Lapp/revanced/patcher/patch/BytecodePatchContext;Lapp/revanced/patches/twitter/misc/hook/json/JsonHook;)V
|
||||
public static final fun getJsonHookPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
@ -1432,7 +1427,6 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat
|
||||
}
|
||||
|
||||
public final class app/revanced/util/BytecodeUtilsKt {
|
||||
public static final fun applyMatch (Lapp/revanced/patcher/Fingerprint;Lapp/revanced/patcher/patch/BytecodePatchContext;Lapp/revanced/patcher/Match;)Lapp/revanced/patcher/Match;
|
||||
public static final fun containsLiteralInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
|
||||
public static final fun findInstructionIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)Ljava/util/List;
|
||||
public static final fun findInstructionIndicesReversed (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
|
||||
@ -1440,8 +1434,6 @@ public final class app/revanced/util/BytecodeUtilsKt {
|
||||
public static final fun findInstructionIndicesReversedOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Ljava/util/List;
|
||||
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
|
||||
public static final fun forEachLiteralValueInstruction (Lapp/revanced/patcher/patch/BytecodePatchContext;JLkotlin/jvm/functions/Function2;)V
|
||||
public static final fun getException (Lapp/revanced/patcher/Fingerprint;)Lapp/revanced/patcher/patch/PatchException;
|
||||
public static final fun getMatchOrThrow (Lapp/revanced/patcher/Fingerprint;)Lapp/revanced/patcher/Match;
|
||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILcom/android/tools/smali/dexlib2/Opcode;)I
|
||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;ILkotlin/jvm/functions/Function1;)I
|
||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/Opcode;)I
|
||||
@ -1468,12 +1460,8 @@ public final class app/revanced/util/BytecodeUtilsKt {
|
||||
public static final fun indexOfFirstResourceIdOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
||||
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
|
||||
public static final fun literal (Lapp/revanced/patcher/FingerprintBuilder;Lkotlin/jvm/functions/Function0;)V
|
||||
public static final fun returnEarly (Lapp/revanced/patcher/Fingerprint;Z)V
|
||||
public static final fun returnEarly (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Z)V
|
||||
public static final fun returnEarly (Ljava/lang/Iterable;Z)V
|
||||
public static synthetic fun returnEarly$default (Lapp/revanced/patcher/Fingerprint;ZILjava/lang/Object;)V
|
||||
public static synthetic fun returnEarly$default (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ZILjava/lang/Object;)V
|
||||
public static synthetic fun returnEarly$default (Ljava/lang/Iterable;ZILjava/lang/Object;)V
|
||||
public static final fun transformMethods (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V
|
||||
public static final fun traverseClassHierarchy (Lapp/revanced/patcher/patch/BytecodePatchContext;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V
|
||||
}
|
||||
|
@ -21,6 +21,12 @@ dependencies {
|
||||
compileOnly(project(":patches:stub"))
|
||||
}
|
||||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
freeCompilerArgs = listOf("-Xcontext-receivers")
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
|
@ -8,10 +8,10 @@ val exportAllActivitiesPatch = resourcePatch(
|
||||
description = "Makes all app activities exportable.",
|
||||
use = false,
|
||||
) {
|
||||
execute { context ->
|
||||
execute {
|
||||
val exportedFlag = "android:exported"
|
||||
|
||||
context.document["AndroidManifest.xml"].use { document ->
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
val activities = document.getElementsByTagName("activity")
|
||||
|
||||
for (i in 0..activities.length) {
|
||||
|
@ -8,8 +8,8 @@ val enableAndroidDebuggingPatch = resourcePatch(
|
||||
description = "Enables Android debugging capabilities. This can slow down the app.",
|
||||
use = false,
|
||||
) {
|
||||
execute { context ->
|
||||
context.document["AndroidManifest.xml"].use { document ->
|
||||
execute {
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
val applicationNode =
|
||||
document
|
||||
.getElementsByTagName("application")
|
||||
|
@ -8,10 +8,10 @@ val predictiveBackGesturePatch = resourcePatch(
|
||||
description = "Enables the predictive back gesture introduced on Android 13.",
|
||||
use = false,
|
||||
) {
|
||||
execute { context ->
|
||||
execute {
|
||||
val flag = "android:enableOnBackInvokedCallback"
|
||||
|
||||
context.document["AndroidManifest.xml"].use { document ->
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
with(document.getElementsByTagName("application").item(0)) {
|
||||
if (attributes.getNamedItem(flag) != null) return@with
|
||||
|
||||
|
@ -14,11 +14,11 @@ val overrideCertificatePinningPatch = resourcePatch(
|
||||
) {
|
||||
dependsOn(enableAndroidDebuggingPatch)
|
||||
|
||||
execute { context ->
|
||||
val resXmlDirectory = context["res/xml"]
|
||||
execute {
|
||||
val resXmlDirectory = get("res/xml")
|
||||
|
||||
// Add android:networkSecurityConfig="@xml/network_security_config" and the "networkSecurityConfig" attribute if it does not exist.
|
||||
context.document["AndroidManifest.xml"].use { document ->
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
val applicationNode = document.getElementsByTagName("application").item(0) as Element
|
||||
|
||||
if (!applicationNode.hasAttribute("networkSecurityConfig")) {
|
||||
|
@ -41,8 +41,8 @@ val changePackageNamePatch = resourcePatch(
|
||||
it == "Default" || it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$"))
|
||||
}
|
||||
|
||||
finalize { context ->
|
||||
context.document["AndroidManifest.xml"].use { document ->
|
||||
finalize {
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
|
||||
val replacementPackageName = packageNameOption.value
|
||||
|
||||
|
@ -275,7 +275,7 @@ val addResourcesPatch = resourcePatch(
|
||||
After all patches that depend on addResourcesPatch have been executed,
|
||||
addResourcesPatch#finalize is finally called to add all staged resources to the app.
|
||||
*/
|
||||
execute { context ->
|
||||
execute {
|
||||
stagedResources = buildMap {
|
||||
/**
|
||||
* Puts resources under `/resources/addresources/<value>/<resourceKind>.xml` into the map.
|
||||
@ -299,7 +299,7 @@ val addResourcesPatch = resourcePatch(
|
||||
// instead of overwriting it.
|
||||
// This covers the example case such as adding strings and arrays of the same value.
|
||||
getOrPut(destValue, ::mutableMapOf).apply {
|
||||
context.document[stream].use { document ->
|
||||
document(stream).use { document ->
|
||||
document.getElementsByTagName("app").asSequence().forEach { app ->
|
||||
val appId = app.attributes.getNamedItem("id").textContent
|
||||
|
||||
@ -343,7 +343,7 @@ val addResourcesPatch = resourcePatch(
|
||||
* Adds all resources staged in [addResourcesPatch] to the app.
|
||||
* This is called after all patches that depend on [addResourcesPatch] have been executed.
|
||||
*/
|
||||
finalize { context ->
|
||||
finalize {
|
||||
operator fun MutableMap<String, Pair<Document, Node>>.invoke(
|
||||
value: Value,
|
||||
resource: BaseResource,
|
||||
@ -359,8 +359,7 @@ val addResourcesPatch = resourcePatch(
|
||||
}
|
||||
|
||||
getOrPut(resourceFileName) {
|
||||
val targetFile =
|
||||
context["res/$value/$resourceFileName.xml"].also {
|
||||
val targetFile = this@finalize["res/$value/$resourceFileName.xml"].also {
|
||||
it.parentFile?.mkdirs()
|
||||
|
||||
if (it.createNewFile()) {
|
||||
@ -368,7 +367,7 @@ val addResourcesPatch = resourcePatch(
|
||||
}
|
||||
}
|
||||
|
||||
context.document[targetFile.path].let { document ->
|
||||
document(targetFile.path).let { document ->
|
||||
|
||||
// Save the target node here as well
|
||||
// in order to avoid having to call document.getNode("resources")
|
||||
|
@ -10,8 +10,8 @@ import org.w3c.dom.Element
|
||||
private val removeCaptureRestrictionResourcePatch = resourcePatch(
|
||||
description = "Sets allowAudioPlaybackCapture in manifest to true.",
|
||||
) {
|
||||
execute { context ->
|
||||
context.document["AndroidManifest.xml"].use { document ->
|
||||
execute {
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
// Get the application node.
|
||||
val applicationNode =
|
||||
document
|
||||
|
@ -13,9 +13,9 @@ val removeShareTargetsPatch = resourcePatch(
|
||||
description = "Removes share targets like directly sharing to a frequent contact.",
|
||||
use = false,
|
||||
) {
|
||||
execute { context ->
|
||||
execute {
|
||||
try {
|
||||
context.document["res/xml/shortcuts.xml"]
|
||||
document("res/xml/shortcuts.xml")
|
||||
} catch (_: FileNotFoundException) {
|
||||
return@execute Logger.getLogger(this::class.java.name).warning("The app has no shortcuts")
|
||||
}.use { document ->
|
||||
|
@ -12,16 +12,15 @@ fun <T> transformInstructionsPatch(
|
||||
transform: (MutableMethod, T) -> Unit,
|
||||
) = bytecodePatch {
|
||||
// Returns the patch indices as a Sequence, which will execute lazily.
|
||||
fun findPatchIndices(classDef: ClassDef, method: Method): Sequence<T>? {
|
||||
return method.implementation?.instructions?.asSequence()?.withIndex()?.mapNotNull { (index, instruction) ->
|
||||
fun findPatchIndices(classDef: ClassDef, method: Method): Sequence<T>? =
|
||||
method.implementation?.instructions?.asSequence()?.withIndex()?.mapNotNull { (index, instruction) ->
|
||||
filterMap(classDef, method, instruction, index)
|
||||
}
|
||||
}
|
||||
|
||||
execute { context ->
|
||||
execute {
|
||||
// Find all methods to patch
|
||||
buildMap {
|
||||
context.classes.forEach { classDef ->
|
||||
classes.forEach { classDef ->
|
||||
val methods = buildList {
|
||||
classDef.methods.forEach { method ->
|
||||
// Since the Sequence executes lazily,
|
||||
@ -37,7 +36,7 @@ fun <T> transformInstructionsPatch(
|
||||
}
|
||||
}.forEach { (classDef, methods) ->
|
||||
// And finally transform the methods...
|
||||
val mutableClass = context.proxy(classDef).mutableClass
|
||||
val mutableClass = proxy(classDef).mutableClass
|
||||
|
||||
methods.map(mutableClass::findMutableMethodOf).forEach methods@{ mutableMethod ->
|
||||
val patchIndices = findPatchIndices(mutableClass, mutableMethod)?.toCollection(ArrayDeque())
|
||||
|
@ -25,8 +25,8 @@ val changeVersionCodePatch = resourcePatch(
|
||||
required = true,
|
||||
) { versionCode -> versionCode!! >= 1 }
|
||||
|
||||
execute { context ->
|
||||
context.document["AndroidManifest.xml"].use { document ->
|
||||
execute {
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
val manifestElement = document.getNode("manifest") as Element
|
||||
manifestElement.setAttribute("android:versionCode", "$versionCode")
|
||||
}
|
||||
|
@ -10,10 +10,8 @@ val deepLinkingPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.amazon.mShop.android.shopping")
|
||||
|
||||
val deepLinkingMatch by deepLinkingFingerprint()
|
||||
|
||||
execute {
|
||||
deepLinkingMatch.mutableMethod.addInstructions(
|
||||
deepLinkingFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -11,15 +11,13 @@ val proUnlockPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.backdrops.wallpapers")
|
||||
|
||||
val proUnlockMatch by proUnlockFingerprint()
|
||||
|
||||
execute {
|
||||
val registerIndex = proUnlockMatch.patternMatch!!.endIndex - 1
|
||||
val registerIndex = proUnlockFingerprint.patternMatch!!.endIndex - 1
|
||||
|
||||
proUnlockMatch.mutableMethod.apply {
|
||||
proUnlockFingerprint.method.apply {
|
||||
val register = getInstruction<OneRegisterInstruction>(registerIndex).registerA
|
||||
addInstruction(
|
||||
proUnlockMatch.patternMatch!!.endIndex,
|
||||
proUnlockFingerprint.patternMatch!!.endIndex,
|
||||
"const/4 v$register, 0x1",
|
||||
)
|
||||
}
|
||||
|
@ -10,9 +10,7 @@ val removePlayLimitsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.bandcamp.android")
|
||||
|
||||
val handlePlaybackLimitsMatch by handlePlaybackLimitsFingerprint()
|
||||
|
||||
execute {
|
||||
handlePlaybackLimitsMatch.mutableMethod.addInstructions(0, "return-void")
|
||||
handlePlaybackLimitsFingerprint.method.addInstructions(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,7 @@ val bypassRootChecksPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("it.ipzs.cieid")
|
||||
|
||||
val checkRootMatch by checkRootFingerprint()
|
||||
|
||||
execute {
|
||||
checkRootMatch.mutableMethod.addInstruction(1, "return-void")
|
||||
checkRootFingerprint.method.addInstruction(1, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,6 @@ val disableAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.duolingo")
|
||||
|
||||
val initializeMonetizationDebugSettingsMatch by initializeMonetizationDebugSettingsFingerprint()
|
||||
|
||||
execute {
|
||||
// Couple approaches to remove ads exist:
|
||||
//
|
||||
@ -21,8 +19,8 @@ val disableAdsPatch = bytecodePatch(
|
||||
// SharedPreferences has a debug boolean value with key "disable_ads", which maps to "DebugCategory.DISABLE_ADS".
|
||||
//
|
||||
// MonetizationDebugSettings seems to be the most general setting to work fine.
|
||||
initializeMonetizationDebugSettingsMatch.mutableMethod.apply {
|
||||
val insertIndex = initializeMonetizationDebugSettingsMatch.patternMatch!!.startIndex
|
||||
initializeMonetizationDebugSettingsFingerprint.method.apply {
|
||||
val insertIndex = initializeMonetizationDebugSettingsFingerprint.patternMatch!!.startIndex
|
||||
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -12,11 +12,9 @@ val enableDebugMenuPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.duolingo"("5.158.4"))
|
||||
|
||||
val initializeBuildConfigProviderMatch by initializeBuildConfigProviderFingerprint()
|
||||
|
||||
execute {
|
||||
initializeBuildConfigProviderMatch.mutableMethod.apply {
|
||||
val insertIndex = initializeBuildConfigProviderMatch.patternMatch!!.startIndex
|
||||
initializeBuildConfigProviderFingerprint.method.apply {
|
||||
val insertIndex = initializeBuildConfigProviderFingerprint.patternMatch!!.startIndex
|
||||
val register = getInstruction<TwoRegisterInstruction>(insertIndex).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -19,13 +19,9 @@ val hideSponsoredStoriesPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.facebook.katana")
|
||||
|
||||
val getStoryVisibilityMatch by getStoryVisibilityFingerprint()
|
||||
val getSponsoredDataModelTemplateMatch by getSponsoredDataModelTemplateFingerprint()
|
||||
val baseModelMapperMatch by baseModelMapperFingerprint()
|
||||
|
||||
execute {
|
||||
val sponsoredDataModelTemplateMethod = getSponsoredDataModelTemplateMatch.method
|
||||
val baseModelMapperMethod = baseModelMapperMatch.method
|
||||
val sponsoredDataModelTemplateMethod = getSponsoredDataModelTemplateFingerprint.originalMethod
|
||||
val baseModelMapperMethod = baseModelMapperFingerprint.originalMethod
|
||||
val baseModelWithTreeType = baseModelMapperMethod.returnType
|
||||
|
||||
val graphQlStoryClassDescriptor = "Lcom/facebook/graphql/model/GraphQLStory;"
|
||||
@ -33,8 +29,9 @@ val hideSponsoredStoriesPatch = bytecodePatch(
|
||||
// The "SponsoredDataModelTemplate" methods has the ids in its body to extract sponsored data
|
||||
// from GraphQL models, but targets the wrong derived type of "BaseModelWithTree". Since those ids
|
||||
// could change in future version, we need to extract them and call the base implementation directly.
|
||||
|
||||
val getSponsoredDataHelperMethod = ImmutableMethod(
|
||||
getStoryVisibilityMatch.classDef.type,
|
||||
getStoryVisibilityFingerprint.originalClassDef.type,
|
||||
"getSponsoredData",
|
||||
listOf(ImmutableMethodParameter(graphQlStoryClassDescriptor, null, null)),
|
||||
baseModelWithTreeType,
|
||||
@ -68,12 +65,12 @@ val hideSponsoredStoriesPatch = bytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
getStoryVisibilityMatch.mutableClass.methods.add(getSponsoredDataHelperMethod)
|
||||
getStoryVisibilityFingerprint.classDef.methods.add(getSponsoredDataHelperMethod)
|
||||
|
||||
// Check if the parameter type is GraphQLStory and if sponsoredDataModelGetter returns a non-null value.
|
||||
// If so, hide the story by setting the visibility to StoryVisibility.GONE.
|
||||
getStoryVisibilityMatch.mutableMethod.addInstructionsWithLabels(
|
||||
getStoryVisibilityMatch.patternMatch!!.startIndex,
|
||||
getStoryVisibilityFingerprint.method.addInstructionsWithLabels(
|
||||
getStoryVisibilityFingerprint.patternMatch!!.startIndex,
|
||||
"""
|
||||
instance-of v0, p0, $graphQlStoryClassDescriptor
|
||||
if-eqz v0, :resume_normal
|
||||
|
@ -10,12 +10,12 @@ val hideStoryAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.facebook.katana")
|
||||
|
||||
val fetchMoreAdsMatch by fetchMoreAdsFingerprint()
|
||||
val adsInsertionMatch by adsInsertionFingerprint()
|
||||
|
||||
execute {
|
||||
setOf(fetchMoreAdsMatch, adsInsertionMatch).forEach { match ->
|
||||
match.mutableMethod.replaceInstruction(0, "return-void")
|
||||
setOf(
|
||||
fetchMoreAdsFingerprint,
|
||||
adsInsertionFingerprint,
|
||||
).forEach { fingerprint ->
|
||||
fingerprint.method.replaceInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,12 +10,9 @@ val bootloaderDetectionPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("at.gv.bmf.bmf2go")
|
||||
|
||||
val createKeyMatch by createKeyFingerprint()
|
||||
val bootStateMatch by bootStateFingerprint()
|
||||
|
||||
execute {
|
||||
setOf(createKeyMatch, bootStateMatch).forEach { match ->
|
||||
match.mutableMethod.addInstructions(
|
||||
setOf(createKeyFingerprint, bootStateFingerprint).forEach { fingerprint ->
|
||||
fingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -10,10 +10,8 @@ val rootDetectionPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("at.gv.bmf.bmf2go")
|
||||
|
||||
val rootDetectionMatch by rootDetectionFingerprint()
|
||||
|
||||
execute {
|
||||
rootDetectionMatch.mutableMethod.addInstructions(
|
||||
rootDetectionFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
sget-object v0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
|
||||
|
@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
|
||||
|
||||
@Suppress("unused")
|
||||
val enableCustomTabsPatch = bytecodePatch(
|
||||
@ -12,11 +13,9 @@ val enableCustomTabsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.magazines")
|
||||
|
||||
val launchCustomTabMatch by launchCustomTabFingerprint()
|
||||
|
||||
execute {
|
||||
launchCustomTabMatch.mutableMethod.apply {
|
||||
val checkIndex = launchCustomTabMatch.patternMatch!!.endIndex + 1
|
||||
launchCustomTabFingerprint.method.apply {
|
||||
val checkIndex = launchCustomTabFingerprint.patternMatch!!.endIndex + 1
|
||||
val register = getInstruction<OneRegisterInstruction>(checkIndex).registerA
|
||||
|
||||
replaceInstruction(checkIndex, "const/4 v$register, 0x1")
|
||||
|
@ -54,8 +54,6 @@ val spoofFeaturesPatch = bytecodePatch(
|
||||
required = true,
|
||||
)
|
||||
|
||||
val initializeFeaturesEnumMatch by initializeFeaturesEnumFingerprint()
|
||||
|
||||
execute {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val featuresToEnable = featuresToEnable!!.toSet()
|
||||
@ -63,7 +61,7 @@ val spoofFeaturesPatch = bytecodePatch(
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val featuresToDisable = featuresToDisable!!.toSet()
|
||||
|
||||
initializeFeaturesEnumMatch.mutableMethod.apply {
|
||||
initializeFeaturesEnumFingerprint.method.apply {
|
||||
instructions.filter { it.opcode == Opcode.CONST_STRING }.forEach {
|
||||
val feature = it.getReference<StringReference>()!!.string
|
||||
|
||||
|
@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
|
||||
|
||||
@Suppress("unused")
|
||||
val restoreHiddenBackUpWhileChargingTogglePatch = bytecodePatch(
|
||||
@ -12,12 +13,10 @@ val restoreHiddenBackUpWhileChargingTogglePatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.photos")
|
||||
|
||||
val backupPreferencesMatch by backupPreferencesFingerprint()
|
||||
|
||||
execute {
|
||||
// Patches 'backup_prefs_had_backup_only_when_charging_enabled' to always be true.
|
||||
val chargingPrefStringIndex = backupPreferencesMatch.stringMatches!!.first().index
|
||||
backupPreferencesMatch.mutableMethod.apply {
|
||||
val chargingPrefStringIndex = backupPreferencesFingerprint.stringMatches!!.first().index
|
||||
backupPreferencesFingerprint.method.apply {
|
||||
// Get the register of move-result.
|
||||
val resultRegister = getInstruction<OneRegisterInstruction>(chargingPrefStringIndex + 2).registerA
|
||||
// Insert const after move-result to override register as true.
|
||||
|
@ -5,6 +5,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
|
||||
|
||||
@Suppress("unused")
|
||||
val removeDeviceRestrictionsPatch = bytecodePatch(
|
||||
@ -13,12 +14,10 @@ val removeDeviceRestrictionsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.recorder")
|
||||
|
||||
val onApplicationCreateMatch by onApplicationCreateFingerprint()
|
||||
|
||||
execute {
|
||||
val featureStringIndex = onApplicationCreateMatch.stringMatches!!.first().index
|
||||
val featureStringIndex = onApplicationCreateFingerprint.stringMatches!!.first().index
|
||||
|
||||
onApplicationCreateMatch.mutableMethod.apply {
|
||||
onApplicationCreateFingerprint.method.apply {
|
||||
// Remove check for device restrictions.
|
||||
removeInstructions(featureStringIndex - 2, 5)
|
||||
|
||||
|
@ -9,10 +9,8 @@ val disableAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.myprog.hexedit")
|
||||
|
||||
val primaryAdsMatch by primaryAdsFingerprint()
|
||||
|
||||
execute {
|
||||
primaryAdsMatch.mutableMethod.replaceInstructions(
|
||||
primaryAdsFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -9,10 +9,8 @@ val unlockProPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("ginlemon.iconpackstudio"("2.2 build 016"))
|
||||
|
||||
val checkProMatch by checkProFingerprint()
|
||||
|
||||
execute {
|
||||
checkProMatch.mutableMethod.addInstructions(
|
||||
checkProFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -10,11 +10,11 @@ val rootDetectionPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("at.gv.oe.app")
|
||||
|
||||
attestationSupportedCheckFingerprint()
|
||||
bootloaderCheckFingerprint()
|
||||
rootCheckFingerprint()
|
||||
|
||||
execute {
|
||||
setOf(attestationSupportedCheckFingerprint, bootloaderCheckFingerprint, rootCheckFingerprint).returnEarly(true)
|
||||
setOf(
|
||||
attestationSupportedCheckFingerprint,
|
||||
bootloaderCheckFingerprint,
|
||||
rootCheckFingerprint,
|
||||
).forEach { it.method.returnEarly(true) }
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ val spoofSignaturePatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("at.gv.oe.app")
|
||||
|
||||
val spoofSignatureMatch by spoofSignatureFingerprint()
|
||||
|
||||
execute {
|
||||
val expectedSignature =
|
||||
"OpenSSLRSAPublicKey{modulus=ac3e6fd6050aa7e0d6010ae58190404cd89a56935b44f6fee" +
|
||||
@ -26,7 +24,7 @@ val spoofSignaturePatch = bytecodePatch(
|
||||
"77ef1be61b2c01ebdabddcbf53cc4b6fd9a3c445606ee77b3758162c80ad8f8137b3c6864e92db904807dcb2be9d7717dd21" +
|
||||
"bf42c121d620ddfb7914f7a95c713d9e1c1b7bdb4a03d618e40cf7e9e235c0b5687e03b7ab3,publicExponent=10001}"
|
||||
|
||||
spoofSignatureMatch.mutableMethod.addInstructions(
|
||||
spoofSignatureFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$expectedSignature"
|
||||
|
@ -9,10 +9,8 @@ val hideAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.nis.app")
|
||||
|
||||
val inshortsAdsMatch by inshortsAdsFingerprint()
|
||||
|
||||
execute {
|
||||
inshortsAdsMatch.mutableMethod.addInstruction(
|
||||
inshortsAdsFingerprint.method.addInstruction(
|
||||
0,
|
||||
"""
|
||||
return-void
|
||||
|
@ -11,10 +11,8 @@ val hideAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.instagram.android")
|
||||
|
||||
val adInjectorMatch by adInjectorFingerprint()
|
||||
|
||||
execute {
|
||||
adInjectorMatch.mutableMethod.addInstructions(
|
||||
adInjectorFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
|
@ -9,11 +9,9 @@ val removeAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("net.binarymode.android.irplus")
|
||||
|
||||
val irplusAdsMatch by irplusAdsFingerprint()
|
||||
|
||||
execute {
|
||||
// By overwriting the second parameter of the method,
|
||||
// the view which holds the advertisement is removed.
|
||||
irplusAdsMatch.mutableMethod.addInstruction(0, "const/4 p2, 0x0")
|
||||
irplusAdsFingerprint.method.addInstruction(0, "const/4 p2, 0x0")
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,8 @@ val disableMandatoryLoginPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.adobe.lrmobile")
|
||||
|
||||
val isLoggedInMatch by isLoggedInFingerprint()
|
||||
|
||||
execute {
|
||||
isLoggedInMatch.mutableMethod.apply {
|
||||
isLoggedInFingerprint.method.apply {
|
||||
val index = implementation!!.instructions.lastIndex - 1
|
||||
// Set isLoggedIn = true.
|
||||
replaceInstruction(index, "const/4 v0, 0x1")
|
||||
|
@ -9,10 +9,8 @@ val unlockPremiumPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.adobe.lrmobile")
|
||||
|
||||
val hasPurchasedMatch by hasPurchasedFingerprint()
|
||||
|
||||
execute {
|
||||
// Set hasPremium = true.
|
||||
hasPurchasedMatch.mutableMethod.replaceInstruction(2, "const/4 v2, 0x1")
|
||||
hasPurchasedFingerprint.method.replaceInstruction(2, "const/4 v2, 0x1")
|
||||
}
|
||||
}
|
||||
|
@ -6,10 +6,9 @@ import app.revanced.patcher.patch.bytecodePatch
|
||||
val licenseValidationPatch = bytecodePatch(
|
||||
description = "Disables Firebase license validation.",
|
||||
) {
|
||||
val licenseValidationMatch by licenseValidationFingerprint()
|
||||
|
||||
execute {
|
||||
licenseValidationMatch.mutableMethod.replaceInstructions(
|
||||
licenseValidationFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 p0, 0x1
|
||||
|
@ -6,10 +6,9 @@ import app.revanced.patcher.patch.bytecodePatch
|
||||
val signatureVerificationPatch = bytecodePatch(
|
||||
description = "Disables detection of incorrect signature.",
|
||||
) {
|
||||
val verifySignatureMatch by verifySignatureFingerprint()
|
||||
|
||||
execute {
|
||||
verifySignatureMatch.mutableMethod.replaceInstructions(
|
||||
verifySignatureFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 p0, 0x1
|
||||
|
@ -13,10 +13,8 @@ val unlockProVersionPatch = bytecodePatch(
|
||||
|
||||
compatibleWith("com.zombodroid.MemeGenerator"("4.6364", "4.6370", "4.6375", "4.6377"))
|
||||
|
||||
val isFreeVersionMatch by isFreeVersionFingerprint()
|
||||
|
||||
execute {
|
||||
isFreeVersionMatch.mutableMethod.replaceInstructions(
|
||||
isFreeVersionFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
sget-object p0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
|
||||
|
@ -10,9 +10,7 @@ val hideInboxAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.facebook.orca")
|
||||
|
||||
val loadInboxAdsMatch by loadInboxAdsFingerprint()
|
||||
|
||||
execute {
|
||||
loadInboxAdsMatch.mutableMethod.replaceInstruction(0, "return-void")
|
||||
loadInboxAdsFingerprint.method.replaceInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,7 @@ val hideInboxSubtabsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.facebook.orca")
|
||||
|
||||
val createInboxSubTabsMatch by createInboxSubTabsFingerprint()
|
||||
|
||||
execute {
|
||||
createInboxSubTabsMatch.mutableMethod.replaceInstruction(2, "const/4 v0, 0x0")
|
||||
createInboxSubTabsFingerprint.method.replaceInstruction(2, "const/4 v0, 0x0")
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.sun.org.apache.bcel.internal.generic.InstructionConst.getInstruction
|
||||
|
||||
@Suppress("unused")
|
||||
val disableSwitchingEmojiToStickerPatch = bytecodePatch(
|
||||
@ -12,12 +13,9 @@ val disableSwitchingEmojiToStickerPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.facebook.orca"("439.0.0.29.119"))
|
||||
|
||||
val switchMessangeInputEmojiButtonMatch by switchMessangeInputEmojiButtonFingerprint()
|
||||
|
||||
execute {
|
||||
val setStringIndex = switchMessangeInputEmojiButtonMatch.patternMatch!!.startIndex + 2
|
||||
|
||||
switchMessangeInputEmojiButtonMatch.mutableMethod.apply {
|
||||
switchMessengeInputEmojiButtonFingerprint.method.apply {
|
||||
val setStringIndex = switchMessengeInputEmojiButtonFingerprint.patternMatch!!.startIndex + 2
|
||||
val targetRegister = getInstruction<OneRegisterInstruction>(setStringIndex).registerA
|
||||
|
||||
replaceInstruction(setStringIndex, "const-string v$targetRegister, \"expression\"")
|
||||
|
@ -10,9 +10,7 @@ val disableTypingIndicatorPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.facebook.orca")
|
||||
|
||||
val sendTypingIndicatorMatch by sendTypingIndicatorFingerprint()
|
||||
|
||||
execute {
|
||||
sendTypingIndicatorMatch.mutableMethod.replaceInstruction(0, "return-void")
|
||||
sendTypingIndicatorFingerprint.method.replaceInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ internal val sendTypingIndicatorFingerprint = fingerprint {
|
||||
}
|
||||
}
|
||||
|
||||
internal val switchMessangeInputEmojiButtonFingerprint = fingerprint {
|
||||
internal val switchMessengeInputEmojiButtonFingerprint = fingerprint {
|
||||
returns("V")
|
||||
parameters("L", "Z")
|
||||
opcodes(
|
||||
|
@ -15,14 +15,10 @@ val forceEnglishLocalePatch = bytecodePatch(
|
||||
|
||||
dependsOn(fixLoginPatch)
|
||||
|
||||
val syncBluetoothLanguageMatch by syncBluetoothLanguageFingerprint()
|
||||
|
||||
execute {
|
||||
val resolvePhoneLocaleInstruction = syncBluetoothLanguageMatch.patternMatch!!.startIndex
|
||||
|
||||
syncBluetoothLanguageMatch.mutableMethod.apply {
|
||||
val registerIndexToUpdate =
|
||||
getInstruction<OneRegisterInstruction>(resolvePhoneLocaleInstruction).registerA
|
||||
syncBluetoothLanguageFingerprint.method.apply {
|
||||
val resolvePhoneLocaleInstruction = syncBluetoothLanguageFingerprint.patternMatch!!.startIndex
|
||||
val registerIndexToUpdate = getInstruction<OneRegisterInstruction>(resolvePhoneLocaleInstruction).registerA
|
||||
|
||||
replaceInstruction(
|
||||
resolvePhoneLocaleInstruction,
|
||||
|
@ -9,9 +9,7 @@ val fixLoginPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.xiaomi.wearable")
|
||||
|
||||
val xiaomiAccountManagerConstructorMatch by xiaomiAccountManagerConstructorFingerprint()
|
||||
|
||||
execute {
|
||||
xiaomiAccountManagerConstructorMatch.mutableMethod.addInstruction(0, "const/16 p2, 0x0")
|
||||
xiaomiAccountManagerConstructorFingerprint.method.addInstruction(0, "const/16 p2, 0x0")
|
||||
}
|
||||
}
|
||||
|
@ -10,13 +10,10 @@ val hideVideoAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
|
||||
val showVideoAdsParentMatch by showVideoAdsParentFingerprint()
|
||||
|
||||
execute { context ->
|
||||
val showVideoAdsMethod = context
|
||||
.navigate(showVideoAdsParentMatch.mutableMethod)
|
||||
.at(showVideoAdsParentMatch.patternMatch!!.startIndex + 1).mutable()
|
||||
|
||||
showVideoAdsMethod.addInstruction(0, "const/4 p1, 0x0")
|
||||
execute {
|
||||
navigate(showVideoAdsParentFingerprint.originalMethod)
|
||||
.to(showVideoAdsParentFingerprint.patternMatch!!.startIndex + 1)
|
||||
.stop()
|
||||
.addInstruction(0, "const/4 p1, 0x0")
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,8 @@ val enableExclusiveAudioPlaybackPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
|
||||
val allowExclusiveAudioPlaybackMatch by allowExclusiveAudioPlaybackFingerprint()
|
||||
|
||||
execute {
|
||||
allowExclusiveAudioPlaybackMatch.mutableMethod.apply {
|
||||
allowExclusiveAudioPlaybackFingerprint.method.apply {
|
||||
addInstructions(
|
||||
0,
|
||||
"""
|
||||
|
@ -13,13 +13,12 @@ val permanentRepeatPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
|
||||
val repeatTrackMatch by repeatTrackFingerprint()
|
||||
|
||||
execute {
|
||||
val startIndex = repeatTrackMatch.patternMatch!!.endIndex
|
||||
|
||||
val startIndex = repeatTrackFingerprint.patternMatch!!.endIndex
|
||||
val repeatIndex = startIndex + 1
|
||||
|
||||
repeatTrackMatch.mutableMethod.apply {
|
||||
repeatTrackFingerprint.method.apply {
|
||||
addInstructionsWithLabels(
|
||||
startIndex,
|
||||
"goto :repeat",
|
||||
|
@ -20,9 +20,7 @@ val permanentShufflePatch = bytecodePatch(
|
||||
),
|
||||
)
|
||||
|
||||
val disableShuffleMatch by disableShuffleFingerprint()
|
||||
|
||||
execute {
|
||||
disableShuffleMatch.mutableMethod.addInstruction(0, "return-void")
|
||||
disableShuffleFingerprint.method.addInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,9 @@ val hideCategoryBar = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
|
||||
val constructCategoryBarMatch by constructCategoryBarFingerprint()
|
||||
|
||||
execute {
|
||||
constructCategoryBarMatch.mutableMethod.apply {
|
||||
val insertIndex = constructCategoryBarMatch.patternMatch!!.startIndex
|
||||
constructCategoryBarFingerprint.method.apply {
|
||||
val insertIndex = constructCategoryBarFingerprint.patternMatch!!.startIndex
|
||||
val register = getInstruction<OneRegisterInstruction>(insertIndex - 1).registerA
|
||||
|
||||
addInstructions(
|
||||
|
@ -14,12 +14,9 @@ val hideGetPremiumPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
|
||||
val hideGetPremiumMatch by hideGetPremiumFingerprint()
|
||||
val membershipSettingsMatch by membershipSettingsFingerprint()
|
||||
|
||||
execute {
|
||||
hideGetPremiumMatch.mutableMethod.apply {
|
||||
val insertIndex = hideGetPremiumMatch.patternMatch!!.endIndex
|
||||
hideGetPremiumFingerprint.method.apply {
|
||||
val insertIndex = hideGetPremiumFingerprint.patternMatch!!.endIndex
|
||||
|
||||
val setVisibilityInstruction = getInstruction<FiveRegisterInstruction>(insertIndex)
|
||||
val getPremiumViewRegister = setVisibilityInstruction.registerC
|
||||
@ -37,7 +34,7 @@ val hideGetPremiumPatch = bytecodePatch(
|
||||
)
|
||||
}
|
||||
|
||||
membershipSettingsMatch.mutableMethod.addInstructions(
|
||||
membershipSettingsFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
|
@ -20,12 +20,10 @@ val removeUpgradeButtonPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
|
||||
val pivotBarConstructorMatch by pivotBarConstructorFingerprint()
|
||||
|
||||
execute {
|
||||
pivotBarConstructorMatch.mutableMethod.apply {
|
||||
pivotBarConstructorFingerprint.method.apply {
|
||||
val pivotBarElementFieldReference =
|
||||
getInstruction(pivotBarConstructorMatch.patternMatch!!.endIndex - 1)
|
||||
getInstruction(pivotBarConstructorFingerprint.patternMatch!!.endIndex - 1)
|
||||
.getReference<FieldReference>()
|
||||
|
||||
val register = getInstruction<FiveRegisterInstruction>(0).registerC
|
||||
@ -39,7 +37,7 @@ val removeUpgradeButtonPatch = bytecodePatch(
|
||||
iput-object v0, v$register, $pivotBarElementFieldReference
|
||||
""".toInstructions().toMutableList()
|
||||
|
||||
val endIndex = pivotBarConstructorMatch.patternMatch!!.endIndex
|
||||
val endIndex = pivotBarConstructorFingerprint.patternMatch!!.endIndex
|
||||
|
||||
// Replace the instruction to retain the label at given index.
|
||||
replaceInstruction(
|
||||
|
@ -10,10 +10,8 @@ val bypassCertificateChecksPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
|
||||
val checkCertificateMatch by checkCertificateFingerprint()
|
||||
|
||||
execute {
|
||||
checkCertificateMatch.mutableMethod.addInstructions(
|
||||
checkCertificateFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -11,16 +11,13 @@ val backgroundPlaybackPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.google.android.apps.youtube.music")
|
||||
|
||||
val kidsBackgroundPlaybackPolicyControllerMatch by kidsBackgroundPlaybackPolicyControllerFingerprint()
|
||||
val backgroundPlaybackDisableMatch by backgroundPlaybackDisableFingerprint()
|
||||
|
||||
execute {
|
||||
kidsBackgroundPlaybackPolicyControllerMatch.mutableMethod.addInstruction(
|
||||
kidsBackgroundPlaybackPolicyControllerFingerprint.method.addInstruction(
|
||||
0,
|
||||
"return-void",
|
||||
)
|
||||
|
||||
backgroundPlaybackDisableMatch.mutableMethod.addInstructions(
|
||||
backgroundPlaybackDisableFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -9,10 +9,8 @@ val unlockProPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("org.totschnig.myexpenses")
|
||||
|
||||
val isEnabledMatch by isEnabledFingerprint()
|
||||
|
||||
execute {
|
||||
isEnabledMatch.mutableMethod.addInstructions(
|
||||
isEnabledFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -10,12 +10,9 @@ val hideAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.myfitnesspal.android"("24.14.2"))
|
||||
|
||||
val isPremiumUseCaseImplMatch by isPremiumUseCaseImplFingerprint()
|
||||
val mainActivityNavigateToNativePremiumUpsellMatch by mainActivityNavigateToNativePremiumUpsellFingerprint()
|
||||
|
||||
execute {
|
||||
// Overwrite the premium status specifically for ads.
|
||||
isPremiumUseCaseImplMatch.mutableMethod.replaceInstructions(
|
||||
isPremiumUseCaseImplFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
sget-object v0, Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;
|
||||
@ -25,7 +22,7 @@ val hideAdsPatch = bytecodePatch(
|
||||
|
||||
// Prevent the premium upsell dialog from showing when the main activity is launched.
|
||||
// In other places that are premium-only the dialog will still show.
|
||||
mainActivityNavigateToNativePremiumUpsellMatch.mutableMethod.replaceInstructions(
|
||||
mainActivityNavigateToNativePremiumUpsellFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"return-void",
|
||||
)
|
||||
|
@ -10,8 +10,8 @@ val removeBroadcastsRestrictionPatch = resourcePatch(
|
||||
) {
|
||||
compatibleWith("eu.faircode.netguard")
|
||||
|
||||
execute { context ->
|
||||
context.document["AndroidManifest.xml"].use { document ->
|
||||
execute {
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
val applicationNode =
|
||||
document
|
||||
.getElementsByTagName("application")
|
||||
|
@ -9,10 +9,8 @@ val unlockProPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.wakdev.apps.nfctools.se")
|
||||
|
||||
val isLicenseRegisteredMatch by isLicenseRegisteredFingerprint()
|
||||
|
||||
execute {
|
||||
isLicenseRegisteredMatch.mutableMethod.addInstructions(
|
||||
isLicenseRegisteredFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -9,10 +9,8 @@ val unlockProPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.awedea.nyx")
|
||||
|
||||
val checkProMatch by checkProFingerprint()
|
||||
|
||||
execute {
|
||||
checkProMatch.mutableMethod.addInstructions(
|
||||
checkProFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -17,10 +17,8 @@ val fixCrashPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("de.simon.openinghours"("1.0"))
|
||||
|
||||
val setPlaceMatch by setPlaceFingerprint()
|
||||
|
||||
execute {
|
||||
val indexedInstructions = setPlaceMatch.mutableMethod.instructions.withIndex().toList()
|
||||
val indexedInstructions = setPlaceFingerprint.method.instructions.withIndex().toList()
|
||||
|
||||
/**
|
||||
* This function replaces all `checkNotNull` instructions in the integer interval
|
||||
@ -29,7 +27,7 @@ val fixCrashPatch = bytecodePatch(
|
||||
* the value is indeed null, we jump to a newly created label at `endIndex + 1`.
|
||||
*/
|
||||
fun avoidNullPointerException(startIndex: Int, endIndex: Int) {
|
||||
val continueLabel = setPlaceMatch.mutableMethod.newLabel(endIndex + 1)
|
||||
val continueLabel = setPlaceFingerprint.method.newLabel(endIndex + 1)
|
||||
|
||||
for (index in startIndex..endIndex) {
|
||||
val instruction = indexedInstructions[index].value
|
||||
@ -41,7 +39,7 @@ val fixCrashPatch = bytecodePatch(
|
||||
val checkNotNullInstruction = instruction as FiveRegisterInstruction
|
||||
val originalRegister = checkNotNullInstruction.registerC
|
||||
|
||||
setPlaceMatch.mutableMethod.replaceInstruction(
|
||||
setPlaceFingerprint.method.replaceInstruction(
|
||||
index,
|
||||
BuilderInstruction21t(
|
||||
Opcode.IF_EQZ,
|
||||
|
@ -14,10 +14,8 @@ val getDeviceIdPatch = bytecodePatch(
|
||||
|
||||
compatibleWith("com.microblink.photomath"("8.37.0"))
|
||||
|
||||
val getDeviceIdMatch by getDeviceIdFingerprint()
|
||||
|
||||
execute {
|
||||
getDeviceIdMatch.mutableMethod.replaceInstructions(
|
||||
getDeviceIdFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "${Random.nextLong().toString(16)}"
|
||||
|
@ -8,17 +8,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
val signatureDetectionPatch = bytecodePatch(
|
||||
description = "Disables detection of incorrect signature.",
|
||||
) {
|
||||
val checkSignatureMatch by checkSignatureFingerprint()
|
||||
|
||||
execute {
|
||||
val signatureCheckInstruction = checkSignatureMatch.mutableMethod.getInstruction(
|
||||
checkSignatureMatch.patternMatch!!.endIndex,
|
||||
)
|
||||
val checkRegister = (signatureCheckInstruction as OneRegisterInstruction).registerA
|
||||
|
||||
checkSignatureMatch.mutableMethod.replaceInstruction(
|
||||
signatureCheckInstruction.location.index,
|
||||
"const/4 v$checkRegister, 0x1",
|
||||
)
|
||||
val replacementIndex = checkSignatureFingerprint.patternMatch!!.endIndex
|
||||
val checkRegister =
|
||||
checkSignatureFingerprint.method.getInstruction<OneRegisterInstruction>(replacementIndex).registerA
|
||||
checkSignatureFingerprint.method.replaceInstruction(replacementIndex, "const/4 v$checkRegister, 0x1")
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,8 @@ val hideUpdatePopupPatch = bytecodePatch(
|
||||
|
||||
compatibleWith("com.microblink.photomath"("8.32.0"))
|
||||
|
||||
val hideUpdatePopupMatch by hideUpdatePopupFingerprint()
|
||||
|
||||
execute {
|
||||
hideUpdatePopupMatch.mutableMethod.addInstructions(
|
||||
hideUpdatePopupFingerprint.method.addInstructions(
|
||||
2, // Insert after the null check.
|
||||
"return-void",
|
||||
)
|
||||
|
@ -6,10 +6,9 @@ import app.revanced.patcher.patch.bytecodePatch
|
||||
val enableBookpointPatch = bytecodePatch(
|
||||
description = "Enables textbook access",
|
||||
) {
|
||||
val isBookpointEnabledMatch by isBookpointEnabledFingerprint()
|
||||
|
||||
execute {
|
||||
isBookpointEnabledMatch.mutableMethod.replaceInstructions(
|
||||
isBookpointEnabledFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -13,10 +13,8 @@ val unlockPlusPatch = bytecodePatch(
|
||||
|
||||
compatibleWith("com.microblink.photomath"("8.37.0"))
|
||||
|
||||
val isPlusUnlockedMatch by isPlusUnlockedFingerprint()
|
||||
|
||||
execute {
|
||||
isPlusUnlockedMatch.mutableMethod.addInstructions(
|
||||
isPlusUnlockedFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -30,8 +30,6 @@ val spoofAndroidDeviceIdPatch = bytecodePatch(
|
||||
),
|
||||
)
|
||||
|
||||
val getAndroidIDMatch by getAndroidIdFingerprint()
|
||||
|
||||
val androidDeviceId by stringOption(
|
||||
key = "android-device-id",
|
||||
default = "0011223344556677",
|
||||
@ -41,7 +39,7 @@ val spoofAndroidDeviceIdPatch = bytecodePatch(
|
||||
) { it!!.matches("[A-Fa-f0-9]{16}".toRegex()) }
|
||||
|
||||
execute {
|
||||
getAndroidIDMatch.mutableMethod.addInstructions(
|
||||
getAndroidIdFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$androidDeviceId"
|
||||
|
@ -33,12 +33,8 @@ val disableTrackingPatch = bytecodePatch(
|
||||
),
|
||||
)
|
||||
|
||||
val facebookSDKMatch by facebookSDKFingerprint()
|
||||
val firebaseInstallMatch by firebaseInstallFingerprint()
|
||||
val appMeasurementMatch by appMeasurementFingerprint()
|
||||
|
||||
execute {
|
||||
facebookSDKMatch.mutableMethod.apply {
|
||||
facebookSDKFingerprint.method.apply {
|
||||
instructions.filter { instruction ->
|
||||
instruction.opcode == Opcode.CONST_STRING
|
||||
}.forEach { instruction ->
|
||||
@ -51,7 +47,7 @@ val disableTrackingPatch = bytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
firebaseInstallMatch.mutableMethod.apply {
|
||||
firebaseInstallFingerprint.method.apply {
|
||||
instructions.filter {
|
||||
it.opcode == Opcode.CONST_STRING
|
||||
}.filter {
|
||||
@ -66,6 +62,6 @@ val disableTrackingPatch = bytecodePatch(
|
||||
}
|
||||
}
|
||||
|
||||
appMeasurementMatch.mutableMethod.addInstruction(0, "return-void")
|
||||
appMeasurementFingerprint.method.addInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,8 @@ val hideAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("jp.pxv.android")
|
||||
|
||||
val shouldShowAdsMatch by shouldShowAdsFingerprint()
|
||||
|
||||
execute {
|
||||
shouldShowAdsMatch.mutableMethod.addInstructions(
|
||||
shouldShowAdsFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x0
|
||||
|
@ -11,9 +11,7 @@ val hidePurchaseReminderPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.rarlab.rar")
|
||||
|
||||
val showReminderMatch by showReminderFingerprint()
|
||||
|
||||
execute {
|
||||
showReminderMatch.mutableMethod.addInstruction(0, "return-void")
|
||||
showReminderFingerprint.method.addInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ import app.revanced.patcher.patch.resourcePatch
|
||||
val hideBannerPatch = resourcePatch(
|
||||
description = "Hides banner ads from comments on subreddits.",
|
||||
) {
|
||||
execute { context ->
|
||||
execute {
|
||||
val resourceFilePath = "res/layout/merge_listheader_link_detail.xml"
|
||||
|
||||
context.document[resourceFilePath].use { document ->
|
||||
document(resourceFilePath).use { document ->
|
||||
document.getElementsByTagName("merge").item(0).childNodes.apply {
|
||||
val attributes = arrayOf("height", "width")
|
||||
|
||||
|
@ -6,10 +6,9 @@ import app.revanced.patcher.patch.bytecodePatch
|
||||
val hideCommentAdsPatch = bytecodePatch(
|
||||
description = "Removes ads in the comments.",
|
||||
) {
|
||||
val hideCommentAdsMatch by hideCommentAdsFingerprint()
|
||||
|
||||
execute {
|
||||
hideCommentAdsMatch.mutableMethod.addInstructions(
|
||||
hideCommentAdsFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
new-instance v0, Ljava/lang/Object;
|
||||
|
@ -25,9 +25,6 @@ val hideAdsPatch = bytecodePatch(
|
||||
// This constraint is necessary due to dependency on hideBannerPatch.
|
||||
compatibleWith("com.reddit.frontpage"("2024.17.0"))
|
||||
|
||||
val adPostMatch by adPostFingerprint()
|
||||
val newAdPostMatch by newAdPostFingerprint()
|
||||
|
||||
execute {
|
||||
// region Filter promoted ads (does not work in popular or latest feed)
|
||||
|
||||
@ -35,7 +32,7 @@ val hideAdsPatch = bytecodePatch(
|
||||
"Lapp/revanced/extension/reddit/patches/FilterPromotedLinksPatch;" +
|
||||
"->filterChildren(Ljava/lang/Iterable;)Ljava/util/List;"
|
||||
|
||||
adPostMatch.mutableMethod.apply {
|
||||
adPostFingerprint.method.apply {
|
||||
val setPostsListChildren = implementation!!.instructions.first { instruction ->
|
||||
if (instruction.opcode != Opcode.IPUT_OBJECT) return@first false
|
||||
|
||||
@ -66,7 +63,8 @@ val hideAdsPatch = bytecodePatch(
|
||||
// The new feeds work by inserting posts into lists.
|
||||
// AdElementConverter is conveniently responsible for inserting all feed ads.
|
||||
// By removing the appending instruction no ad posts gets appended to the feed.
|
||||
val index = newAdPostMatch.method.implementation!!.instructions.indexOfFirst {
|
||||
|
||||
val index = newAdPostFingerprint.originalMethod.implementation!!.instructions.indexOfFirst {
|
||||
if (it.opcode != Opcode.INVOKE_VIRTUAL) return@indexOfFirst false
|
||||
|
||||
val reference = (it as ReferenceInstruction).reference as MethodReference
|
||||
@ -74,7 +72,7 @@ val hideAdsPatch = bytecodePatch(
|
||||
reference.name == "add" && reference.definingClass == "Ljava/util/ArrayList;"
|
||||
}
|
||||
|
||||
newAdPostMatch.mutableMethod.removeInstruction(index)
|
||||
newAdPostFingerprint.method.removeInstruction(index)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
@ -1,6 +1,6 @@
|
||||
package app.revanced.patches.reddit.customclients.baconreader.api
|
||||
|
||||
import app.revanced.patcher.Match
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
@ -12,16 +12,13 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://baconreader.com/au
|
||||
"com.onelouder.baconreader.premium",
|
||||
)
|
||||
|
||||
val getAuthorizationUrlMatch by getAuthorizationUrlFingerprint()
|
||||
val requestTokenMatch by requestTokenFingerprint()
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
||||
execute {
|
||||
fun Match.patch(replacementString: String) {
|
||||
fun Fingerprint.patch(replacementString: String) {
|
||||
val clientIdIndex = stringMatches!!.first().index
|
||||
|
||||
mutableMethod.apply {
|
||||
method.apply {
|
||||
val clientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
|
||||
replaceInstruction(
|
||||
clientIdIndex,
|
||||
@ -31,9 +28,9 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://baconreader.com/au
|
||||
}
|
||||
|
||||
// Patch client id in authorization url.
|
||||
getAuthorizationUrlMatch.patch("client_id=$clientId")
|
||||
getAuthorizationUrlFingerprint.patch("client_id=$clientId")
|
||||
|
||||
// Patch client id for access token request.
|
||||
requestTokenMatch.patch(clientId!!)
|
||||
requestTokenFingerprint.patch(clientId!!)
|
||||
}
|
||||
}
|
||||
|
@ -9,12 +9,9 @@ val disableAdsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.rubenmayayo.reddit")
|
||||
|
||||
val maxMediationMatch by maxMediationFingerprint()
|
||||
val admobMediationMatch by admobMediationFingerprint()
|
||||
|
||||
execute {
|
||||
arrayOf(maxMediationMatch, admobMediationMatch).forEach {
|
||||
it.mutableMethod.addInstructions(0, "return-void")
|
||||
arrayOf(maxMediationFingerprint, admobMediationFingerprint).forEach { fingerprint ->
|
||||
fingerprint.method.addInstructions(0, "return-void")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,12 @@ import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com") { clientIdOption ->
|
||||
compatibleWith("com.rubenmayayo.reddit")
|
||||
|
||||
val getClientIdMatch by getClientIdFingerprint()
|
||||
val buildUserAgentMatch by buildUserAgentFingerprint()
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
||||
execute {
|
||||
// region Patch client id.
|
||||
|
||||
getClientIdMatch.mutableMethod.addInstructions(
|
||||
getClientIdFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$clientId"
|
||||
@ -30,7 +27,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "http://rubenmayayo.com")
|
||||
val platformName = (0..100000).random()
|
||||
val platformParameter = 0
|
||||
|
||||
buildUserAgentMatch.mutableMethod.addInstructions(
|
||||
buildUserAgentFingerprint.method.addInstructions(
|
||||
0,
|
||||
"const-string p$platformParameter, \"$platformName\"",
|
||||
)
|
||||
|
@ -12,16 +12,14 @@ val fixAudioMissingInDownloadsPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.rubenmayayo.reddit")
|
||||
|
||||
val downloadAudioMatch by downloadAudioFingerprint()
|
||||
|
||||
execute {
|
||||
val endpointReplacements = mapOf(
|
||||
"/DASH_audio.mp4" to "/DASH_AUDIO_128.mp4",
|
||||
"/audio" to "/DASH_AUDIO_64.mp4",
|
||||
)
|
||||
|
||||
downloadAudioMatch.stringMatches!!.forEach { match ->
|
||||
downloadAudioMatch.mutableMethod.apply {
|
||||
downloadAudioFingerprint.method.apply {
|
||||
downloadAudioFingerprint.stringMatches!!.forEach { match ->
|
||||
val replacement = endpointReplacements[match.string]
|
||||
val register = getInstruction<OneRegisterInstruction>(match.index).registerA
|
||||
|
||||
|
@ -17,13 +17,10 @@ val fixSlinksPatch = fixSLinksPatch(
|
||||
) {
|
||||
compatibleWith("com.rubenmayayo.reddit")
|
||||
|
||||
val handleNavigationMatch by handleNavigationFingerprint()
|
||||
val setAccessTokenMatch by getOAuthAccessTokenFingerprint()
|
||||
|
||||
execute {
|
||||
// region Patch navigation handler.
|
||||
|
||||
handleNavigationMatch.mutableMethod.apply {
|
||||
handleNavigationFingerprint.method.apply {
|
||||
val urlRegister = "p1"
|
||||
val tempRegister = "v1"
|
||||
|
||||
@ -43,7 +40,7 @@ val fixSlinksPatch = fixSLinksPatch(
|
||||
|
||||
// region Patch set access token.
|
||||
|
||||
setAccessTokenMatch.mutableMethod.addInstruction(
|
||||
getOAuthAccessTokenFingerprint.method.addInstruction(
|
||||
3,
|
||||
"invoke-static { v0 }, $EXTENSION_CLASS_DESCRIPTOR->$SET_ACCESS_TOKEN_METHOD",
|
||||
)
|
||||
|
@ -10,12 +10,10 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "infinity://localhost") { clientIdOption ->
|
||||
compatibleWith("ml.docilealligator.infinityforreddit")
|
||||
|
||||
val apiUtilsMatch by apiUtilsFingerprint()
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
||||
execute {
|
||||
apiUtilsMatch.mutableClass.methods.apply {
|
||||
apiUtilsFingerprint.classDef.methods.apply {
|
||||
val getClientIdMethod = single { it.name == "getId" }.also(::remove)
|
||||
|
||||
val newGetClientIdMethod = ImmutableMethod(
|
||||
|
@ -13,10 +13,10 @@ val unlockSubscriptionPatch = bytecodePatch(
|
||||
|
||||
compatibleWith("ml.docilealligator.infinityforreddit")
|
||||
|
||||
startSubscriptionActivityFingerprint()
|
||||
billingClientOnServiceConnectedFingerprint()
|
||||
|
||||
execute {
|
||||
setOf(startSubscriptionActivityFingerprint, billingClientOnServiceConnectedFingerprint).returnEarly()
|
||||
setOf(
|
||||
startSubscriptionActivityFingerprint,
|
||||
billingClientOnServiceConnectedFingerprint,
|
||||
).forEach { it.method.returnEarly() }
|
||||
}
|
||||
}
|
||||
|
@ -12,10 +12,8 @@ val disableAdsPatch = bytecodePatch(
|
||||
|
||||
compatibleWith("o.o.joey")
|
||||
|
||||
val isAdFreeUserMatch by isAdFreeUserFingerprint()
|
||||
|
||||
execute {
|
||||
isAdFreeUserMatch.mutableMethod.addInstructions(
|
||||
isAdFreeUserFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -14,15 +14,12 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "https://127.0.0.1:65023/a
|
||||
"o.o.joey.dev",
|
||||
)
|
||||
|
||||
val getClientIdMatch by getClientIdFingerprint()
|
||||
val authUtilityUserAgentMatch by authUtilityUserAgentFingerprint()
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
||||
execute {
|
||||
// region Patch client id.
|
||||
|
||||
getClientIdMatch.mutableMethod.addInstructions(
|
||||
getClientIdFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$clientId"
|
||||
@ -38,7 +35,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "https://127.0.0.1:65023/a
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
authUtilityUserAgentMatch.mutableMethod.replaceInstructions(
|
||||
authUtilityUserAgentFingerprint.method.replaceInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$userAgent"
|
||||
|
@ -4,9 +4,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
|
||||
val disablePiracyDetectionPatch = bytecodePatch {
|
||||
val piracyDetectionMatch by piracyDetectionFingerprint()
|
||||
|
||||
execute {
|
||||
piracyDetectionMatch.mutableMethod.addInstruction(0, "return-void")
|
||||
piracyDetectionFingerprint.method.addInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package app.revanced.patches.reddit.customclients.redditisfun.api
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.Match
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
@ -16,10 +17,6 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { cl
|
||||
"com.andrewshu.android.redditdonation",
|
||||
)
|
||||
|
||||
val buildAuthorizationStringMatch by buildAuthorizationStringFingerprint()
|
||||
val basicAuthorizationMatch by basicAuthorizationFingerprint()
|
||||
val getUserAgentMatch by getUserAgentFingerprint()
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
||||
execute {
|
||||
@ -33,10 +30,10 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { cl
|
||||
* @param getReplacementIndex A function that returns the index of the instruction to replace
|
||||
* using the [Match.StringMatch] list from the [Match].
|
||||
*/
|
||||
fun Match.replaceWith(
|
||||
fun Fingerprint.replaceWith(
|
||||
string: String,
|
||||
getReplacementIndex: List<Match.StringMatch>.() -> Int,
|
||||
) = mutableMethod.apply {
|
||||
) = method.apply {
|
||||
val replacementIndex = stringMatches!!.getReplacementIndex()
|
||||
val clientIdRegister = getInstruction<OneRegisterInstruction>(replacementIndex).registerA
|
||||
|
||||
@ -44,10 +41,10 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { cl
|
||||
}
|
||||
|
||||
// Patch OAuth authorization.
|
||||
buildAuthorizationStringMatch.replaceWith(clientId!!) { first().index + 4 }
|
||||
buildAuthorizationStringFingerprint.replaceWith(clientId!!) { first().index + 4 }
|
||||
|
||||
// Path basic authorization.
|
||||
basicAuthorizationMatch.replaceWith("$clientId:") { last().index + 7 }
|
||||
basicAuthorizationFingerprint.replaceWith("$clientId:") { last().index + 7 }
|
||||
|
||||
// endregion
|
||||
|
||||
@ -57,7 +54,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { cl
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
getUserAgentMatch.mutableMethod.addInstructions(
|
||||
getUserAgentFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$userAgent"
|
||||
@ -71,7 +68,7 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "redditisfun://auth") { cl
|
||||
|
||||
// Reddit messed up and does not append a redirect uri to the authorization url to old.reddit.com/login.
|
||||
// Replace old.reddit.com with ssl.reddit.com to fix this.
|
||||
buildAuthorizationStringMatch.mutableMethod.apply {
|
||||
buildAuthorizationStringFingerprint.method.apply {
|
||||
val index = indexOfFirstInstructionOrThrow {
|
||||
getReference<StringReference>()?.contains("old.reddit.com") == true
|
||||
}
|
||||
|
@ -15,29 +15,22 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") {
|
||||
"reddit.news",
|
||||
)
|
||||
|
||||
val loginActivityClientIdMatch by loginActivityClientIdFingerprint()
|
||||
val getLoggedInBearerTokenMatch by getLoggedInBearerTokenFingerprint()
|
||||
val getLoggedOutBearerTokenMatch by getLoggedOutBearerTokenFingerprint()
|
||||
val getRefreshTokenMatch by getRefreshTokenFingerprint()
|
||||
val setRemoteConfigMatch by setRemoteConfigFingerprint()
|
||||
val redditCheckDisableAPIMatch by redditCheckDisableAPIFingerprint()
|
||||
|
||||
val clientId by it
|
||||
|
||||
execute {
|
||||
// region Patch client id.
|
||||
|
||||
setOf(
|
||||
loginActivityClientIdMatch,
|
||||
getLoggedInBearerTokenMatch,
|
||||
getLoggedOutBearerTokenMatch,
|
||||
getRefreshTokenMatch,
|
||||
).forEach { match ->
|
||||
val clientIdIndex = match.stringMatches!!.first().index
|
||||
match.mutableMethod.apply {
|
||||
loginActivityClientIdFingerprint,
|
||||
getLoggedInBearerTokenFingerprint,
|
||||
getLoggedOutBearerTokenFingerprint,
|
||||
getRefreshTokenFingerprint,
|
||||
).forEach { fingerprint ->
|
||||
val clientIdIndex = fingerprint.stringMatches!!.first().index
|
||||
fingerprint.method.apply {
|
||||
val clientIdRegister = getInstruction<OneRegisterInstruction>(clientIdIndex).registerA
|
||||
|
||||
match.mutableMethod.replaceInstruction(
|
||||
fingerprint.method.replaceInstruction(
|
||||
clientIdIndex,
|
||||
"const-string v$clientIdRegister, \"$clientId\"",
|
||||
)
|
||||
@ -49,12 +42,12 @@ val spoofClientPatch = spoofClientPatch(redirectUri = "dbrady://relay") {
|
||||
// region Patch miscellaneous.
|
||||
|
||||
// Do not load remote config which disables OAuth login remotely.
|
||||
setRemoteConfigMatch.mutableMethod.addInstructions(0, "return-void")
|
||||
setRemoteConfigFingerprint.method.addInstructions(0, "return-void")
|
||||
|
||||
// Prevent OAuth login being disabled remotely.
|
||||
val checkIsOAuthRequestIndex = redditCheckDisableAPIMatch.patternMatch!!.startIndex
|
||||
val checkIsOAuthRequestIndex = redditCheckDisableAPIFingerprint.patternMatch!!.startIndex
|
||||
|
||||
redditCheckDisableAPIMatch.mutableMethod.apply {
|
||||
redditCheckDisableAPIFingerprint.method.apply {
|
||||
val returnNextChain = getInstruction<BuilderInstruction21t>(checkIsOAuthRequestIndex).target
|
||||
replaceInstruction(checkIsOAuthRequestIndex, BuilderInstruction10t(Opcode.GOTO, returnNextChain))
|
||||
}
|
||||
|
@ -6,12 +6,10 @@ import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
val spoofClientPatch = spoofClientPatch(redirectUri = "http://www.ccrama.me") { clientIdOption ->
|
||||
compatibleWith("me.ccrama.redditslide")
|
||||
|
||||
val getClientIdMatch by getClientIdFingerprint()
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
||||
execute {
|
||||
getClientIdMatch.mutableMethod.addInstructions(
|
||||
getClientIdFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$clientId"
|
||||
|
@ -7,10 +7,8 @@ import app.revanced.util.returnEarly
|
||||
fun disableAdsPatch(block: BytecodePatchBuilder.() -> Unit = {}) = bytecodePatch(
|
||||
name = "Disable ads",
|
||||
) {
|
||||
isAdsEnabledFingerprint()
|
||||
|
||||
execute {
|
||||
isAdsEnabledFingerprint.returnEarly()
|
||||
isAdsEnabledFingerprint.method.returnEarly()
|
||||
}
|
||||
|
||||
block()
|
||||
|
@ -6,11 +6,10 @@ import app.revanced.patcher.patch.bytecodePatch
|
||||
val disablePiracyDetectionPatch = bytecodePatch(
|
||||
description = "Disables detection of modified versions.",
|
||||
) {
|
||||
val piracyDetectionMatch by piracyDetectionFingerprint()
|
||||
|
||||
execute {
|
||||
// Do not throw an error if the fingerprint is not resolved.
|
||||
// This is fine because new versions of the target app do not need this patch.
|
||||
piracyDetectionMatch.mutableMethod.addInstruction(0, "return-void")
|
||||
piracyDetectionFingerprint.method.addInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,8 @@ val disableSyncForLemmyBottomSheetPatch = bytecodePatch(
|
||||
"com.laurencedawson.reddit_sync.dev"(), // Version unknown.
|
||||
)
|
||||
|
||||
val mainActivityOnCreateMatch by mainActivityOnCreateFingerprint()
|
||||
|
||||
execute {
|
||||
mainActivityOnCreateMatch.mutableMethod.apply {
|
||||
mainActivityOnCreateFingerprint.method.apply {
|
||||
val showBottomSheetIndex = implementation!!.instructions.lastIndex - 1
|
||||
|
||||
removeInstruction(showBottomSheetIndex)
|
||||
|
@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patches.reddit.customclients.spoofClientPatch
|
||||
import app.revanced.patches.reddit.customclients.sync.detection.piracy.disablePiracyDetectionPatch
|
||||
import app.revanced.util.matchOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
||||
@ -22,18 +21,12 @@ val spoofClientPatch = spoofClientPatch(
|
||||
"com.laurencedawson.reddit_sync.dev",
|
||||
)
|
||||
|
||||
val imgurImageAPIMatch by imgurImageAPIFingerprint()
|
||||
val getAuthorizationStringMatch by getAuthorizationStringFingerprint()
|
||||
val getUserAgentMatch by getUserAgentFingerprint()
|
||||
|
||||
val clientId by clientIdOption
|
||||
|
||||
execute { context ->
|
||||
execute {
|
||||
// region Patch client id.
|
||||
|
||||
getBearerTokenFingerprint.apply {
|
||||
match(context, getAuthorizationStringMatch.classDef)
|
||||
}.matchOrThrow.mutableMethod.apply {
|
||||
getBearerTokenFingerprint.match(getAuthorizationStringFingerprint.originalClassDef).method.apply {
|
||||
val auth = Base64.getEncoder().encodeToString("$clientId:".toByteArray(Charsets.UTF_8))
|
||||
addInstructions(
|
||||
0,
|
||||
@ -43,9 +36,9 @@ val spoofClientPatch = spoofClientPatch(
|
||||
""",
|
||||
)
|
||||
val occurrenceIndex =
|
||||
getAuthorizationStringMatch.stringMatches!!.first().index
|
||||
getAuthorizationStringFingerprint.stringMatches!!.first().index
|
||||
|
||||
getAuthorizationStringMatch.mutableMethod.apply {
|
||||
getAuthorizationStringFingerprint.method.apply {
|
||||
val authorizationStringInstruction = getInstruction<ReferenceInstruction>(occurrenceIndex)
|
||||
val targetRegister = (authorizationStringInstruction as OneRegisterInstruction).registerA
|
||||
val reference = authorizationStringInstruction.reference as StringReference
|
||||
@ -70,7 +63,7 @@ val spoofClientPatch = spoofClientPatch(
|
||||
val randomName = (0..100000).random()
|
||||
val userAgent = "$randomName:app.revanced.$randomName:v1.0.0 (by /u/revanced)"
|
||||
|
||||
imgurImageAPIMatch.mutableMethod.replaceInstruction(
|
||||
imgurImageAPIFingerprint.method.replaceInstruction(
|
||||
0,
|
||||
"""
|
||||
const-string v0, "$userAgent"
|
||||
@ -82,8 +75,8 @@ val spoofClientPatch = spoofClientPatch(
|
||||
|
||||
// region Patch Imgur API URL.
|
||||
|
||||
val apiUrlIndex = getUserAgentMatch.stringMatches!!.first().index
|
||||
getUserAgentMatch.mutableMethod.replaceInstruction(
|
||||
val apiUrlIndex = getUserAgentFingerprint.stringMatches!!.first().index
|
||||
getUserAgentFingerprint.method.replaceInstruction(
|
||||
apiUrlIndex,
|
||||
"const-string v1, \"https://api.imgur.com/3/image\"",
|
||||
)
|
||||
|
@ -6,6 +6,8 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.util.smali.ExternalLabel
|
||||
import app.revanced.patches.reddit.customclients.RESOLVE_S_LINK_METHOD
|
||||
import app.revanced.patches.reddit.customclients.SET_ACCESS_TOKEN_METHOD
|
||||
import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.getOAuthAccessTokenFingerprint
|
||||
import app.revanced.patches.reddit.customclients.boostforreddit.fix.slink.handleNavigationFingerprint
|
||||
import app.revanced.patches.reddit.customclients.fixSLinksPatch
|
||||
import app.revanced.patches.reddit.customclients.sync.syncforreddit.extension.sharedExtensionPatch
|
||||
|
||||
@ -21,13 +23,10 @@ val fixSLinksPatch = fixSLinksPatch(
|
||||
"com.laurencedawson.reddit_sync.dev",
|
||||
)
|
||||
|
||||
val handleNavigationMatch by linkHelperOpenLinkFingerprint()
|
||||
val setAccessTokenMatch by setAuthorizationHeaderFingerprint()
|
||||
|
||||
execute {
|
||||
// region Patch navigation handler.
|
||||
|
||||
handleNavigationMatch.mutableMethod.apply {
|
||||
handleNavigationFingerprint.method.apply {
|
||||
val urlRegister = "p3"
|
||||
val tempRegister = "v2"
|
||||
|
||||
@ -47,7 +46,7 @@ val fixSLinksPatch = fixSLinksPatch(
|
||||
|
||||
// region Patch set access token.
|
||||
|
||||
setAccessTokenMatch.mutableMethod.addInstruction(
|
||||
getOAuthAccessTokenFingerprint.method.addInstruction(
|
||||
0,
|
||||
"invoke-static { p0 }, $EXTENSION_CLASS_DESCRIPTOR->$SET_ACCESS_TOKEN_METHOD",
|
||||
)
|
||||
|
@ -20,22 +20,17 @@ val useUserEndpointPatch = bytecodePatch(
|
||||
"com.laurencedawson.reddit_sync.dev",
|
||||
)
|
||||
|
||||
val oAuthFriendRequestMatch by oAuthFriendRequestFingerprint()
|
||||
val oAuthSubredditInfoRequestConstructorMatch by oAuthSubredditInfoRequestConstructorFingerprint()
|
||||
val oAuthSubredditInfoRequestHelperMatch by oAuthSubredditInfoRequestHelperFingerprint()
|
||||
val oAuthUnfriendRequestMatch by oAuthUnfriendRequestFingerprint()
|
||||
val oAuthUserIdRequestMatch by oAuthUserIdRequestFingerprint()
|
||||
val oAuthUserInfoRequestMatch by oAuthUserInfoRequestFingerprint()
|
||||
|
||||
execute {
|
||||
arrayOf(
|
||||
oAuthFriendRequestMatch,
|
||||
oAuthSubredditInfoRequestConstructorMatch,
|
||||
oAuthSubredditInfoRequestHelperMatch,
|
||||
oAuthUnfriendRequestMatch,
|
||||
oAuthUserIdRequestMatch,
|
||||
oAuthUserInfoRequestMatch,
|
||||
).map { it.stringMatches!!.first().index to it.mutableMethod }.forEach { (userPathStringIndex, method) ->
|
||||
oAuthFriendRequestFingerprint,
|
||||
oAuthSubredditInfoRequestConstructorFingerprint,
|
||||
oAuthSubredditInfoRequestHelperFingerprint,
|
||||
oAuthUnfriendRequestFingerprint,
|
||||
oAuthUserIdRequestFingerprint,
|
||||
oAuthUserInfoRequestFingerprint,
|
||||
).map { fingerprint ->
|
||||
fingerprint.stringMatches!!.first().index to fingerprint.method
|
||||
}.forEach { (userPathStringIndex, method) ->
|
||||
val userPathStringInstruction = method.getInstruction<OneRegisterInstruction>(userPathStringIndex)
|
||||
|
||||
val userPathStringRegister = userPathStringInstruction.registerA
|
||||
|
@ -23,16 +23,15 @@ val fixVideoDownloadsPatch = bytecodePatch(
|
||||
"com.laurencedawson.reddit_sync.dev",
|
||||
)
|
||||
|
||||
val parseRedditVideoNetworkResponseMatch by parseRedditVideoNetworkResponseFingerprint()
|
||||
|
||||
execute {
|
||||
val scanResult = parseRedditVideoNetworkResponseMatch.patternMatch!!
|
||||
val scanResult = parseRedditVideoNetworkResponseFingerprint.patternMatch!!
|
||||
val newInstanceIndex = scanResult.startIndex
|
||||
val invokeDirectIndex = scanResult.endIndex - 1
|
||||
|
||||
val buildResponseInstruction = parseRedditVideoNetworkResponseMatch.mutableMethod.getInstruction<Instruction35c>(invokeDirectIndex)
|
||||
val buildResponseInstruction =
|
||||
parseRedditVideoNetworkResponseFingerprint.method.getInstruction<Instruction35c>(invokeDirectIndex)
|
||||
|
||||
parseRedditVideoNetworkResponseMatch.mutableMethod.addInstructions(
|
||||
parseRedditVideoNetworkResponseFingerprint.method.addInstructions(
|
||||
newInstanceIndex + 1,
|
||||
"""
|
||||
# Get byte array from response.
|
||||
|
@ -10,9 +10,7 @@ val disableScreenshotPopupPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.reddit.frontpage")
|
||||
|
||||
val disableScreenshotPopupMatch by disableScreenshotPopupFingerprint()
|
||||
|
||||
execute {
|
||||
disableScreenshotPopupMatch.mutableMethod.addInstruction(0, "return-void")
|
||||
disableScreenshotPopupFingerprint.method.addInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,8 @@ val unlockPremiumIconPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.reddit.frontpage")
|
||||
|
||||
val hasPremiumIconAccessMatch by hasPremiumIconAccessFingerprint()
|
||||
|
||||
execute {
|
||||
hasPremiumIconAccessMatch.mutableMethod.addInstructions(
|
||||
hasPremiumIconAccessFingerprint.method.addInstructions(
|
||||
0,
|
||||
"""
|
||||
const/4 v0, 0x1
|
||||
|
@ -10,10 +10,8 @@ val sanitizeUrlQueryPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("com.reddit.frontpage")
|
||||
|
||||
val shareLinkFormatterMatch by shareLinkFormatterFingerprint()
|
||||
|
||||
execute {
|
||||
shareLinkFormatterMatch.mutableMethod.addInstructions(
|
||||
shareLinkFormatterFingerprint.method.addInstructions(
|
||||
0,
|
||||
"return-object p0",
|
||||
)
|
||||
|
@ -10,9 +10,7 @@ val rootDetectionPatch = bytecodePatch(
|
||||
) {
|
||||
compatibleWith("at.gv.bka.serviceportal")
|
||||
|
||||
val rootDetectionMatch by rootDetectionFingerprint()
|
||||
|
||||
execute {
|
||||
rootDetectionMatch.mutableMethod.addInstruction(0, "return-void")
|
||||
rootDetectionFingerprint.method.addInstruction(0, "return-void")
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package app.revanced.patches.shared.misc.checks
|
||||
|
||||
import android.os.Build.*
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.Match
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
@ -35,20 +34,24 @@ fun checkEnvironmentPatch(
|
||||
addResourcesPatch,
|
||||
)
|
||||
|
||||
val patchInfoMatch by patchInfoFingerprint()
|
||||
val patchInfoBuildMatch by patchInfoBuildFingerprint()
|
||||
val mainActivityOnCreateMatch by mainActivityOnCreateFingerprint()
|
||||
|
||||
execute {
|
||||
addResources("shared", "misc.checks.checkEnvironmentPatch")
|
||||
|
||||
fun setPatchInfo() {
|
||||
patchInfoMatch.setClassFields(
|
||||
fun <T : MutableEncodedValue> Fingerprint.setClassFields(vararg fieldNameValues: Pair<String, T>) {
|
||||
val fieldNameValueMap = mapOf(*fieldNameValues)
|
||||
|
||||
classDef.fields.forEach { field ->
|
||||
field.initialValue = fieldNameValueMap[field.name] ?: return@forEach
|
||||
}
|
||||
}
|
||||
|
||||
patchInfoFingerprint.setClassFields(
|
||||
"PATCH_TIME" to System.currentTimeMillis().encoded,
|
||||
)
|
||||
|
||||
fun setBuildInfo() {
|
||||
patchInfoBuildMatch.setClassFields(
|
||||
patchInfoBuildFingerprint.setClassFields(
|
||||
"PATCH_BOARD" to BOARD.encodedAndHashed,
|
||||
"PATCH_BOOTLOADER" to BOOTLOADER.encodedAndHashed,
|
||||
"PATCH_BRAND" to BRAND.encodedAndHashed,
|
||||
@ -79,7 +82,7 @@ fun checkEnvironmentPatch(
|
||||
}
|
||||
}
|
||||
|
||||
fun invokeCheck() = mainActivityOnCreateMatch.mutableMethod?.addInstructions(
|
||||
fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstructions(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 },$EXTENSION_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
|
||||
)
|
||||
@ -101,11 +104,3 @@ private val String.encodedAndHashed
|
||||
)
|
||||
|
||||
private val Long.encoded get() = MutableLongEncodedValue(ImmutableLongEncodedValue(this))
|
||||
|
||||
private fun <T : MutableEncodedValue> Match.setClassFields(vararg fieldNameValues: Pair<String, T>) {
|
||||
val fieldNameValueMap = mapOf(*fieldNameValues)
|
||||
|
||||
mutableClass.fields.forEach { field ->
|
||||
field.initialValue = fieldNameValueMap[field.name] ?: return@forEach
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@ import app.revanced.patcher.FingerprintBuilder
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.util.matchOrThrow
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import java.net.URLDecoder
|
||||
import java.util.jar.JarFile
|
||||
@ -19,11 +19,8 @@ fun sharedExtensionPatch(
|
||||
) = bytecodePatch {
|
||||
extendWith("extensions/shared.rve")
|
||||
|
||||
val revancedUtilsPatchesVersionMatch by revancedUtilsPatchesVersionFingerprint()
|
||||
hooks.forEach { it.fingerprint() }
|
||||
|
||||
execute { context ->
|
||||
if (context.classBy { EXTENSION_CLASS_DESCRIPTOR in it.type } == null) {
|
||||
execute {
|
||||
if (classBy { EXTENSION_CLASS_DESCRIPTOR in it.type } == null) {
|
||||
throw PatchException(
|
||||
"Shared extension has not been merged yet. This patch can not succeed without merging it.",
|
||||
)
|
||||
@ -32,7 +29,7 @@ fun sharedExtensionPatch(
|
||||
hooks.forEach { hook -> hook(EXTENSION_CLASS_DESCRIPTOR) }
|
||||
|
||||
// Modify Utils method to include the patches release version.
|
||||
revancedUtilsPatchesVersionMatch.mutableMethod.apply {
|
||||
revancedUtilsPatchesVersionFingerprint.method.apply {
|
||||
/**
|
||||
* @return The file path for the jar this classfile is contained inside.
|
||||
*/
|
||||
@ -79,19 +76,18 @@ class ExtensionHook internal constructor(
|
||||
private val insertIndexResolver: ((Method) -> Int),
|
||||
private val contextRegisterResolver: (Method) -> String,
|
||||
) {
|
||||
context(BytecodePatchContext)
|
||||
operator fun invoke(extensionClassDescriptor: String) {
|
||||
fingerprint.matchOrThrow.mutableMethod.let { method ->
|
||||
val insertIndex = insertIndexResolver(method)
|
||||
val contextRegister = contextRegisterResolver(method)
|
||||
val insertIndex = insertIndexResolver(fingerprint.method)
|
||||
val contextRegister = contextRegisterResolver(fingerprint.method)
|
||||
|
||||
method.addInstruction(
|
||||
fingerprint.method.addInstruction(
|
||||
insertIndex,
|
||||
"invoke-static/range { $contextRegister .. $contextRegister }, " +
|
||||
"$extensionClassDescriptor->setContext(Landroid/content/Context;)V",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun extensionHook(
|
||||
insertIndexResolver: ((Method) -> Int) = { 0 },
|
||||
|
@ -8,11 +8,10 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
val verticalScrollPatch = bytecodePatch(
|
||||
description = "Fixes issues with refreshing the feed when the first component is of type EmptyComponent.",
|
||||
) {
|
||||
val canScrollVerticallyMatch by canScrollVerticallyFingerprint()
|
||||
|
||||
execute {
|
||||
canScrollVerticallyMatch.mutableMethod.apply {
|
||||
val moveResultIndex = canScrollVerticallyMatch.patternMatch!!.endIndex
|
||||
canScrollVerticallyFingerprint.method.apply {
|
||||
val moveResultIndex = canScrollVerticallyFingerprint.patternMatch!!.endIndex
|
||||
val moveResultRegister = getInstruction<OneRegisterInstruction>(moveResultIndex).registerA
|
||||
|
||||
val insertIndex = moveResultIndex + 1
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user