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 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 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/PermanentShuffleTogglePatch; public static final field INSTANCE Lapp/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)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 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 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/UnlockProPatch; public static final field INSTANCE Lapp/revanced/patches/ticktick/misc/themeunlock/UnlockThemesPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)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", name = "Spoof Wi-Fi connection",
description = "Spoofs an existing Wi-Fi connection.", description = "Spoofs an existing Wi-Fi connection.",
use = false, use = false,
requiresIntegrations = true requiresIntegrations = true,
) )
@Suppress("unused") @Suppress("unused")
object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() { object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
@ -25,12 +25,12 @@ object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
classDef: ClassDef, classDef: ClassDef,
method: Method, method: Method,
instruction: Instruction, instruction: Instruction,
instructionIndex: Int instructionIndex: Int,
) = filterMapInstruction35c<MethodCall>( ) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX, INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef, classDef,
instruction, instruction,
instructionIndex instructionIndex,
) )
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) { override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
@ -38,14 +38,13 @@ object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex) methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
} }
// Information about method calls we want to replace // Information about method calls we want to replace
private enum class MethodCall( private enum class MethodCall(
override val definedClassName: String, override val definedClassName: String,
override val methodName: String, override val methodName: String,
override val methodParams: Array<String>, override val methodParams: Array<String>,
override val returnType: String, override val returnType: String,
): IMethodCall { ) : IMethodCall {
GetSystemService1( GetSystemService1(
"Landroid/content/Context;", "Landroid/content/Context;",
"getSystemService", "getSystemService",
@ -201,6 +200,6 @@ object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
"unregisterNetworkCallback", "unregisterNetworkCallback",
arrayOf("Landroid/app/PendingIntent;"), arrayOf("Landroid/app/PendingIntent;"),
"V", "V",
); ),
} }
} }

View File

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

View File

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

View File

@ -24,7 +24,7 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
@Suppress("unused") @Suppress("unused")
object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() { object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
private const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX = private const val INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/integrations/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch" "Lapp/revanced/integrations/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;" private const val INTEGRATIONS_CLASS_DESCRIPTOR = "$INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX;"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
@ -36,12 +36,12 @@ object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruc
classDef: ClassDef, classDef: ClassDef,
method: Method, method: Method,
instruction: Instruction, instruction: Instruction,
instructionIndex: Int instructionIndex: Int,
) = filterMapInstruction35c<MethodCall>( ) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX, INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef, classDef,
instruction, instruction,
instructionIndex instructionIndex,
) )
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) { override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
@ -54,8 +54,8 @@ object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruc
override val definedClassName: String, override val definedClassName: String,
override val methodName: String, override val methodName: String,
override val methodParams: Array<String>, override val methodParams: Array<String>,
override val returnType: String override val returnType: String,
): IMethodCall { ) : IMethodCall {
AddFlags( AddFlags(
"Landroid/view/Window;", "Landroid/view/Window;",
"addFlags", "addFlags",
@ -67,7 +67,7 @@ object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruc
"setFlags", "setFlags",
arrayOf("I", "I"), arrayOf("I", "I"),
"V", "V",
); ),
} }
} }
@ -76,7 +76,7 @@ private class ModifyLayoutParamsFlags : BaseTransformInstructionsPatch<Pair<Inst
classDef: ClassDef, classDef: ClassDef,
method: Method, method: Method,
instruction: Instruction, instruction: Instruction,
instructionIndex: Int instructionIndex: Int,
): Pair<Instruction22c, Int>? { ): Pair<Instruction22c, Int>? {
if (instruction.opcode != Opcode.IPUT) { if (instruction.opcode != Opcode.IPUT) {
return null return null
@ -85,9 +85,10 @@ private class ModifyLayoutParamsFlags : BaseTransformInstructionsPatch<Pair<Inst
val instruction22c = instruction as Instruction22c val instruction22c = instruction as Instruction22c
val fieldReference = instruction22c.reference as FieldReference val fieldReference = instruction22c.reference as FieldReference
if (fieldReference.definingClass != "Landroid/view/WindowManager\$LayoutParams;" if (fieldReference.definingClass != "Landroid/view/WindowManager\$LayoutParams;" ||
|| fieldReference.name != "flags" fieldReference.name != "flags" ||
|| fieldReference.type != "I") { fieldReference.type != "I"
) {
return null return null
} }
@ -100,7 +101,7 @@ private class ModifyLayoutParamsFlags : BaseTransformInstructionsPatch<Pair<Inst
mutableMethod.addInstructions( mutableMethod.addInstructions(
index, 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 com.android.tools.smali.dexlib2.util.MethodUtil
import java.util.* import java.util.*
@Patch( @Patch(
name = "Spoof SIM country", name = "Spoof SIM country",
description = "Spoofs country information returned by the SIM card provider.", description = "Spoofs country information returned by the SIM card provider.",
@ -46,14 +45,14 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
title, title,
"ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.", "ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.",
false, false,
validator = { it: String? -> it == null || it.uppercase() in countries.values } validator = { it: String? -> it == null || it.uppercase() in countries.values },
) )
override fun filterMap( override fun filterMap(
classDef: ClassDef, classDef: ClassDef,
method: Method, method: Method,
instruction: Instruction, instruction: Instruction,
instructionIndex: Int instructionIndex: Int,
): Pair<Int, String>? { ): Pair<Int, String>? {
if (instruction !is ReferenceInstruction) return null if (instruction !is ReferenceInstruction) return null
@ -73,12 +72,12 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
override fun transform( override fun transform(
mutableMethod: MutableMethod, mutableMethod: MutableMethod,
entry: Pair<Int, String> entry: Pair<Int, String>,
) = transformMethodCall(entry, mutableMethod) ) = transformMethodCall(entry, mutableMethod)
private fun transformMethodCall( private fun transformMethodCall(
entry: Pair<Int, String>, entry: Pair<Int, String>,
mutableMethod: MutableMethod mutableMethod: MutableMethod,
) { ) {
val (instructionIndex, methodCallValue) = entry val (instructionIndex, methodCallValue) = entry
@ -86,28 +85,28 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
mutableMethod.replaceInstruction( mutableMethod.replaceInstruction(
instructionIndex + 1, instructionIndex + 1,
"const-string v$register, \"$methodCallValue\"" "const-string v$register, \"$methodCallValue\"",
) )
} }
private enum class MethodCall( private enum class MethodCall(
val reference: MethodReference val reference: MethodReference,
) { ) {
NetworkCountryIso( NetworkCountryIso(
ImmutableMethodReference( ImmutableMethodReference(
"Landroid/telephony/TelephonyManager;", "Landroid/telephony/TelephonyManager;",
"getNetworkCountryIso", "getNetworkCountryIso",
emptyList(), emptyList(),
"Ljava/lang/String;" "Ljava/lang/String;",
) ),
), ),
SimCountryIso( SimCountryIso(
ImmutableMethodReference( ImmutableMethodReference(
"Landroid/telephony/TelephonyManager;", "Landroid/telephony/TelephonyManager;",
"getSimCountryIso", "getSimCountryIso",
emptyList(), emptyList(),
"Ljava/lang/String;" "Ljava/lang/String;",
) ),
) ),
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,5 @@
package app.revanced.patches.facebook.ads.story package app.revanced.patches.facebook.ads.story
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch 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.patcher.patch.annotation.Patch
import app.revanced.patches.facebook.ads.story.fingerprints.AdsInsertionFingerprint import app.revanced.patches.facebook.ads.story.fingerprints.AdsInsertionFingerprint
import app.revanced.patches.facebook.ads.story.fingerprints.FetchMoreAdsFingerprint import app.revanced.patches.facebook.ads.story.fingerprints.FetchMoreAdsFingerprint
import app.revanced.util.exception
@Patch( @Patch(
name = "Hide story ads", name = "Hide story ads",
description = "Hides the ads in the Facebook app stories.", description = "Hides the ads in the Facebook app stories.",
compatiblePackages = [CompatiblePackage("com.facebook.katana")] compatiblePackages = [CompatiblePackage("com.facebook.katana")],
) )
@Suppress("unused") @Suppress("unused")
object HideStoryAdsPatch : BytecodePatch( object HideStoryAdsPatch : BytecodePatch(
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint) setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint),
) { ) {
override fun execute(context: BytecodeContext) = override fun execute(context: BytecodeContext) =
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint).forEach { fingerprint -> 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 if (field.name != "__redex_internal_original_name") return@any false
(field.initialValue as? StringEncodedValue)?.value == fieldValue (field.initialValue as? StringEncodedValue)?.value == fieldValue
} }
} },
) )

View File

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

View File

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

View File

@ -7,5 +7,5 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object CreateKeyFingerprint : MethodFingerprint( internal object CreateKeyFingerprint : MethodFingerprint(
"Z", "Z",
accessFlags = AccessFlags.PUBLIC.value, 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 package app.revanced.patches.finanzonline.detection.root
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.finanzonline.detection.root.fingerprints.RootDetectionFingerprint import app.revanced.patches.finanzonline.detection.root.fingerprints.RootDetectionFingerprint
import app.revanced.util.exception
@Patch( @Patch(
name = "Remove root detection", name = "Remove root detection",
description = "Removes the check for root permissions.", description = "Removes the check for root permissions.",
compatiblePackages = [CompatiblePackage("at.gv.bmf.bmf2go")] compatiblePackages = [CompatiblePackage("at.gv.bmf.bmf2go")],
) )
@Suppress("unused") @Suppress("unused")
object RootDetectionPatch : BytecodePatch( object RootDetectionPatch : BytecodePatch(
setOf(RootDetectionFingerprint) setOf(RootDetectionFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
RootDetectionFingerprint.result?.mutableMethod?.addInstructions( RootDetectionFingerprint.result?.mutableMethod?.addInstructions(
@ -23,7 +23,7 @@ object RootDetectionPatch : BytecodePatch(
""" """
sget-object v0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean; sget-object v0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
return-object v0 return-object v0
""" """,
) ?: throw RootDetectionFingerprint.exception ) ?: throw RootDetectionFingerprint.exception
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,5 +4,5 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
internal object CheckProFingerprint : MethodFingerprint( internal object CheckProFingerprint : MethodFingerprint(
"Z", "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( @Patch(
name = "Remove root detection", name = "Remove root detection",
description = "Removes the check for root permissions and unlocked bootloader.", description = "Removes the check for root permissions and unlocked bootloader.",
compatiblePackages = [CompatiblePackage("at.gv.oe.app")] compatiblePackages = [CompatiblePackage("at.gv.oe.app")],
) )
@Suppress("unused") @Suppress("unused")
object RootDetectionPatch : BytecodePatch( object RootDetectionPatch : BytecodePatch(
setOf(AttestationSupportedCheckFingerprint, BootloaderCheckFingerprint, RootCheckFingerprint) setOf(AttestationSupportedCheckFingerprint, BootloaderCheckFingerprint, RootCheckFingerprint),
) { ) {
override fun execute(context: BytecodeContext) = listOf( override fun execute(context: BytecodeContext) = listOf(
AttestationSupportedCheckFingerprint, AttestationSupportedCheckFingerprint,
BootloaderCheckFingerprint, BootloaderCheckFingerprint,
RootCheckFingerprint RootCheckFingerprint,
).returnEarly(true) ).returnEarly(true)
} }

View File

@ -8,6 +8,6 @@ internal object AttestationSupportedCheckFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC.value, accessFlags = AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.name == "attestationSupportCheck" && methodDef.name == "attestationSupportCheck" &&
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;") methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
} },
) )

View File

@ -8,6 +8,6 @@ internal object BootloaderCheckFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC.value, accessFlags = AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.name == "bootloaderCheck" && methodDef.name == "bootloaderCheck" &&
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;") methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
} },
) )

View File

@ -8,6 +8,6 @@ internal object RootCheckFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC.value, accessFlags = AccessFlags.PUBLIC.value,
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.name == "rootCheck" && methodDef.name == "rootCheck" &&
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;") methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
} },
) )

View File

@ -10,24 +10,24 @@ import app.revanced.patches.idaustria.detection.signature.fingerprints.SpoofSign
@Patch( @Patch(
name = "Spoof signature", name = "Spoof signature",
description = "Spoofs the signature of the app.", description = "Spoofs the signature of the app.",
compatiblePackages = [CompatiblePackage("at.gv.oe.app")] compatiblePackages = [CompatiblePackage("at.gv.oe.app")],
) )
@Suppress("unused") @Suppress("unused")
object SpoofSignaturePatch : BytecodePatch( object SpoofSignaturePatch : BytecodePatch(
setOf(SpoofSignatureFingerprint) setOf(SpoofSignatureFingerprint),
) { ) {
private const val EXPECTED_SIGNATURE = private const val EXPECTED_SIGNATURE =
"OpenSSLRSAPublicKey{modulus=ac3e6fd6050aa7e0d6010ae58190404cd89a56935b44f6fee" + "OpenSSLRSAPublicKey{modulus=ac3e6fd6050aa7e0d6010ae58190404cd89a56935b44f6fee" +
"067c149768320026e10b24799a1339e414605e448e3f264444a327b9ae292be2b62ad567dd1800dbed4a88f718a33dc6db6b" + "067c149768320026e10b24799a1339e414605e448e3f264444a327b9ae292be2b62ad567dd1800dbed4a88f718a33dc6db6b" +
"f5178aa41aa0efff8a3409f5ca95dbfccd92c7b4298966df806ea7a0204a00f0e745f6d9f13bdf24f3df715d7b62c1600906" + "f5178aa41aa0efff8a3409f5ca95dbfccd92c7b4298966df806ea7a0204a00f0e745f6d9f13bdf24f3df715d7b62c1600906" +
"15de1c8a956b9286764985a3b3c060963c435fb9481a5543aaf0671fc2dba6c5c2b17d1ef1d85137f14dc9bbdf3490288087" + "15de1c8a956b9286764985a3b3c060963c435fb9481a5543aaf0671fc2dba6c5c2b17d1ef1d85137f14dc9bbdf3490288087" +
"324cd48341cce64fabf6a9b55d1a7bf23b2fcdff451fd85bf0c7feb0a5e884d7c5c078e413149566a12a686e6efa70ae5161" + "324cd48341cce64fabf6a9b55d1a7bf23b2fcdff451fd85bf0c7feb0a5e884d7c5c078e413149566a12a686e6efa70ae5161" +
"a0201307692834cda336c55157fef125e67c01c1359886f94742105596b42a790404bbcda5dad6a65f115aaff5e45ef3c28b" + "a0201307692834cda336c55157fef125e67c01c1359886f94742105596b42a790404bbcda5dad6a65f115aaff5e45ef3c28b" +
"2316ff6cef07aa49a45aa58c07bf258051b13ef449ccb37a3679afd5cfb9132f70bb9d931a937897544f90c3bcc80ed012e9" + "2316ff6cef07aa49a45aa58c07bf258051b13ef449ccb37a3679afd5cfb9132f70bb9d931a937897544f90c3bcc80ed012e9" +
"f6ba020b8cdc23f8c29ac092b88f0e370ff9434e4f0f359e614ae0868dc526fa41e4b7596533e8d10279b66e923ecd9f0b20" + "f6ba020b8cdc23f8c29ac092b88f0e370ff9434e4f0f359e614ae0868dc526fa41e4b7596533e8d10279b66e923ecd9f0b20" +
"0def55be2c1f6f9c72c92fb45d7e0a9ac571cb38f0a9a37bb33ea06f223fde8c7a92e8c47769e386f9799776e8f110c21df2" + "0def55be2c1f6f9c72c92fb45d7e0a9ac571cb38f0a9a37bb33ea06f223fde8c7a92e8c47769e386f9799776e8f110c21df2" +
"77ef1be61b2c01ebdabddcbf53cc4b6fd9a3c445606ee77b3758162c80ad8f8137b3c6864e92db904807dcb2be9d7717dd21" + "77ef1be61b2c01ebdabddcbf53cc4b6fd9a3c445606ee77b3758162c80ad8f8137b3c6864e92db904807dcb2be9d7717dd21" +
"bf42c121d620ddfb7914f7a95c713d9e1c1b7bdb4a03d618e40cf7e9e235c0b5687e03b7ab3,publicExponent=10001}" "bf42c121d620ddfb7914f7a95c713d9e1c1b7bdb4a03d618e40cf7e9e235c0b5687e03b7ab3,publicExponent=10001}"
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
SpoofSignatureFingerprint.result!!.mutableMethod.addInstructions( SpoofSignatureFingerprint.result!!.mutableMethod.addInstructions(
@ -35,7 +35,7 @@ object SpoofSignaturePatch : BytecodePatch(
""" """
const-string v0, "$EXPECTED_SIGNATURE" const-string v0, "$EXPECTED_SIGNATURE"
return-object v0 return-object v0
""" """,
) )
} }
} }

View File

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

View File

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

View File

@ -4,5 +4,5 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
internal object InshortsAdsFingerprint : MethodFingerprint( internal object InshortsAdsFingerprint : MethodFingerprint(
"V", "V",
strings = listOf("GoogleAdLoader","exception in requestAd"), strings = listOf("GoogleAdLoader", "exception in requestAd"),
) )

View File

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

View File

@ -3,5 +3,5 @@ package app.revanced.patches.instagram.patches.ads.timeline.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
internal object MediaFingerprint : 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.IF_EQZ,
Opcode.CONST_4, Opcode.CONST_4,
Opcode.RETURN, Opcode.RETURN,
) ),
) { ) {
override fun toString() = result!!.method.toString() override fun toString() = result!!.method.toString()
} }

View File

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

View File

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

View File

@ -15,7 +15,7 @@ internal object ShoppingAdFingerprint : MediaAdFingerprint(
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.XOR_INT_LIT8, Opcode.XOR_INT_LIT8,
Opcode.IF_EQZ, Opcode.IF_EQZ,
) ),
) { ) {
override fun toString() = result!!.method.toString() 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.patcher.patch.annotation.Patch
import app.revanced.patches.irplus.ad.fingerprints.IrplusAdsFingerprint import app.revanced.patches.irplus.ad.fingerprints.IrplusAdsFingerprint
@Patch( @Patch(
name = "Remove ads", name = "Remove ads",
compatiblePackages = [CompatiblePackage("net.binarymode.android.irplus")] compatiblePackages = [CompatiblePackage("net.binarymode.android.irplus")],
) )
@Suppress("unused") @Suppress("unused")
object RemoveAdsPatch : BytecodePatch( object RemoveAdsPatch : BytecodePatch(
setOf(IrplusAdsFingerprint) setOf(IrplusAdsFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
val method = IrplusAdsFingerprint.result!!.mutableMethod val method = IrplusAdsFingerprint.result!!.mutableMethod

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,11 +8,10 @@ internal object LoadInboxAdsFingerprint : MethodFingerprint(
returnType = "V", returnType = "V",
strings = listOf( strings = listOf(
"ads_load_begin", "ads_load_begin",
"inbox_ads_fetch_start" "inbox_ads_fetch_start",
), ),
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
customFingerprint = { methodDef, _ -> customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/facebook/messaging/business/inboxads/plugins/inboxads/itemsupplier/InboxAdsItemSupplierImplementation;" 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 package app.revanced.patches.messenger.ads.inbox.patch
import app.revanced.util.exception
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.messenger.ads.inbox.fingerprints.LoadInboxAdsFingerprint import app.revanced.patches.messenger.ads.inbox.fingerprints.LoadInboxAdsFingerprint
import app.revanced.util.exception
@Patch( @Patch(
name = "Hide inbox ads", name = "Hide inbox ads",
description = "Hides ads in inbox.", description = "Hides ads in inbox.",
compatiblePackages = [CompatiblePackage("com.facebook.orca")] compatiblePackages = [CompatiblePackage("com.facebook.orca")],
) )
@Suppress("unused") @Suppress("unused")
object HideInboxAdsPatch : BytecodePatch( object HideInboxAdsPatch : BytecodePatch(
setOf(LoadInboxAdsFingerprint) setOf(LoadInboxAdsFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
LoadInboxAdsFingerprint.result?.mutableMethod?.apply { LoadInboxAdsFingerprint.result?.mutableMethod?.apply {
@ -23,4 +23,3 @@ object HideInboxAdsPatch : BytecodePatch(
} ?: throw LoadInboxAdsFingerprint.exception } ?: throw LoadInboxAdsFingerprint.exception
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,11 +11,11 @@ import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsFingerp
@Patch( @Patch(
name = "Music video ads", name = "Music video ads",
description = "Removes ads in the music player.", 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") @Suppress("unused")
object MusicVideoAdsPatch : BytecodePatch( object MusicVideoAdsPatch : BytecodePatch(
setOf(ShowMusicVideoAdsConstructorFingerprint) setOf(ShowMusicVideoAdsConstructorFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
ShowMusicVideoAdsFingerprint.resolve(context, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef) ShowMusicVideoAdsFingerprint.resolve(context, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef)
@ -26,7 +26,7 @@ object MusicVideoAdsPatch : BytecodePatch(
result.scanResult.patternScanResult!!.startIndex, result.scanResult.patternScanResult!!.startIndex,
""" """
const/4 p1, 0x0 const/4 p1, 0x0
""" """,
) )
} }
} }

View File

@ -1,13 +1,16 @@
package app.revanced.patches.music.ad.video.fingerprints package app.revanced.patches.music.ad.video.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint 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.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
internal object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint( 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.INVOKE_DIRECT,
Opcode.NEW_INSTANCE, Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
@ -22,6 +25,6 @@ internal object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint(
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.CONST_4, Opcode.CONST_4,
Opcode.IPUT_BOOLEAN, 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 import com.android.tools.smali.dexlib2.Opcode
internal object ShowMusicVideoAdsFingerprint : MethodFingerprint( 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.IPUT_BOOLEAN,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID Opcode.RETURN_VOID,
) ),
) )

View File

@ -12,11 +12,11 @@ import com.android.tools.smali.dexlib2.Opcode
@Patch( @Patch(
name = "Codecs unlock", name = "Codecs unlock",
description = "Adds more audio codec options. The new audio codecs usually result in better audio quality.", 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") @Suppress("unused")
object CodecsUnlockPatch : BytecodePatch( object CodecsUnlockPatch : BytecodePatch(
setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint) setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
val codecsLockResult = CodecsLockFingerprint.result!! val codecsLockResult = CodecsLockFingerprint.result!!
@ -25,13 +25,13 @@ object CodecsUnlockPatch : BytecodePatch(
val scanResultStartIndex = codecsLockResult.scanResult.patternScanResult!!.startIndex val scanResultStartIndex = codecsLockResult.scanResult.patternScanResult!!.startIndex
val instructionIndex = scanResultStartIndex + val instructionIndex = scanResultStartIndex +
if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) { if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) {
// for 5.16.xx and lower // for 5.16.xx and lower
-3 -3
} else { } else {
// since 5.17.xx // since 5.17.xx
-2 -2
} }
val allCodecsResult = AllCodecsReferenceFingerprint.result!! val allCodecsResult = AllCodecsReferenceFingerprint.result!!
val allCodecsMethod = val allCodecsMethod =
@ -41,7 +41,7 @@ object CodecsUnlockPatch : BytecodePatch(
implementation.replaceInstruction( implementation.replaceInstruction(
instructionIndex, 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 package app.revanced.patches.music.audio.codecs.fingerprints
import app.revanced.patcher.extensions.or import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint 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.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. @FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value.
internal object AllCodecsReferenceFingerprint : MethodFingerprint( 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.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
@ -47,6 +49,7 @@ internal object AllCodecsReferenceFingerprint : MethodFingerprint(
Opcode.MOVE_EXCEPTION, Opcode.MOVE_EXCEPTION,
Opcode.INVOKE_SUPER, Opcode.INVOKE_SUPER,
Opcode.MOVE_RESULT_WIDE, Opcode.MOVE_RESULT_WIDE,
Opcode.RETURN_WIDE Opcode.RETURN_WIDE,
), listOf("itag") ),
listOf("itag"),
) )

View File

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

View File

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

View File

@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
internal object AllowExclusiveAudioPlaybackFingerprint: MethodFingerprint( internal object AllowExclusiveAudioPlaybackFingerprint : MethodFingerprint(
"Z", "Z",
AccessFlags.PUBLIC or AccessFlags.FINAL, AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(), listOf(),
@ -20,6 +20,6 @@ internal object AllowExclusiveAudioPlaybackFingerprint: MethodFingerprint(
Opcode.GOTO, Opcode.GOTO,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT, Opcode.MOVE_RESULT,
Opcode.RETURN Opcode.RETURN,
) ),
) )

View File

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

View File

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

View File

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

View File

@ -15,6 +15,6 @@ internal object DisableShuffleFingerprint : MethodFingerprint(
Opcode.SGET_OBJECT, Opcode.SGET_OBJECT,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.IGET_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", name = "Compact header",
description = "Hides the music category bar at the top of the homepage.", description = "Hides the music category bar at the top of the homepage.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
use = false use = false,
) )
@Suppress("unused") @Suppress("unused")
object CompactHeaderPatch : BytecodePatch( object CompactHeaderPatch : BytecodePatch(
setOf(CompactHeaderConstructorFingerprint) setOf(CompactHeaderConstructorFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
val result = CompactHeaderConstructorFingerprint.result!! val result = CompactHeaderConstructorFingerprint.result!!
@ -25,10 +25,11 @@ object CompactHeaderPatch : BytecodePatch(
val insertIndex = result.scanResult.patternScanResult!!.endIndex val insertIndex = result.scanResult.patternScanResult!!.endIndex
val register = (method.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA val register = (method.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA
method.addInstructions( method.addInstructions(
insertIndex, """ insertIndex,
const/16 v2, 0x8
invoke-virtual {v${register}, v2}, Landroid/view/View;->setVisibility(I)V
""" """
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 import com.android.tools.smali.dexlib2.Opcode
internal object CompactHeaderConstructorFingerprint : MethodFingerprint( 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.INVOKE_DIRECT,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT, Opcode.IPUT_OBJECT,
@ -18,6 +21,6 @@ internal object CompactHeaderConstructorFingerprint : MethodFingerprint(
Opcode.CONST_4, Opcode.CONST_4,
Opcode.INVOKE_STATIC, Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST Opcode.CHECK_CAST,
) ),
) )

View File

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

View File

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

View File

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

View File

@ -6,11 +6,14 @@ import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcode
internal object HideGetPremiumFingerprint : MethodFingerprint( internal object HideGetPremiumFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( "V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
listOf(
Opcode.IF_NEZ, Opcode.IF_NEZ,
Opcode.CONST_16, Opcode.CONST_16,
Opcode.GOTO, Opcode.GOTO,
Opcode.NOP, 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 import com.android.tools.smali.dexlib2.Opcode
internal object HideGetPremiumParentFingerprint : MethodFingerprint( internal object HideGetPremiumParentFingerprint : MethodFingerprint(
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( "V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
listOf(),
listOf(
Opcode.IGET_BOOLEAN, Opcode.IGET_BOOLEAN,
Opcode.CONST_4, Opcode.CONST_4,
Opcode.IF_EQZ, Opcode.IF_EQZ,
Opcode.IGET_OBJECT, Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL, Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT, Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_STATIC Opcode.INVOKE_STATIC,
), ),
listOf("FEmusic_history"), 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.Instruction22c
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
@Patch( @Patch(
name = "Remove upgrade button", name = "Remove upgrade button",
description = "Removes the upgrade tab from the pivot bar.", 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") @Suppress("unused")
object RemoveUpgradeButtonPatch : BytecodePatch( object RemoveUpgradeButtonPatch : BytecodePatch(
setOf(PivotBarConstructorFingerprint) setOf(PivotBarConstructorFingerprint),
) { ) {
override fun execute(context: BytecodeContext) { override fun execute(context: BytecodeContext) {
val result = PivotBarConstructorFingerprint.result!! val result = PivotBarConstructorFingerprint.result!!
@ -39,19 +38,20 @@ object RemoveUpgradeButtonPatch : BytecodePatch(
iput-object v0, v$register, $pivotBarElementFieldRef iput-object v0, v$register, $pivotBarElementFieldRef
""".toInstructions().toMutableList() """.toInstructions().toMutableList()
val endIndex = result.scanResult.patternScanResult!!.endIndex val endIndex = result.scanResult.patternScanResult!!.endIndex
// replace the instruction to retain the label at given index // replace the instruction to retain the label at given index
implementation.replaceInstruction( 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 // do not forget to remove this instruction since we added it already
instructionList.removeFirst() instructionList.removeFirst()
val exitInstruction = instructionList.last() // iput-object val exitInstruction = instructionList.last() // iput-object
implementation.addInstruction( implementation.addInstruction(
endIndex, exitInstruction endIndex,
exitInstruction,
) )
// do not forget to remove this instruction since we added it already // do not forget to remove this instruction since we added it already
instructionList.removeLast() instructionList.removeLast()
@ -60,12 +60,16 @@ object RemoveUpgradeButtonPatch : BytecodePatch(
instructionList.add( instructionList.add(
2, // if-le 2, // if-le
BuilderInstruction22t( BuilderInstruction22t(
Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(endIndex) Opcode.IF_LE,
) 1,
2,
implementation.newLabelForIndex(endIndex),
),
) )
implementation.addInstructions( implementation.addInstructions(
endIndex, instructionList endIndex,
instructionList,
) )
} }
} }

View File

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

View File

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

View File

@ -8,5 +8,5 @@ internal object CheckCertificateFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
returnType = "Z", returnType = "Z",
parameters = listOf("Ljava/lang/String;"), 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.Constants.REVANCED_MUSIC_PACKAGE_NAME
import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption
import app.revanced.patches.music.misc.gms.fingerprints.* 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.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.fingerprints.CastContextFetchFingerprint
import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch
@Suppress("unused") @Suppress("unused")
object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
@ -32,7 +32,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
CastDynamiteModuleV2Fingerprint, CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint, CastContextFetchFingerprint,
PrimeMethodFingerprint, PrimeMethodFingerprint,
) ),
) { ) {
override val gmsCoreVendor by gmsCoreVendorOption override val gmsCoreVendor by gmsCoreVendorOption
} }

View File

@ -7,5 +7,5 @@ import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportResourcePatch
object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch( object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch(
fromPackageName = MUSIC_PACKAGE_NAME, fromPackageName = MUSIC_PACKAGE_NAME,
toPackageName = REVANCED_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 package app.revanced.patches.music.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
internal object CastDynamiteModuleFingerprint : 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 package app.revanced.patches.music.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
internal object CastDynamiteModuleV2Fingerprint : 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", "MetadataValueReader",
"GooglePlayServicesUtil", "GooglePlayServicesUtil",
"com.android.vending", "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 package app.revanced.patches.music.misc.gms.fingerprints
import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.fingerprint.MethodFingerprint
internal object PrimeMethodFingerprint : 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.INVOKE_STATIC,
Opcode.NEW_INSTANCE, Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT, Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL Opcode.INVOKE_VIRTUAL,
), ),
strings = listOf("activity"), strings = listOf("activity"),
customFingerprint = { methodDef, _ -> methodDef.name == "onCreate" }, customFingerprint = { methodDef, _ -> methodDef.name == "onCreate" },

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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