chore: Lint code

This commit also changes the API, but these changes are considered fixes.
This commit is contained in:
oSumAtrIX 2024-03-02 23:53:59 +01:00
parent e8b54bd0ec
commit 9ac558dd2b
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
563 changed files with 2281 additions and 2207 deletions

View File

@ -314,8 +314,8 @@ public final class app/revanced/patches/music/interaction/permanentrepeat/Perman
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}
public final class app/revanced/patches/music/interaction/permanentshuffle/PermanentShuffleTogglePatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/music/interaction/permanentshuffle/PermanentShuffleTogglePatch;
public final class app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}
@ -894,8 +894,8 @@ public final class app/revanced/patches/strava/upselling/DisableSubscriptionSugg
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}
public final class app/revanced/patches/ticktick/misc/themeunlock/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/ticktick/misc/themeunlock/UnlockProPatch;
public final class app/revanced/patches/ticktick/misc/themeunlock/UnlockThemesPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/ticktick/misc/themeunlock/UnlockThemesPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}

View File

@ -14,7 +14,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
name = "Spoof Wi-Fi connection",
description = "Spoofs an existing Wi-Fi connection.",
use = false,
requiresIntegrations = true
requiresIntegrations = true,
)
@Suppress("unused")
object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
@ -25,12 +25,12 @@ object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int
instructionIndex: Int,
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex
instructionIndex,
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
@ -38,7 +38,6 @@ object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
}
// Information about method calls we want to replace
private enum class MethodCall(
override val definedClassName: String,
@ -201,6 +200,6 @@ object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
"unregisterNetworkCallback",
arrayOf("Landroid/app/PendingIntent;"),
"V",
);
),
}
}

View File

@ -33,48 +33,50 @@ interface IMethodCall {
definingClassDescriptor: String,
method: MutableMethod,
instruction: Instruction35c,
instructionIndex: Int
instructionIndex: Int,
) {
val registers = arrayOf(
instruction.registerC,
instruction.registerD,
instruction.registerE,
instruction.registerF,
instruction.registerG
instruction.registerG,
)
val argsNum = methodParams.size + 1 // + 1 for instance of definedClassName
if (argsNum > registers.size) {
// should never happen, but just to be sure (also for the future) a safety check
throw RuntimeException(
"Not enough registers for ${definedClassName}#${methodName}: " +
"Required $argsNum registers, but only got ${registers.size}."
"Not enough registers for $definedClassName#$methodName: " +
"Required $argsNum registers, but only got ${registers.size}.",
)
}
val args = registers.take(argsNum).joinToString(separator = ", ") { reg -> "v${reg}" }
val args = registers.take(argsNum).joinToString(separator = ", ") { reg -> "v$reg" }
val replacementMethodDefinition =
"${methodName}(${definedClassName}${methodParams.joinToString(separator = "")})${returnType}"
"$methodName(${definedClassName}${methodParams.joinToString(separator = "")})$returnType"
method.replaceInstruction(
instructionIndex,
"invoke-static { $args }, ${definingClassDescriptor}->${replacementMethodDefinition}"
"invoke-static { $args }, $definingClassDescriptor->$replacementMethodDefinition",
)
}
}
inline fun <reified E> fromMethodReference(methodReference: MethodReference)
inline fun <reified E> fromMethodReference(
methodReference: MethodReference,
)
where E : Enum<E>, E : IMethodCall = enumValues<E>().firstOrNull { search ->
search.definedClassName == methodReference.definingClass
&& search.methodName == methodReference.name
&& methodReference.parameterTypes.toTypedArray().contentEquals(search.methodParams)
&& search.returnType == methodReference.returnType
search.definedClassName == methodReference.definingClass &&
search.methodName == methodReference.name &&
methodReference.parameterTypes.toTypedArray().contentEquals(search.methodParams) &&
search.returnType == methodReference.returnType
}
inline fun <reified E> filterMapInstruction35c(
integrationsClassDescriptorPrefix: String,
classDef: ClassDef,
instruction: Instruction,
instructionIndex: Int
instructionIndex: Int,
): Instruction35cInfo? where E : Enum<E>, E : IMethodCall {
if (classDef.type.startsWith(integrationsClassDescriptorPrefix)) {
// avoid infinite recursion

View File

@ -15,19 +15,20 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
description = "Removes the restriction of capturing audio from apps that normally wouldn't allow it.",
dependencies = [RemoveCaptureRestrictionResourcePatch::class],
use = false,
requiresIntegrations = true
requiresIntegrations = true,
)
@Suppress("unused")
object RemoveCaptureRestrictionPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
private const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/integrations/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch"
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
// Information about method calls we want to replace
enum class MethodCall(
override val definedClassName: String,
override val methodName: String,
override val methodParams: Array<String>,
override val returnType: String
override val returnType: String,
) : IMethodCall {
SetAllowedCapturePolicySingle(
"Landroid/media/AudioAttributes\$Builder;",
@ -40,19 +41,19 @@ object RemoveCaptureRestrictionPatch : BaseTransformInstructionsPatch<Instructio
"setAllowedCapturePolicy",
arrayOf("I"),
"V",
);
),
}
override fun filterMap(
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int
instructionIndex: Int,
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex
instructionIndex,
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {

View File

@ -36,12 +36,12 @@ object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruc
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int
instructionIndex: Int,
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex
instructionIndex,
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
@ -54,7 +54,7 @@ object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruc
override val definedClassName: String,
override val methodName: String,
override val methodParams: Array<String>,
override val returnType: String
override val returnType: String,
) : IMethodCall {
AddFlags(
"Landroid/view/Window;",
@ -67,7 +67,7 @@ object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruc
"setFlags",
arrayOf("I", "I"),
"V",
);
),
}
}
@ -76,7 +76,7 @@ private class ModifyLayoutParamsFlags : BaseTransformInstructionsPatch<Pair<Inst
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int
instructionIndex: Int,
): Pair<Instruction22c, Int>? {
if (instruction.opcode != Opcode.IPUT) {
return null
@ -85,9 +85,10 @@ private class ModifyLayoutParamsFlags : BaseTransformInstructionsPatch<Pair<Inst
val instruction22c = instruction as Instruction22c
val fieldReference = instruction22c.reference as FieldReference
if (fieldReference.definingClass != "Landroid/view/WindowManager\$LayoutParams;"
|| fieldReference.name != "flags"
|| fieldReference.type != "I") {
if (fieldReference.definingClass != "Landroid/view/WindowManager\$LayoutParams;" ||
fieldReference.name != "flags" ||
fieldReference.type != "I"
) {
return null
}
@ -100,7 +101,7 @@ private class ModifyLayoutParamsFlags : BaseTransformInstructionsPatch<Pair<Inst
mutableMethod.addInstructions(
index,
"and-int/lit16 v$register, v$register, -0x2001"
"and-int/lit16 v$register, v$register, -0x2001",
)
}
}

View File

@ -16,7 +16,6 @@ import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodRefere
import com.android.tools.smali.dexlib2.util.MethodUtil
import java.util.*
@Patch(
name = "Spoof SIM country",
description = "Spoofs country information returned by the SIM card provider.",
@ -46,14 +45,14 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
title,
"ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.",
false,
validator = { it: String? -> it == null || it.uppercase() in countries.values }
validator = { it: String? -> it == null || it.uppercase() in countries.values },
)
override fun filterMap(
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int
instructionIndex: Int,
): Pair<Int, String>? {
if (instruction !is ReferenceInstruction) return null
@ -73,12 +72,12 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
override fun transform(
mutableMethod: MutableMethod,
entry: Pair<Int, String>
entry: Pair<Int, String>,
) = transformMethodCall(entry, mutableMethod)
private fun transformMethodCall(
entry: Pair<Int, String>,
mutableMethod: MutableMethod
mutableMethod: MutableMethod,
) {
val (instructionIndex, methodCallValue) = entry
@ -86,28 +85,28 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
mutableMethod.replaceInstruction(
instructionIndex + 1,
"const-string v$register, \"$methodCallValue\""
"const-string v$register, \"$methodCallValue\"",
)
}
private enum class MethodCall(
val reference: MethodReference
val reference: MethodReference,
) {
NetworkCountryIso(
ImmutableMethodReference(
"Landroid/telephony/TelephonyManager;",
"getNetworkCountryIso",
emptyList(),
"Ljava/lang/String;"
)
"Ljava/lang/String;",
),
),
SimCountryIso(
ImmutableMethodReference(
"Landroid/telephony/TelephonyManager;",
"getSimCountryIso",
emptyList(),
"Ljava/lang/String;"
)
)
"Ljava/lang/String;",
),
),
}
}

View File

@ -1,6 +1,5 @@
package app.revanced.patches.backdrops.misc.pro
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@ -8,15 +7,16 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.backdrops.misc.pro.fingerprints.ProUnlockFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Pro unlock",
compatiblePackages = [CompatiblePackage("com.backdrops.wallpapers", ["4.52"])]
compatiblePackages = [CompatiblePackage("com.backdrops.wallpapers", ["4.52"])],
)
@Suppress("unused")
object ProUnlockPatch : BytecodePatch(
setOf(ProUnlockFingerprint)
setOf(ProUnlockFingerprint),
) {
override fun execute(context: BytecodeContext) {
ProUnlockFingerprint.result?.let { result ->
@ -28,10 +28,9 @@ object ProUnlockPatch : BytecodePatch(
result.scanResult.patternScanResult!!.endIndex,
"""
const/4 v$register, 0x1
"""
""",
)
}
} ?: throw ProUnlockFingerprint.exception
}
}

View File

@ -9,10 +9,10 @@ internal object ProUnlockFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ
Opcode.IF_EQZ,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/backdrops/wallpapers/data/local/DatabaseHandlerIAB;"
&& methodDef.name == "lambda\$existPurchase\$0"
}
methodDef.definingClass == "Lcom/backdrops/wallpapers/data/local/DatabaseHandlerIAB;" &&
methodDef.name == "lambda\$existPurchase\$0"
},
)

View File

@ -1,20 +1,20 @@
package app.revanced.patches.candylinkvpn
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.candylinkvpn.fingerprints.IsPremiumPurchasedFingerprint
import app.revanced.util.exception
@Patch(
name = "Unlock pro",
compatiblePackages = [CompatiblePackage("com.candylink.openvpn")]
compatiblePackages = [CompatiblePackage("com.candylink.openvpn")],
)
@Suppress("unused")
object UnlockProPatch : BytecodePatch(
setOf(IsPremiumPurchasedFingerprint)
setOf(IsPremiumPurchasedFingerprint),
) {
override fun execute(context: BytecodeContext) {
IsPremiumPurchasedFingerprint.result?.mutableMethod?.addInstructions(
@ -22,7 +22,7 @@ object UnlockProPatch : BytecodePatch(
"""
const/4 v0, 0x1
return v0
"""
""",
) ?: throw IsPremiumPurchasedFingerprint.exception
}
}

View File

@ -6,5 +6,5 @@ internal object IsPremiumPurchasedFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("PreferenceProvider;") &&
methodDef.name == "isPremiumPurchased"
}
},
)

View File

@ -1,21 +1,21 @@
package app.revanced.patches.cieid.restrictions.root
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.cieid.restrictions.root.fingerprints.CheckRootFingerprint
import app.revanced.util.exception
@Patch(
name = "Bypass root checks",
description = "Removes the restriction to use the app with root permissions or on a custom ROM.",
compatiblePackages = [CompatiblePackage("it.ipzs.cieid")]
compatiblePackages = [CompatiblePackage("it.ipzs.cieid")],
)
@Suppress("unused")
object BypassRootChecksPatch : BytecodePatch(
setOf(CheckRootFingerprint)
setOf(CheckRootFingerprint),
) {
override fun execute(context: BytecodeContext) {
CheckRootFingerprint.result?.mutableMethod?.addInstruction(1, "return-void")

View File

@ -5,5 +5,5 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
internal object CheckRootFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lit/ipzs/cieid/BaseActivity;" && methodDef.name == "onResume"
}
},
)

View File

@ -1,6 +1,5 @@
package app.revanced.patches.facebook.ads.story
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
@ -8,15 +7,16 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.facebook.ads.story.fingerprints.AdsInsertionFingerprint
import app.revanced.patches.facebook.ads.story.fingerprints.FetchMoreAdsFingerprint
import app.revanced.util.exception
@Patch(
name = "Hide story ads",
description = "Hides the ads in the Facebook app stories.",
compatiblePackages = [CompatiblePackage("com.facebook.katana")]
compatiblePackages = [CompatiblePackage("com.facebook.katana")],
)
@Suppress("unused")
object HideStoryAdsPatch : BytecodePatch(
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint)
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint),
) {
override fun execute(context: BytecodeContext) =
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint).forEach { fingerprint ->

View File

@ -11,5 +11,5 @@ internal abstract class FieldMethodFingerprint(fieldValue: String) : MethodFinge
if (field.name != "__redex_internal_original_name") return@any false
(field.initialValue as? StringEncodedValue)?.value == fieldValue
}
}
},
)

View File

@ -1,6 +1,5 @@
package app.revanced.patches.finanzonline.detection.bootloader
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
@ -8,16 +7,16 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.finanzonline.detection.bootloader.fingerprints.BootStateFingerprint
import app.revanced.patches.finanzonline.detection.bootloader.fingerprints.CreateKeyFingerprint
import app.revanced.util.exception
@Patch(
name = "Remove bootloader detection",
description = "Removes the check for an unlocked bootloader.",
compatiblePackages = [CompatiblePackage("at.gv.bmf.bmf2go")]
compatiblePackages = [CompatiblePackage("at.gv.bmf.bmf2go")],
)
@Suppress("unused")
object BootloaderDetectionPatch : BytecodePatch(
setOf(CreateKeyFingerprint, BootStateFingerprint)
setOf(CreateKeyFingerprint, BootStateFingerprint),
) {
override fun execute(context: BytecodeContext) {
arrayOf(CreateKeyFingerprint, BootStateFingerprint).forEach { fingerprint ->
@ -26,7 +25,7 @@ object BootloaderDetectionPatch : BytecodePatch(
"""
const/4 v0, 0x1
return v0
"""
""",
) ?: throw fingerprint.exception
}
}

View File

@ -25,6 +25,6 @@ internal object BootStateFingerprint : MethodFingerprint(
Opcode.IF_NE,
Opcode.GOTO,
Opcode.MOVE,
Opcode.RETURN
)
Opcode.RETURN,
),
)

View File

@ -7,5 +7,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object CreateKeyFingerprint : MethodFingerprint(
"Z",
accessFlags = AccessFlags.PUBLIC.value,
strings = listOf("attestation", "SHA-256", "random", "EC", "AndroidKeyStore")
strings = listOf("attestation", "SHA-256", "random", "EC", "AndroidKeyStore"),
)

View File

@ -1,21 +1,21 @@
package app.revanced.patches.finanzonline.detection.root
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.finanzonline.detection.root.fingerprints.RootDetectionFingerprint
import app.revanced.util.exception
@Patch(
name = "Remove root detection",
description = "Removes the check for root permissions.",
compatiblePackages = [CompatiblePackage("at.gv.bmf.bmf2go")]
compatiblePackages = [CompatiblePackage("at.gv.bmf.bmf2go")],
)
@Suppress("unused")
object RootDetectionPatch : BytecodePatch(
setOf(RootDetectionFingerprint)
setOf(RootDetectionFingerprint),
) {
override fun execute(context: BytecodeContext) {
RootDetectionFingerprint.result?.mutableMethod?.addInstructions(
@ -23,7 +23,7 @@ object RootDetectionPatch : BytecodePatch(
"""
sget-object v0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
return-object v0
"""
""",
) ?: throw RootDetectionFingerprint.exception
}
}

View File

@ -17,6 +17,6 @@ internal object RootDetectionFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT
)
Opcode.RETURN_OBJECT,
),
)

View File

@ -1,6 +1,5 @@
package app.revanced.patches.googlerecorder.restrictions
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@ -9,16 +8,17 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.googlerecorder.restrictions.fingerprints.OnApplicationCreateFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Remove device restrictions",
description = "Removes restrictions from using the app on any device. Requires mounting patched app over original.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.recorder")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.recorder")],
)
@Suppress("unused")
object RemoveDeviceRestrictions : BytecodePatch(
setOf(OnApplicationCreateFingerprint)
setOf(OnApplicationCreateFingerprint),
) {
override fun execute(context: BytecodeContext) {
OnApplicationCreateFingerprint.result?.let {

View File

@ -8,5 +8,5 @@ internal object OnApplicationCreateFingerprint : MethodFingerprint(
if (methodDef.name != "onCreate") return@custom false
classDef.type.endsWith("RecorderApplication;")
}
},
)

View File

@ -1,26 +1,26 @@
package app.revanced.patches.hexeditor.ad
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.hexeditor.ad.fingerprints.PrimaryAdsFingerprint
import app.revanced.util.exception
@Patch(
name = "Disable ads",
compatiblePackages = [CompatiblePackage("com.myprog.hexedit")]
compatiblePackages = [CompatiblePackage("com.myprog.hexedit")],
)
@Suppress("unused")
object DisableAdsPatch : BytecodePatch(
setOf(PrimaryAdsFingerprint)
setOf(PrimaryAdsFingerprint),
) {
override fun execute(context: BytecodeContext) = PrimaryAdsFingerprint.result?.mutableMethod?.replaceInstructions(
0,
"""
const/4 v0, 0x1
return v0
"""
""",
) ?: throw PrimaryAdsFingerprint.exception
}

View File

@ -5,5 +5,5 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
internal object PrimaryAdsFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("PreferencesHelper;") && methodDef.name == "isAdsDisabled"
}
},
)

View File

@ -9,11 +9,11 @@ import app.revanced.patches.iconpackstudio.misc.pro.fingerprints.CheckProFingerp
@Patch(
name = "Unlock pro",
compatiblePackages = [CompatiblePackage("ginlemon.iconpackstudio", ["2.2 build 016"])]
compatiblePackages = [CompatiblePackage("ginlemon.iconpackstudio", ["2.2 build 016"])],
)
@Suppress("unused")
object UnlockProPatch : BytecodePatch(
setOf(CheckProFingerprint)
setOf(CheckProFingerprint),
) {
override fun execute(context: BytecodeContext) {
val method = CheckProFingerprint.result!!.mutableMethod
@ -22,7 +22,7 @@ object UnlockProPatch : BytecodePatch(
"""
const/4 v0, 0x1
return v0
"""
""",
)
}
}

View File

@ -4,5 +4,5 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
internal object CheckProFingerprint : MethodFingerprint(
"Z",
customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("IPSPurchaseRepository;")}
customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("IPSPurchaseRepository;") },
)

View File

@ -12,15 +12,15 @@ import app.revanced.util.returnEarly
@Patch(
name = "Remove root detection",
description = "Removes the check for root permissions and unlocked bootloader.",
compatiblePackages = [CompatiblePackage("at.gv.oe.app")]
compatiblePackages = [CompatiblePackage("at.gv.oe.app")],
)
@Suppress("unused")
object RootDetectionPatch : BytecodePatch(
setOf(AttestationSupportedCheckFingerprint, BootloaderCheckFingerprint, RootCheckFingerprint)
setOf(AttestationSupportedCheckFingerprint, BootloaderCheckFingerprint, RootCheckFingerprint),
) {
override fun execute(context: BytecodeContext) = listOf(
AttestationSupportedCheckFingerprint,
BootloaderCheckFingerprint,
RootCheckFingerprint
RootCheckFingerprint,
).returnEarly(true)
}

View File

@ -9,5 +9,5 @@ internal object AttestationSupportedCheckFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.name == "attestationSupportCheck" &&
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
}
},
)

View File

@ -9,5 +9,5 @@ internal object BootloaderCheckFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.name == "bootloaderCheck" &&
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
}
},
)

View File

@ -9,5 +9,5 @@ internal object RootCheckFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.name == "rootCheck" &&
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
}
},
)

View File

@ -10,11 +10,11 @@ import app.revanced.patches.idaustria.detection.signature.fingerprints.SpoofSign
@Patch(
name = "Spoof signature",
description = "Spoofs the signature of the app.",
compatiblePackages = [CompatiblePackage("at.gv.oe.app")]
compatiblePackages = [CompatiblePackage("at.gv.oe.app")],
)
@Suppress("unused")
object SpoofSignaturePatch : BytecodePatch(
setOf(SpoofSignatureFingerprint)
setOf(SpoofSignatureFingerprint),
) {
private const val EXPECTED_SIGNATURE =
"OpenSSLRSAPublicKey{modulus=ac3e6fd6050aa7e0d6010ae58190404cd89a56935b44f6fee" +
@ -35,7 +35,7 @@ object SpoofSignaturePatch : BytecodePatch(
"""
const-string v0, "$EXPECTED_SIGNATURE"
return-object v0
"""
""",
)
}
}

View File

@ -9,5 +9,5 @@ internal object SpoofSignatureFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE.value,
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/SL2Step1Task;") && methodDef.name == "getPubKey"
}
},
)

View File

@ -1,20 +1,20 @@
package app.revanced.patches.inshorts.ad
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.inshorts.ad.fingerprints.InshortsAdsFingerprint
import app.revanced.util.exception
@Patch(
name = "Hide ads",
compatiblePackages = [CompatiblePackage("com.nis.app")]
compatiblePackages = [CompatiblePackage("com.nis.app")],
)
@Suppress("unused")
object HideAdsPatch : BytecodePatch(
setOf(InshortsAdsFingerprint)
setOf(InshortsAdsFingerprint),
) {
override fun execute(context: BytecodeContext) {
InshortsAdsFingerprint.result?.let { result ->
@ -23,7 +23,7 @@ object HideAdsPatch : BytecodePatch(
0,
"""
return-void
"""
""",
)
}
} ?: throw InshortsAdsFingerprint.exception

View File

@ -1,6 +1,5 @@
package app.revanced.patches.instagram.patches.ads.timeline
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@ -15,21 +14,23 @@ import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.Gene
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.MediaAdFingerprint
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.PaidPartnershipAdFingerprint
import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.ShoppingAdFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Hide timeline ads",
description = "Removes ads from the timeline.",
compatiblePackages = [CompatiblePackage("com.instagram.android", ["275.0.0.27.98"])]
compatiblePackages = [CompatiblePackage("com.instagram.android", ["275.0.0.27.98"])],
)
@Suppress("unused")
object HideTimelineAdsPatch : BytecodePatch(
setOf(
ShowAdFingerprint,
MediaFingerprint,
PaidPartnershipAdFingerprint // Unlike the other ads this one is resolved from all classes.
)
// Unlike the other ads this one is resolved from all classes.
PaidPartnershipAdFingerprint,
),
) {
override fun execute(context: BytecodeContext) {
// region Resolve required methods to check for ads.
@ -80,8 +81,9 @@ object HideTimelineAdsPatch : BytecodePatch(
checkForAdInstructions,
ExternalLabel(
returnFalseLabel,
mutableMethod.getInstruction(mutableMethod.implementation!!.instructions.size - 2 /* return false = ad */)
)
// return false = ad
mutableMethod.getInstruction(mutableMethod.implementation!!.instructions.size - 2),
),
)
// endregion
@ -92,7 +94,7 @@ object HideTimelineAdsPatch : BytecodePatch(
addInstructionsWithLabels(
jumpIndex + 1,
"if-nez v$freeRegister, :start_check",
ExternalLabel("start_check", getInstruction(insertIndex))
ExternalLabel("start_check", getInstruction(insertIndex)),
)
}.removeInstruction(jumpIndex)

View File

@ -3,5 +3,5 @@ package app.revanced.patches.instagram.patches.ads.timeline.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object MediaFingerprint : MethodFingerprint(
strings = listOf("force_overlay", "Media#updateFields", "live_reels_metadata")
strings = listOf("force_overlay", "Media#updateFields", "live_reels_metadata"),
)

View File

@ -12,7 +12,7 @@ internal object GenericMediaAdFingerprint : MediaAdFingerprint(
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
)
),
) {
override fun toString() = result!!.method.toString()
}

View File

@ -12,13 +12,13 @@ internal abstract class MediaAdFingerprint(
accessFlags: Int? = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters: Iterable<String>? = listOf(),
opcodes: Iterable<Opcode>?,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
) : MethodFingerprint(
returnType,
accessFlags,
parameters,
opcodes,
customFingerprint = customFingerprint
customFingerprint = customFingerprint,
) {
abstract override fun toString(): String
}

View File

@ -12,11 +12,11 @@ internal object PaidPartnershipAdFingerprint : MediaAdFingerprint(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IPUT_BOOLEAN,
Opcode.IPUT_BOOLEAN
Opcode.IPUT_BOOLEAN,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("ClipsEditMetadataController;")
}
},
) {
override fun toString() = result!!.let {
val adCheckIndex = it.scanResult.patternScanResult!!.startIndex

View File

@ -15,7 +15,7 @@ internal object ShoppingAdFingerprint : MediaAdFingerprint(
Opcode.MOVE_RESULT,
Opcode.XOR_INT_LIT8,
Opcode.IF_EQZ,
)
),
) {
override fun toString() = result!!.method.toString()
}

View File

@ -7,14 +7,13 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.irplus.ad.fingerprints.IrplusAdsFingerprint
@Patch(
name = "Remove ads",
compatiblePackages = [CompatiblePackage("net.binarymode.android.irplus")]
compatiblePackages = [CompatiblePackage("net.binarymode.android.irplus")],
)
@Suppress("unused")
object RemoveAdsPatch : BytecodePatch(
setOf(IrplusAdsFingerprint)
setOf(IrplusAdsFingerprint),
) {
override fun execute(context: BytecodeContext) {
val method = IrplusAdsFingerprint.result!!.mutableMethod

View File

@ -8,5 +8,5 @@ internal object IrplusAdsFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "Z"),
strings = listOf("TAGGED")
strings = listOf("TAGGED"),
)

View File

@ -1,20 +1,20 @@
package app.revanced.patches.lightroom.misc.login
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.lightroom.misc.login.fingerprints.IsLoggedInFingerprint
import app.revanced.util.exception
@Patch(
name = "Disable mandatory login",
compatiblePackages = [CompatiblePackage("com.adobe.lrmobile")]
compatiblePackages = [CompatiblePackage("com.adobe.lrmobile")],
)
@Suppress("unused")
object DisableMandatoryLoginPatch : BytecodePatch(
setOf(IsLoggedInFingerprint)
setOf(IsLoggedInFingerprint),
) {
override fun execute(context: BytecodeContext) {
IsLoggedInFingerprint.result?.mutableMethod?.apply {

View File

@ -14,6 +14,6 @@ internal object IsLoggedInFingerprint : MethodFingerprint(
Opcode.SGET_OBJECT,
Opcode.IF_NE,
Opcode.CONST_4,
Opcode.GOTO
)
Opcode.GOTO,
),
)

View File

@ -1,20 +1,20 @@
package app.revanced.patches.lightroom.misc.premium
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.lightroom.misc.premium.fingerprints.HasPurchasedFingerprint
import app.revanced.util.exception
@Patch(
name = "Unlock premium",
compatiblePackages = [CompatiblePackage("com.adobe.lrmobile")]
compatiblePackages = [CompatiblePackage("com.adobe.lrmobile")],
)
@Suppress("unused")
object UnlockPremiumPatch : BytecodePatch(
setOf(HasPurchasedFingerprint)
setOf(HasPurchasedFingerprint),
) {
override fun execute(context: BytecodeContext) {
// Set hasPremium = true.

View File

@ -14,5 +14,5 @@ internal object HasPurchasedFingerprint : MethodFingerprint(
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST_4,
)
),
)

View File

@ -1,15 +1,15 @@
package app.revanced.patches.memegenerator.detection.license
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.memegenerator.detection.license.fingerprints.LicenseValidationFingerprint
import app.revanced.util.exception
@Patch(description = "Disables Firebase license validation.")
object LicenseValidationPatch : BytecodePatch(
setOf(LicenseValidationFingerprint)
setOf(LicenseValidationFingerprint),
) {
override fun execute(context: BytecodeContext) {
LicenseValidationFingerprint.result?.apply {
@ -18,7 +18,7 @@ object LicenseValidationPatch : BytecodePatch(
"""
const/4 p0, 0x1
return p0
"""
""",
)
} ?: throw LicenseValidationFingerprint.exception
}

View File

@ -19,6 +19,6 @@ internal object LicenseValidationFingerprint : MethodFingerprint(
Opcode.CONST_4,
Opcode.RETURN,
Opcode.CONST_4,
Opcode.RETURN
)
Opcode.RETURN,
),
)

View File

@ -1,15 +1,15 @@
package app.revanced.patches.memegenerator.detection.signature
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.memegenerator.detection.signature.fingerprints.VerifySignatureFingerprint
import app.revanced.util.exception
@Patch(description = "Disables detection of incorrect signature.")
object SignatureVerificationPatch : BytecodePatch(
setOf(VerifySignatureFingerprint)
setOf(VerifySignatureFingerprint),
) {
override fun execute(context: BytecodeContext) {
VerifySignatureFingerprint.result?.apply {
@ -18,7 +18,7 @@ object SignatureVerificationPatch : BytecodePatch(
"""
const/4 p0, 0x1
return p0
"""
""",
)
} ?: throw VerifySignatureFingerprint.exception
}

View File

@ -1,8 +1,8 @@
package app.revanced.patches.memegenerator.detection.signature.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@ -30,6 +30,6 @@ internal object VerifySignatureFingerprint : MethodFingerprint(
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
Opcode.ADD_INT_LIT8
Opcode.ADD_INT_LIT8,
),
)

View File

@ -1,6 +1,5 @@
package app.revanced.patches.memegenerator.misc.pro
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
@ -9,35 +8,38 @@ import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.memegenerator.detection.license.LicenseValidationPatch
import app.revanced.patches.memegenerator.detection.signature.SignatureVerificationPatch
import app.revanced.patches.memegenerator.misc.pro.fingerprints.IsFreeVersionFingerprint
import app.revanced.util.exception
@Patch(
name = "Unlock pro",
dependencies = [
SignatureVerificationPatch::class,
LicenseValidationPatch::class
LicenseValidationPatch::class,
],
compatiblePackages = [
CompatiblePackage(
"com.zombodroid.MemeGenerator", [
"com.zombodroid.MemeGenerator",
[
"4.6364",
"4.6370",
"4.6375",
"4.6377"
]
)
]
"4.6377",
],
),
],
)
@Suppress("unused")
object UnlockProVersionPatch : BytecodePatch(
setOf(IsFreeVersionFingerprint)
setOf(IsFreeVersionFingerprint),
) {
override fun execute(context: BytecodeContext) {
IsFreeVersionFingerprint.result?.apply {
mutableMethod.replaceInstructions(0,
mutableMethod.replaceInstructions(
0,
"""
sget-object p0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
return-object p0
"""
""",
)
} ?: throw IsFreeVersionFingerprint.exception
}

View File

@ -17,6 +17,6 @@ internal object IsFreeVersionFingerprint : MethodFingerprint(
Opcode.CONST_STRING,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ
)
Opcode.IF_EQZ,
),
)

View File

@ -8,11 +8,10 @@ internal object LoadInboxAdsFingerprint : MethodFingerprint(
returnType = "V",
strings = listOf(
"ads_load_begin",
"inbox_ads_fetch_start"
"inbox_ads_fetch_start",
),
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/facebook/messaging/business/inboxads/plugins/inboxads/itemsupplier/InboxAdsItemSupplierImplementation;"
}
},
)

View File

@ -1,21 +1,21 @@
package app.revanced.patches.messenger.ads.inbox.patch
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.messenger.ads.inbox.fingerprints.LoadInboxAdsFingerprint
import app.revanced.util.exception
@Patch(
name = "Hide inbox ads",
description = "Hides ads in inbox.",
compatiblePackages = [CompatiblePackage("com.facebook.orca")]
compatiblePackages = [CompatiblePackage("com.facebook.orca")],
)
@Suppress("unused")
object HideInboxAdsPatch : BytecodePatch(
setOf(LoadInboxAdsFingerprint)
setOf(LoadInboxAdsFingerprint),
) {
override fun execute(context: BytecodeContext) {
LoadInboxAdsFingerprint.result?.mutableMethod?.apply {
@ -23,4 +23,3 @@ object HideInboxAdsPatch : BytecodePatch(
} ?: throw LoadInboxAdsFingerprint.exception
}
}

View File

@ -8,8 +8,8 @@ internal object SendTypingIndicatorFingerprint : MethodFingerprint(
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "run" && classDef.fields.any {
it.name == "__redex_internal_original_name"
&& (it.initialValue as? DexBackedStringEncodedValue)?.value == "ConversationTypingContext\$sendActiveStateRunnable\$1"
}
it.name == "__redex_internal_original_name" &&
(it.initialValue as? DexBackedStringEncodedValue)?.value == "ConversationTypingContext\$sendActiveStateRunnable\$1"
}
},
)

View File

@ -13,6 +13,6 @@ internal object SwitchMessangeInputEmojiButtonFingerprint : MethodFingerprint(
Opcode.CONST_STRING,
Opcode.GOTO,
Opcode.CONST_STRING,
Opcode.GOTO
)
Opcode.GOTO,
),
)

View File

@ -1,6 +1,5 @@
package app.revanced.patches.messenger.inputfield.patch
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
@ -8,16 +7,17 @@ import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.messenger.inputfield.fingerprints.SwitchMessangeInputEmojiButtonFingerprint
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Disable switching emoji to sticker",
description = "Disables switching from emoji to sticker search mode in message input field.",
compatiblePackages = [CompatiblePackage("com.facebook.orca")]
compatiblePackages = [CompatiblePackage("com.facebook.orca")],
)
@Suppress("unused")
object DisableSwitchingEmojiToStickerPatch : BytecodePatch(
setOf(SwitchMessangeInputEmojiButtonFingerprint)
setOf(SwitchMessangeInputEmojiButtonFingerprint),
) {
override fun execute(context: BytecodeContext) {
SwitchMessangeInputEmojiButtonFingerprint.result?.let {
@ -28,7 +28,7 @@ object DisableSwitchingEmojiToStickerPatch : BytecodePatch(
replaceInstruction(
setStringIndex,
"const-string v$targetRegister, \"expression\""
"const-string v$targetRegister, \"expression\"",
)
}
} ?: throw SwitchMessangeInputEmojiButtonFingerprint.exception

View File

@ -1,21 +1,21 @@
package app.revanced.patches.messenger.inputfield.patch
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.messenger.inputfield.fingerprints.SendTypingIndicatorFingerprint
import app.revanced.util.exception
@Patch(
name = "Disable typing indicator",
description = "Disables the indicator while typing a message.",
compatiblePackages = [CompatiblePackage("com.facebook.orca")]
compatiblePackages = [CompatiblePackage("com.facebook.orca")],
)
@Suppress("unused")
object DisableTypingIndicatorPatch : BytecodePatch(
setOf(SendTypingIndicatorFingerprint)
setOf(SendTypingIndicatorFingerprint),
) {
override fun execute(context: BytecodeContext) {
SendTypingIndicatorFingerprint.result?.mutableMethod?.replaceInstruction(0, "return-void")

View File

@ -9,11 +9,11 @@ import app.revanced.patches.moneymanager.fingerprints.UnlockProFingerprint
@Patch(
name = "Unlock pro",
compatiblePackages = [CompatiblePackage("com.ithebk.expensemanager")]
compatiblePackages = [CompatiblePackage("com.ithebk.expensemanager")],
)
@Suppress("unused")
object UnlockProPatch : BytecodePatch(
setOf(UnlockProFingerprint)
setOf(UnlockProFingerprint),
) {
override fun execute(context: BytecodeContext) {
UnlockProFingerprint.result!!.mutableMethod.addInstructions(
@ -21,7 +21,7 @@ object UnlockProPatch : BytecodePatch(
"""
const/4 v0, 0x1
return v0
"""
""",
)
}
}

View File

@ -11,9 +11,9 @@ internal object UnlockProFingerprint : MethodFingerprint(
parameters = listOf("L"),
opcodes = listOf(
Opcode.IGET_BOOLEAN,
Opcode.RETURN
Opcode.RETURN,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("MainActivity;")
}
},
)

View File

@ -11,11 +11,11 @@ import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsFingerp
@Patch(
name = "Music video ads",
description = "Removes ads in the music player.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object MusicVideoAdsPatch : BytecodePatch(
setOf(ShowMusicVideoAdsConstructorFingerprint)
setOf(ShowMusicVideoAdsConstructorFingerprint),
) {
override fun execute(context: BytecodeContext) {
ShowMusicVideoAdsFingerprint.resolve(context, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef)
@ -26,7 +26,7 @@ object MusicVideoAdsPatch : BytecodePatch(
result.scanResult.patternScanResult!!.startIndex,
"""
const/4 p1, 0x0
"""
""",
)
}
}

View File

@ -1,13 +1,16 @@
package app.revanced.patches.music.ad.video.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
internal object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf(
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "L", "L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
@ -22,6 +25,6 @@ internal object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint(
Opcode.IPUT_OBJECT,
Opcode.CONST_4,
Opcode.IPUT_BOOLEAN,
Opcode.RETURN_VOID
)
Opcode.RETURN_VOID,
),
)

View File

@ -6,9 +6,12 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object ShowMusicVideoAdsFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), listOf(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("Z"),
listOf(
Opcode.IPUT_BOOLEAN,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
)
Opcode.RETURN_VOID,
),
)

View File

@ -12,11 +12,11 @@ import com.android.tools.smali.dexlib2.Opcode
@Patch(
name = "Codecs unlock",
description = "Adds more audio codec options. The new audio codecs usually result in better audio quality.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object CodecsUnlockPatch : BytecodePatch(
setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint)
setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint),
) {
override fun execute(context: BytecodeContext) {
val codecsLockResult = CodecsLockFingerprint.result!!
@ -41,7 +41,7 @@ object CodecsUnlockPatch : BytecodePatch(
implementation.replaceInstruction(
instructionIndex,
"invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction()
"invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction(),
)
}
}

View File

@ -1,15 +1,17 @@
package app.revanced.patches.music.audio.codecs.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
internal object AllCodecsReferenceFingerprint : MethodFingerprint(
"J", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("L"), listOf(
"J",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf("L"),
listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC,
@ -47,6 +49,7 @@ internal object AllCodecsReferenceFingerprint : MethodFingerprint(
Opcode.MOVE_EXCEPTION,
Opcode.INVOKE_SUPER,
Opcode.MOVE_RESULT_WIDE,
Opcode.RETURN_WIDE
), listOf("itag")
Opcode.RETURN_WIDE,
),
listOf("itag"),
)

View File

@ -1,15 +1,16 @@
package app.revanced.patches.music.audio.codecs.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
internal object CodecsLockFingerprint : MethodFingerprint(
"L", AccessFlags.PUBLIC or AccessFlags.STATIC, opcodes = listOf(
"L",
AccessFlags.PUBLIC or AccessFlags.STATIC,
opcodes = listOf(
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
@ -23,7 +24,7 @@ internal object CodecsLockFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_OBJECT
Opcode.RETURN_OBJECT,
),
strings = listOf("eac3_supported")
strings = listOf("eac3_supported"),
)

View File

@ -1,21 +1,21 @@
package app.revanced.patches.music.audio.exclusiveaudio
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AllowExclusiveAudioPlaybackFingerprint
import app.revanced.util.exception
@Patch(
name = "Exclusive audio playback",
description = "Enables the option to play audio without video.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object ExclusiveAudioPatch : BytecodePatch(
setOf(AllowExclusiveAudioPlaybackFingerprint)
setOf(AllowExclusiveAudioPlaybackFingerprint),
) {
override fun execute(context: BytecodeContext) {
AllowExclusiveAudioPlaybackFingerprint.result?.mutableMethod?.apply {
@ -24,7 +24,7 @@ object ExclusiveAudioPatch : BytecodePatch(
"""
const/4 v0, 0x1
return v0
"""
""",
)
} ?: throw AllowExclusiveAudioPlaybackFingerprint.exception
}

View File

@ -20,6 +20,6 @@ internal object AllowExclusiveAudioPlaybackFingerprint: MethodFingerprint(
Opcode.GOTO,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.RETURN
)
Opcode.RETURN,
),
)

View File

@ -1,6 +1,5 @@
package app.revanced.patches.music.interaction.permanentrepeat
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@ -9,16 +8,17 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.interaction.permanentrepeat.fingerprints.RepeatTrackFingerprint
import app.revanced.util.exception
@Patch(
name = "Permanent repeat",
description = "Permanently remember your repeating preference even if the playlist ends or another track is played.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
use = false
use = false,
)
@Suppress("unused")
object PermanentRepeatPatch : BytecodePatch(
setOf(RepeatTrackFingerprint)
setOf(RepeatTrackFingerprint),
) {
override fun execute(context: BytecodeContext) {
RepeatTrackFingerprint.result?.let {
@ -29,7 +29,7 @@ object PermanentRepeatPatch : BytecodePatch(
addInstructionsWithLabels(
startIndex,
"goto :repeat",
ExternalLabel("repeat", getInstruction(repeatIndex))
ExternalLabel("repeat", getInstruction(repeatIndex)),
)
}
} ?: throw RepeatTrackFingerprint.exception

View File

@ -17,6 +17,6 @@ internal object RepeatTrackFingerprint : MethodFingerprint(
Opcode.SGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ
)
Opcode.IF_NEZ,
),
)

View File

@ -1,23 +1,22 @@
package app.revanced.patches.music.interaction.permanentshuffle
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.interaction.permanentshuffle.fingerprints.DisableShuffleFingerprint
import app.revanced.util.exception
@Patch(
name = "Permanent shuffle",
description = "Permanently remember your shuffle preference " +
"even if the playlist ends or another track is played.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
use = false
use = false,
)
@Suppress("unused")
object PermanentShuffleTogglePatch : BytecodePatch(setOf(DisableShuffleFingerprint)) {
object PermanentShufflePatch : BytecodePatch(setOf(DisableShuffleFingerprint)) {
override fun execute(context: BytecodeContext) {
DisableShuffleFingerprint.result?.mutableMethod?.addInstruction(0, "return-void")
?: throw DisableShuffleFingerprint.exception

View File

@ -15,6 +15,6 @@ internal object DisableShuffleFingerprint : MethodFingerprint(
Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL
)
Opcode.INVOKE_VIRTUAL,
),
)

View File

@ -12,11 +12,11 @@ import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction11x
name = "Compact header",
description = "Hides the music category bar at the top of the homepage.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
use = false
use = false,
)
@Suppress("unused")
object CompactHeaderPatch : BytecodePatch(
setOf(CompactHeaderConstructorFingerprint)
setOf(CompactHeaderConstructorFingerprint),
) {
override fun execute(context: BytecodeContext) {
val result = CompactHeaderConstructorFingerprint.result!!
@ -25,10 +25,11 @@ object CompactHeaderPatch : BytecodePatch(
val insertIndex = result.scanResult.patternScanResult!!.endIndex
val register = (method.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA
method.addInstructions(
insertIndex, """
const/16 v2, 0x8
invoke-virtual {v${register}, v2}, Landroid/view/View;->setVisibility(I)V
insertIndex,
"""
const/16 v2, 0x8
invoke-virtual {v$register, v2}, Landroid/view/View;->setVisibility(I)V
""",
)
}
}

View File

@ -6,7 +6,10 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object CompactHeaderConstructorFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L", "L"), listOf(
"V",
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
listOf("L", "L", "L", "L", "L"),
listOf(
Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
@ -18,6 +21,6 @@ internal object CompactHeaderConstructorFingerprint : MethodFingerprint(
Opcode.CONST_4,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST
)
Opcode.CHECK_CAST,
),
)

View File

@ -1,18 +1,17 @@
package app.revanced.patches.music.layout.minimizedplayback
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint
import app.revanced.util.exception
@Patch(
name = "Minimized playback music",
description = "Enables minimized playback on Kids music.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object MinimizedPlaybackPatch : BytecodePatch(setOf(MinimizedPlaybackManagerFingerprint)) {
@ -21,6 +20,6 @@ object MinimizedPlaybackPatch : BytecodePatch(setOf(MinimizedPlaybackManagerFing
0,
"""
return-void
"""
""",
) ?: throw MinimizedPlaybackManagerFingerprint.exception
}

View File

@ -22,5 +22,5 @@ internal object MinimizedPlaybackManagerFingerprint : MethodFingerprint(
Opcode.CONST_4,
Opcode.IF_NE,
Opcode.IPUT_BOOLEAN,
)
),
)

View File

@ -12,7 +12,7 @@ import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumPare
@Patch(
name = "Hide get premium",
description = "Removes all \"Get Premium\" evidences from the avatar menu.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object HideGetPremiumPatch : BytecodePatch(setOf(HideGetPremiumParentFingerprint)) {
@ -27,7 +27,7 @@ object HideGetPremiumPatch : BytecodePatch(setOf(HideGetPremiumParentFingerprint
startIndex,
"""
const/4 v1, 0x0
"""
""",
)
val result = HideGetPremiumFingerprint.result!!
@ -36,7 +36,7 @@ object HideGetPremiumPatch : BytecodePatch(setOf(HideGetPremiumParentFingerprint
startIndex,
"""
const/16 v0, 0x8
"""
""",
)
}
}

View File

@ -6,11 +6,14 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object HideGetPremiumFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
listOf(
Opcode.IF_NEZ,
Opcode.CONST_16,
Opcode.GOTO,
Opcode.NOP,
Opcode.INVOKE_VIRTUAL
)
Opcode.INVOKE_VIRTUAL,
),
)

View File

@ -6,14 +6,17 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal object HideGetPremiumParentFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
listOf(
Opcode.IGET_BOOLEAN,
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC
Opcode.INVOKE_STATIC,
),
listOf("FEmusic_history"),
)

View File

@ -12,15 +12,14 @@ import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@Patch(
name = "Remove upgrade button",
description = "Removes the upgrade tab from the pivot bar.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object RemoveUpgradeButtonPatch : BytecodePatch(
setOf(PivotBarConstructorFingerprint)
setOf(PivotBarConstructorFingerprint),
) {
override fun execute(context: BytecodeContext) {
val result = PivotBarConstructorFingerprint.result!!
@ -39,19 +38,20 @@ object RemoveUpgradeButtonPatch : BytecodePatch(
iput-object v0, v$register, $pivotBarElementFieldRef
""".toInstructions().toMutableList()
val endIndex = result.scanResult.patternScanResult!!.endIndex
// replace the instruction to retain the label at given index
implementation.replaceInstruction(
endIndex - 1, instructionList[0] // invoke-interface
endIndex - 1,
instructionList[0], // invoke-interface
)
// do not forget to remove this instruction since we added it already
instructionList.removeFirst()
val exitInstruction = instructionList.last() // iput-object
implementation.addInstruction(
endIndex, exitInstruction
endIndex,
exitInstruction,
)
// do not forget to remove this instruction since we added it already
instructionList.removeLast()
@ -60,12 +60,16 @@ object RemoveUpgradeButtonPatch : BytecodePatch(
instructionList.add(
2, // if-le
BuilderInstruction22t(
Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(endIndex)
)
Opcode.IF_LE,
1,
2,
implementation.newLabelForIndex(endIndex),
),
)
implementation.addInstructions(
endIndex, instructionList
endIndex,
instructionList,
)
}
}

View File

@ -1,12 +1,11 @@
package app.revanced.patches.music.layout.upgradebutton.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
internal object PivotBarConstructorFingerprint : MethodFingerprint(
"V",
@ -57,6 +56,6 @@ internal object PivotBarConstructorFingerprint : MethodFingerprint(
Opcode.GOTO,
Opcode.NOP,
Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID
)
Opcode.RETURN_VOID,
),
)

View File

@ -1,28 +1,28 @@
package app.revanced.patches.music.misc.androidauto
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.misc.androidauto.fingerprints.CheckCertificateFingerprint
import app.revanced.util.exception
@Patch(
name = "Bypass certificate checks",
description = "Bypasses certificate checks which prevent YouTube Music from working on Android Auto.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object BypassCertificateChecksPatch : BytecodePatch(setOf(CheckCertificateFingerprint)) {
override fun execute(context: BytecodeContext) {
CheckCertificateFingerprint.result?.apply {
mutableMethod.addInstructions(
0, """
0,
"""
const/4 v0, 0x1
return v0
"""
""",
)
} ?: throw CheckCertificateFingerprint.exception
}

View File

@ -8,5 +8,5 @@ internal object CheckCertificateFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Z",
parameters = listOf("Ljava/lang/String;"),
strings = listOf("X509", "Failed to get certificate.")
strings = listOf("X509", "Failed to get certificate."),
)

View File

@ -4,10 +4,10 @@ import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME
import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME
import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption
import app.revanced.patches.music.misc.gms.fingerprints.*
import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint
import app.revanced.patches.music.misc.integrations.IntegrationsPatch
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint
import app.revanced.patches.shared.fingerprints.CastContextFetchFingerprint
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
@Suppress("unused")
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
@ -32,7 +32,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint,
PrimeMethodFingerprint,
)
),
) {
override val gmsCoreVendor by gmsCoreVendorOption
}

View File

@ -7,5 +7,5 @@ import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportResourcePatch
object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
fromPackageName = MUSIC_PACKAGE_NAME,
toPackageName = REVANCED_MUSIC_PACKAGE_NAME,
spoofedPackageSignature = "afb0fed5eeaebdd86f56a97742f4b6b33ef59875"
spoofedPackageSignature = "afb0fed5eeaebdd86f56a97742f4b6b33ef59875",
)

View File

@ -1,8 +1,7 @@
package app.revanced.patches.music.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object CastDynamiteModuleFingerprint : MethodFingerprint(
strings = listOf("com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl")
strings = listOf("com.google.android.gms.cast.framework.internal.CastDynamiteModuleImpl"),
)

View File

@ -1,8 +1,7 @@
package app.revanced.patches.music.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object CastDynamiteModuleV2Fingerprint : MethodFingerprint(
strings = listOf("Failed to load module via V2: ")
strings = listOf("Failed to load module via V2: "),
)

View File

@ -13,6 +13,6 @@ internal object GooglePlayUtilityFingerprint : MethodFingerprint(
"MetadataValueReader",
"GooglePlayServicesUtil",
"com.android.vending",
"android.hardware.type.embedded"
)
"android.hardware.type.embedded",
),
)

View File

@ -1,8 +1,7 @@
package app.revanced.patches.music.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint
internal object PrimeMethodFingerprint : MethodFingerprint(
strings = listOf("com.google.android.GoogleCamera", "com.android.vending")
strings = listOf("com.google.android.GoogleCamera", "com.android.vending"),
)

View File

@ -12,7 +12,7 @@ internal object ApplicationInitFingerprint : IntegrationsFingerprint(
Opcode.INVOKE_STATIC,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL
Opcode.INVOKE_VIRTUAL,
),
strings = listOf("activity"),
customFingerprint = { methodDef, _ -> methodDef.name == "onCreate" },

View File

@ -1,26 +1,26 @@
package app.revanced.patches.music.premium.backgroundplay
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.music.premium.backgroundplay.fingerprints.BackgroundPlaybackDisableFingerprint
import app.revanced.util.exception
@Patch(
name = "Background play",
description = "Enables playing music in the background.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
)
@Suppress("unused")
object BackgroundPlayPatch : BytecodePatch(setOf(BackgroundPlaybackDisableFingerprint)) {
override fun execute(context: BytecodeContext) =
BackgroundPlaybackDisableFingerprint.result?.mutableMethod?.addInstructions(
0, """
0,
"""
const/4 v0, 0x1
return v0
"""
""",
) ?: throw BackgroundPlaybackDisableFingerprint.exception
}

View File

@ -1,15 +1,17 @@
package app.revanced.patches.music.premium.backgroundplay.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
internal object BackgroundPlaybackDisableFingerprint : MethodFingerprint(
"Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf(
"Z",
AccessFlags.PUBLIC or AccessFlags.STATIC,
listOf("L"),
listOf(
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.IGET,
@ -38,6 +40,6 @@ internal object BackgroundPlaybackDisableFingerprint : MethodFingerprint(
Opcode.CONST_4,
Opcode.RETURN,
Opcode.RETURN,
Opcode.RETURN
)
Opcode.RETURN,
),
)

View File

@ -1,16 +1,16 @@
package app.revanced.patches.myexpenses.misc.pro
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.myexpenses.misc.pro.fingerprints.IsEnabledFingerprint
import app.revanced.util.exception
@Patch(
name = "Unlock pro",
compatiblePackages = [CompatiblePackage("org.totschnig.myexpenses", ["3.4.9"])]
compatiblePackages = [CompatiblePackage("org.totschnig.myexpenses", ["3.4.9"])],
)
@Suppress("unused")
object UnlockProPatch : BytecodePatch(setOf(IsEnabledFingerprint)) {
@ -19,7 +19,6 @@ object UnlockProPatch : BytecodePatch(setOf(IsEnabledFingerprint)) {
"""
const/4 v0, 0x1
return v0
"""
""",
) ?: throw IsEnabledFingerprint.exception
}

View File

@ -4,5 +4,5 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
internal object IsEnabledFingerprint : MethodFingerprint(
"Z",
strings = listOf("feature", "feature.licenceStatus")
strings = listOf("feature", "feature.licenceStatus"),
)

View File

@ -12,11 +12,11 @@ import app.revanced.util.exception
@Patch(
name = "Hide ads",
description = "Hides most of the ads across the app.",
compatiblePackages = [CompatiblePackage("com.myfitnesspal.android")]
compatiblePackages = [CompatiblePackage("com.myfitnesspal.android")],
)
@Suppress("unused")
object HideAdsPatch : BytecodePatch(
setOf(IsPremiumUseCaseImplFingerprint, MainActivityNavigateToNativePremiumUpsellFingerprint)
setOf(IsPremiumUseCaseImplFingerprint, MainActivityNavigateToNativePremiumUpsellFingerprint),
) {
override fun execute(context: BytecodeContext) {
// Overwrite the premium status specifically for ads.
@ -25,14 +25,14 @@ object HideAdsPatch : BytecodePatch(
"""
sget-object v0, Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;
return-object v0
"""
""",
) ?: throw IsPremiumUseCaseImplFingerprint.exception
// 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.
MainActivityNavigateToNativePremiumUpsellFingerprint.result?.mutableMethod?.replaceInstructions(
0,
"return-void"
"return-void",
) ?: throw MainActivityNavigateToNativePremiumUpsellFingerprint.exception
}
}

View File

@ -7,5 +7,5 @@ object IsPremiumUseCaseImplFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, classDef ->
classDef.type.endsWith("IsPremiumUseCaseImpl;") && methodDef.name == "doWork"
}
},
)

View File

@ -9,5 +9,5 @@ object MainActivityNavigateToNativePremiumUpsellFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
customFingerprint = { methodDef, classDef ->
classDef.type.endsWith("MainActivity;") && methodDef.name == "navigateToNativePremiumUpsell"
}
},
)

View File

@ -1,25 +1,25 @@
package app.revanced.patches.nfctoolsse.misc.pro
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.nfctoolsse.misc.pro.fingerprints.IsLicenseRegisteredFingerprint
import app.revanced.util.exception
@Patch(
name = "Unlock pro",
compatiblePackages = [CompatiblePackage("com.wakdev.apps.nfctools.se")]
compatiblePackages = [CompatiblePackage("com.wakdev.apps.nfctools.se")],
)
@Suppress("unused")
object UnlockProPatch : BytecodePatch(setOf(IsLicenseRegisteredFingerprint)) {
override fun execute(context: BytecodeContext) = IsLicenseRegisteredFingerprint.result?.mutableMethod
?.addInstructions(
0, """
0,
"""
const/4 v0, 0x1
return v0
"""
""",
) ?: throw IsLicenseRegisteredFingerprint.exception
}

View File

@ -6,5 +6,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object IsLicenseRegisteredFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC.value,
strings = listOf("kLicenseCheck")
strings = listOf("kLicenseCheck"),
)

View File

@ -1,16 +1,16 @@
package app.revanced.patches.nyx.misc.pro
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.nyx.misc.pro.fingerprints.CheckProFingerprint
import app.revanced.util.exception
@Patch(
name = "Unlock pro",
compatiblePackages = [CompatiblePackage("com.awedea.nyx", ["2.2.7"])]
compatiblePackages = [CompatiblePackage("com.awedea.nyx", ["2.2.7"])],
)
@Suppress("unused")
object UnlockProPatch : BytecodePatch(setOf(CheckProFingerprint)) {
@ -19,6 +19,6 @@ object UnlockProPatch : BytecodePatch(setOf(CheckProFingerprint)) {
"""
const/4 v0, 0x1
return v0
"""
""",
) ?: throw CheckProFingerprint.exception
}

View File

@ -5,5 +5,5 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
internal object CheckProFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("BillingManager;") && methodDef.name == "isProVersion"
}
},
)

View File

@ -1,6 +1,5 @@
package app.revanced.patches.photomath.detection.deviceid
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstructions
import app.revanced.patcher.patch.BytecodePatch
@ -8,23 +7,24 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.photomath.detection.deviceid.fingerprints.GetDeviceIdFingerprint
import app.revanced.patches.photomath.detection.signature.SignatureDetectionPatch
import app.revanced.util.exception
import kotlin.random.Random
@Patch(
name = "Spoof device ID",
description = "Spoofs device ID to mitigate manual bans by developers.",
dependencies = [SignatureDetectionPatch::class],
compatiblePackages = [CompatiblePackage("com.microblink.photomath", ["8.32.0"])]
compatiblePackages = [CompatiblePackage("com.microblink.photomath", ["8.32.0"])],
)
@Suppress("unused")
object SpoofDeviceIdPatch : BytecodePatch(
setOf(GetDeviceIdFingerprint)
setOf(GetDeviceIdFingerprint),
) {
override fun execute(context: BytecodeContext) = GetDeviceIdFingerprint.result?.mutableMethod?.replaceInstructions(
0,
"""
const-string v0, "${Random.nextLong().toString(16)}"
return-object v0
"""
""",
) ?: throw GetDeviceIdFingerprint.exception
}

Some files were not shown because too many files have changed in this diff Show More