chore: Changes from gradle ktlintformat task

This commit is contained in:
LisoUseInAIKyrios 2024-03-31 23:43:13 +04:00
parent 57012c0e58
commit e925ed6eb3
616 changed files with 3063 additions and 2614 deletions

View file

@ -68,8 +68,9 @@ tasks {
dependsOn(build)
doLast {
val d8 = File(System.getenv("ANDROID_HOME")).resolve("build-tools")
.listFilesOrdered().last().resolve("d8").absolutePath
val d8 =
File(System.getenv("ANDROID_HOME")).resolve("build-tools")
.listFilesOrdered().last().resolve("d8").absolutePath
val patchesJar = configurations.archives.get().allArtifacts.files.files.first().absolutePath
val workingDirectory = layout.buildDirectory.dir("libs").get().asFile

View file

@ -6,27 +6,28 @@ import com.google.gson.GsonBuilder
import java.io.File
internal class JsonPatchesFileGenerator : PatchesFileGenerator {
override fun generate(patches: PatchSet) = patches.map {
JsonPatch(
it.name!!,
it.description,
it.compatiblePackages,
it.use,
it.requiresIntegrations,
it.options.values.map { option ->
JsonPatch.Option(
option.key,
option.default,
option.values,
option.title,
option.description,
option.required,
)
},
)
}.let {
File("patches.json").writeText(GsonBuilder().serializeNulls().create().toJson(it))
}
override fun generate(patches: PatchSet) =
patches.map {
JsonPatch(
it.name!!,
it.description,
it.compatiblePackages,
it.use,
it.requiresIntegrations,
it.options.values.map { option ->
JsonPatch.Option(
option.key,
option.default,
option.values,
option.title,
option.description,
option.required
)
}
)
}.let {
File("patches.json").writeText(GsonBuilder().serializeNulls().create().toJson(it))
}
@Suppress("unused")
private class JsonPatch(
@ -35,7 +36,7 @@ internal class JsonPatchesFileGenerator : PatchesFileGenerator {
val compatiblePackages: Set<Patch.CompatiblePackage>? = null,
val use: Boolean = true,
val requiresIntegrations: Boolean = false,
val options: List<Option>,
val options: List<Option>
) {
class Option(
val key: String,
@ -43,7 +44,7 @@ internal class JsonPatchesFileGenerator : PatchesFileGenerator {
val values: Map<String, Any?>?,
val title: String?,
val description: String?,
val required: Boolean,
val required: Boolean
)
}
}

View file

@ -3,10 +3,11 @@ package app.revanced.generator
import app.revanced.patcher.PatchBundleLoader
import java.io.File
internal fun main() = PatchBundleLoader.Jar(
File("build/libs/").listFiles { it -> it.name.endsWith(".jar") }!!.first(),
).also { loader ->
if (loader.isEmpty()) throw IllegalStateException("No patches found")
}.let { bundle ->
arrayOf(JsonPatchesFileGenerator()).forEach { generator -> generator.generate(bundle) }
}
internal fun main() =
PatchBundleLoader.Jar(
File("build/libs/").listFiles { it -> it.name.endsWith(".jar") }!!.first()
).also { loader ->
if (loader.isEmpty()) throw IllegalStateException("No patches found")
}.let { bundle ->
arrayOf(JsonPatchesFileGenerator()).forEach { generator -> generator.generate(bundle) }
}

View file

@ -7,7 +7,7 @@ import app.revanced.patcher.patch.annotation.Patch
@Patch(
name = "Export all activities",
description = "Makes all app activities exportable.",
use = false,
use = false
)
@Suppress("unused")
object ExportAllActivitiesPatch : ResourcePatch() {

View file

@ -14,7 +14,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
name = "Spoof Wi-Fi connection",
description = "Spoofs an existing Wi-Fi connection.",
use = false,
requiresIntegrations = true,
requiresIntegrations = true
)
@Suppress("unused")
object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
@ -25,15 +25,18 @@ object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int,
instructionIndex: Int
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex,
instructionIndex
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
override fun transform(
mutableMethod: MutableMethod,
entry: Instruction35cInfo
) {
val (methodType, instruction, instructionIndex) = entry
methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
}
@ -43,163 +46,163 @@ object SpoofWifiPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
override val definedClassName: String,
override val methodName: String,
override val methodParams: Array<String>,
override val returnType: String,
override val returnType: String
) : IMethodCall {
GetSystemService1(
"Landroid/content/Context;",
"getSystemService",
arrayOf("Ljava/lang/String;"),
"Ljava/lang/Object;",
"Ljava/lang/Object;"
),
GetSystemService2(
"Landroid/content/Context;",
"getSystemService",
arrayOf("Ljava/lang/Class;"),
"Ljava/lang/Object;",
"Ljava/lang/Object;"
),
GetActiveNetworkInfo(
"Landroid/net/ConnectivityManager;",
"getActiveNetworkInfo",
arrayOf(),
"Landroid/net/NetworkInfo;",
"Landroid/net/NetworkInfo;"
),
IsConnected(
"Landroid/net/NetworkInfo;",
"isConnected",
arrayOf(),
"Z",
"Z"
),
IsConnectedOrConnecting(
"Landroid/net/NetworkInfo;",
"isConnectedOrConnecting",
arrayOf(),
"Z",
"Z"
),
IsAvailable(
"Landroid/net/NetworkInfo;",
"isAvailable",
arrayOf(),
"Z",
"Z"
),
GetState(
"Landroid/net/NetworkInfo;",
"getState",
arrayOf(),
"Landroid/net/NetworkInfo\$State;",
"Landroid/net/NetworkInfo\$State;"
),
GetDetailedState(
"Landroid/net/NetworkInfo;",
"getDetailedState",
arrayOf(),
"Landroid/net/NetworkInfo\$DetailedState;",
"Landroid/net/NetworkInfo\$DetailedState;"
),
IsActiveNetworkMetered(
"Landroid/net/ConnectivityManager;",
"isActiveNetworkMetered",
arrayOf(),
"Z",
"Z"
),
GetActiveNetwork(
"Landroid/net/ConnectivityManager;",
"getActiveNetwork",
arrayOf(),
"Landroid/net/Network;",
"Landroid/net/Network;"
),
GetNetworkInfo(
"Landroid/net/ConnectivityManager;",
"getNetworkInfo",
arrayOf("Landroid/net/Network;"),
"Landroid/net/NetworkInfo;",
"Landroid/net/NetworkInfo;"
),
HasTransport(
"Landroid/net/NetworkCapabilities;",
"hasTransport",
arrayOf("I"),
"Z",
"Z"
),
HasCapability(
"Landroid/net/NetworkCapabilities;",
"hasCapability",
arrayOf("I"),
"Z",
"Z"
),
RegisterBestMatchingNetworkCallback(
"Landroid/net/ConnectivityManager;",
"registerBestMatchingNetworkCallback",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
"V",
"V"
),
RegisterDefaultNetworkCallback1(
"Landroid/net/ConnectivityManager;",
"registerDefaultNetworkCallback",
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"),
"V",
"V"
),
RegisterDefaultNetworkCallback2(
"Landroid/net/ConnectivityManager;",
"registerDefaultNetworkCallback",
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
"V",
"V"
),
RegisterNetworkCallback1(
"Landroid/net/ConnectivityManager;",
"registerNetworkCallback",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"),
"V",
"V"
),
RegisterNetworkCallback2(
"Landroid/net/ConnectivityManager;",
"registerNetworkCallback",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/app/PendingIntent;"),
"V",
"V"
),
RegisterNetworkCallback3(
"Landroid/net/ConnectivityManager;",
"registerNetworkCallback",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
"V",
"V"
),
RequestNetwork1(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"),
"V",
"V"
),
RequestNetwork2(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "I"),
"V",
"V"
),
RequestNetwork3(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;"),
"V",
"V"
),
RequestNetwork4(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/app/PendingIntent;"),
"V",
"V"
),
RequestNetwork5(
"Landroid/net/ConnectivityManager;",
"requestNetwork",
arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "Landroid/os/Handler;", "I"),
"V",
"V"
),
UnregisterNetworkCallback1(
"Landroid/net/ConnectivityManager;",
"unregisterNetworkCallback",
arrayOf("Landroid/net/ConnectivityManager\$NetworkCallback;"),
"V",
"V"
),
UnregisterNetworkCallback2(
"Landroid/net/ConnectivityManager;",
"unregisterNetworkCallback",
arrayOf("Landroid/app/PendingIntent;"),
"V",
),
"V"
)
}
}

View file

@ -7,7 +7,7 @@ import app.revanced.patcher.patch.annotation.Patch
@Patch(
name = "Predictive back gesture",
description = "Enables the predictive back gesture introduced on Android 13.",
use = false,
use = false
)
@Suppress("unused")
object PredictiveBackGesturePatch : ResourcePatch() {

View file

@ -8,7 +8,7 @@ import org.w3c.dom.Element
@Patch(
name = "Enable Android debugging",
description = "Enables Android debugging capabilities. This can slow down the app.",
use = false,
use = false
)
@Suppress("unused")
object EnableAndroidDebuggingPatch : ResourcePatch() {

View file

@ -5,14 +5,14 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.all.misc.debugging.EnableAndroidDebuggingPatch
import app.revanced.util.Utils.trimIndentMultiline
import org.w3c.dom.Element
import java.io.File
import org.w3c.dom.Element
@Patch(
name = "Override certificate pinning",
description = "Overrides certificate pinning, allowing to inspect traffic via a proxy.",
dependencies = [EnableAndroidDebuggingPatch::class],
use = false,
use = false
)
@Suppress("unused")
object OverrideCertificatePinningPatch : ResourcePatch() {
@ -54,7 +54,7 @@ object OverrideCertificatePinningPatch : ResourcePatch() {
</trust-anchors>
</debug-overrides>
</network-security-config>
""".trimIndentMultiline(),
""".trimIndentMultiline()
)
}
}

View file

@ -5,13 +5,13 @@ import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatchOption
import app.revanced.patcher.patch.options.PatchOptionException
import org.w3c.dom.Element
import java.io.Closeable
import org.w3c.dom.Element
@Patch(
name = "Change package name",
description = "Appends \".revanced\" to the package name by default. Changing the package name of the app can lead to unexpected issues.",
use = false,
use = false
)
@Suppress("unused")
object ChangePackageNamePatch : ResourcePatch(), Closeable {
@ -22,7 +22,7 @@ object ChangePackageNamePatch : ResourcePatch(), Closeable {
values = mapOf("Default" to "Default"),
title = "Package name",
description = "The name of the package to rename the app to.",
required = true,
required = true
) {
it == "Default" || it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$"))
}
@ -64,7 +64,7 @@ object ChangePackageNamePatch : ResourcePatch(), Closeable {
replacementPackageName
} else {
"${manifest.getAttribute("package")}.revanced"
},
}
)
}
}

View file

@ -11,9 +11,9 @@ import app.revanced.util.*
import app.revanced.util.resource.ArrayResource
import app.revanced.util.resource.BaseResource
import app.revanced.util.resource.StringResource
import org.w3c.dom.Node
import java.io.Closeable
import java.util.*
import org.w3c.dom.Node
/**
* An identifier of an app. For example, `youtube`.
@ -82,11 +82,11 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
fun addResources(
value: Value,
resourceKind: String,
transform: (Node) -> BaseResource,
transform: (Node) -> BaseResource
) {
inputStreamFromBundledResource(
"addresources",
"$value/$resourceKind.xml",
"$value/$resourceKind.xml"
)?.let { stream ->
// Add the resources associated with the given value to the map,
// instead of overwriting it.
@ -144,7 +144,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
*/
operator fun invoke(
value: Value,
resource: BaseResource,
resource: BaseResource
) = getOrPut(value, ::mutableSetOf).add(resource)
/**
@ -157,7 +157,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
*/
operator fun invoke(
value: Value,
resources: Iterable<BaseResource>,
resources: Iterable<BaseResource>
) = getOrPut(value, ::mutableSetOf).addAll(resources)
/**
@ -174,7 +174,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
name: String,
value: String,
formatted: Boolean = true,
resourceValue: Value = "values",
resourceValue: Value = "values"
) = invoke(resourceValue, StringResource(name, value, formatted))
/**
@ -187,7 +187,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
*/
operator fun invoke(
name: String,
items: List<String>,
items: List<String>
) = invoke("values", ArrayResource(name, items))
/**
@ -218,7 +218,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
appId to patchId
}
},
}
): Boolean {
val (appId, patchId) = patch.parseIds()
@ -241,7 +241,7 @@ object AddResourcesPatch : ResourcePatch(), MutableMap<Value, MutableSet<BaseRes
override fun close() {
operator fun MutableMap<String, Pair<DomFileEditor, Node>>.invoke(
value: Value,
resource: BaseResource,
resource: BaseResource
) {
// TODO: Fix open-closed principle violation by modifying BaseResource#serialize so that it accepts
// a Value and the map of documents. It will then get or put the document suitable for its resource type

View file

@ -14,13 +14,19 @@ abstract class BaseTransformInstructionsPatch<T> : BytecodePatch(emptySet()) {
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int,
instructionIndex: Int
): T?
abstract fun transform(mutableMethod: MutableMethod, entry: T)
abstract fun transform(
mutableMethod: MutableMethod,
entry: T
)
// Returns the patch indices as a Sequence, which will execute lazily.
fun findPatchIndices(classDef: ClassDef, method: Method): Sequence<T>? {
fun findPatchIndices(
classDef: ClassDef,
method: Method
): Sequence<T>? {
return method.implementation?.instructions?.asSequence()?.withIndex()?.mapNotNull { (index, instruction) ->
filterMap(classDef, method, instruction, index)
}
@ -30,14 +36,15 @@ abstract class BaseTransformInstructionsPatch<T> : BytecodePatch(emptySet()) {
// Find all methods to patch
buildMap {
context.classes.forEach { classDef ->
val methods = buildList {
classDef.methods.forEach { method ->
// Since the Sequence executes lazily,
// using any() results in only calling
// filterMap until the first index has been found.
if (findPatchIndices(classDef, method)?.any() == true) add(method)
val methods =
buildList {
classDef.methods.forEach { method ->
// Since the Sequence executes lazily,
// using any() results in only calling
// filterMap until the first index has been found.
if (findPatchIndices(classDef, method)?.any() == true) add(method)
}
}
}
if (methods.isNotEmpty()) {
put(classDef, methods)
@ -48,8 +55,9 @@ abstract class BaseTransformInstructionsPatch<T> : BytecodePatch(emptySet()) {
val mutableClass = context.proxy(classDef).mutableClass
methods.map(mutableClass::findMutableMethodOf).forEach methods@{ mutableMethod ->
val patchIndices = findPatchIndices(mutableClass, mutableMethod)?.toCollection(ArrayDeque())
?: return@methods
val patchIndices =
findPatchIndices(mutableClass, mutableMethod)?.toCollection(ArrayDeque())
?: return@methods
while (!patchIndices.isEmpty()) transform(mutableMethod, patchIndices.removeLast())
}

View file

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

View file

@ -15,7 +15,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
description = "Removes the restriction of capturing audio from apps that normally wouldn't allow it.",
dependencies = [RemoveCaptureRestrictionResourcePatch::class],
use = false,
requiresIntegrations = true,
requiresIntegrations = true
)
@Suppress("unused")
object RemoveCaptureRestrictionPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
@ -28,35 +28,38 @@ object RemoveCaptureRestrictionPatch : BaseTransformInstructionsPatch<Instructio
override val definedClassName: String,
override val methodName: String,
override val methodParams: Array<String>,
override val returnType: String,
override val returnType: String
) : IMethodCall {
SetAllowedCapturePolicySingle(
"Landroid/media/AudioAttributes\$Builder;",
"setAllowedCapturePolicy",
arrayOf("I"),
"Landroid/media/AudioAttributes\$Builder;",
"Landroid/media/AudioAttributes\$Builder;"
),
SetAllowedCapturePolicyGlobal(
"Landroid/media/AudioManager;",
"setAllowedCapturePolicy",
arrayOf("I"),
"V",
),
"V"
)
}
override fun filterMap(
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int,
instructionIndex: Int
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex,
instructionIndex
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
override fun transform(
mutableMethod: MutableMethod,
entry: Instruction35cInfo
) {
val (methodType, instruction, instructionIndex) = entry
methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
}

View file

@ -19,7 +19,7 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
name = "Remove screenshot restriction",
description = "Removes the restriction of taking screenshots in apps that normally wouldn't allow it.",
use = false,
requiresIntegrations = true,
requiresIntegrations = true
)
@Suppress("unused")
object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
@ -36,15 +36,18 @@ object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruc
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int,
instructionIndex: Int
) = filterMapInstruction35c<MethodCall>(
INTEGRATIONS_CLASS_DESCRIPTOR_PREFIX,
classDef,
instruction,
instructionIndex,
instructionIndex
)
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
override fun transform(
mutableMethod: MutableMethod,
entry: Instruction35cInfo
) {
val (methodType, instruction, instructionIndex) = entry
methodType.replaceInvokeVirtualWithIntegrations(INTEGRATIONS_CLASS_DESCRIPTOR, mutableMethod, instruction, instructionIndex)
}
@ -54,20 +57,20 @@ object RemoveScreenshotRestrictionPatch : BaseTransformInstructionsPatch<Instruc
override val definedClassName: String,
override val methodName: String,
override val methodParams: Array<String>,
override val returnType: String,
override val returnType: String
) : IMethodCall {
AddFlags(
"Landroid/view/Window;",
"addFlags",
arrayOf("I"),
"V",
"V"
),
SetFlags(
"Landroid/view/Window;",
"setFlags",
arrayOf("I", "I"),
"V",
),
"V"
)
}
}
@ -76,7 +79,7 @@ private class ModifyLayoutParamsFlags : BaseTransformInstructionsPatch<Pair<Inst
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int,
instructionIndex: Int
): Pair<Instruction22c, Int>? {
if (instruction.opcode != Opcode.IPUT) {
return null
@ -95,13 +98,16 @@ private class ModifyLayoutParamsFlags : BaseTransformInstructionsPatch<Pair<Inst
return Pair(instruction22c, instructionIndex)
}
override fun transform(mutableMethod: MutableMethod, entry: Pair<Instruction22c, Int>) {
override fun transform(
mutableMethod: MutableMethod,
entry: Pair<Instruction22c, Int>
) {
val (instruction, index) = entry
val register = instruction.registerA
mutableMethod.addInstructions(
index,
"and-int/lit16 v$register, v$register, -0x2001",
"and-int/lit16 v$register, v$register, -0x2001"
)
}
}

View file

@ -19,7 +19,7 @@ import java.util.*
@Patch(
name = "Spoof SIM country",
description = "Spoofs country information returned by the SIM card provider.",
use = false,
use = false
)
@Suppress("unused")
object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>() {
@ -27,17 +27,17 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
private val networkCountryIso by isoCountryPatchOption(
"networkCountryIso",
"Network ISO Country Code",
"Network ISO Country Code"
)
private val simCountryIso by isoCountryPatchOption(
"simCountryIso",
"Sim ISO Country Code",
"Sim ISO Country Code"
)
private fun isoCountryPatchOption(
key: String,
title: String,
title: String
) = stringPatchOption(
key,
null,
@ -45,39 +45,41 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
title,
"ISO-3166-1 alpha-2 country code equivalent for the SIM provider's country code.",
false,
validator = { it: String? -> it == null || it.uppercase() in countries.values },
validator = { it: String? -> it == null || it.uppercase() in countries.values }
)
override fun filterMap(
classDef: ClassDef,
method: Method,
instruction: Instruction,
instructionIndex: Int,
instructionIndex: Int
): Pair<Int, String>? {
if (instruction !is ReferenceInstruction) return null
val reference = instruction.reference as? MethodReference ?: return null
val match = MethodCall.entries.firstOrNull { search ->
MethodUtil.methodSignaturesMatch(reference, search.reference)
} ?: return null
val match =
MethodCall.entries.firstOrNull { search ->
MethodUtil.methodSignaturesMatch(reference, search.reference)
} ?: return null
val iso = when (match) {
MethodCall.NetworkCountryIso -> networkCountryIso
MethodCall.SimCountryIso -> simCountryIso
}?.lowercase()
val iso =
when (match) {
MethodCall.NetworkCountryIso -> networkCountryIso
MethodCall.SimCountryIso -> simCountryIso
}?.lowercase()
return iso?.let { instructionIndex to it }
}
override fun transform(
mutableMethod: MutableMethod,
entry: Pair<Int, String>,
entry: Pair<Int, String>
) = transformMethodCall(entry, mutableMethod)
private fun transformMethodCall(
entry: Pair<Int, String>,
mutableMethod: MutableMethod,
mutableMethod: MutableMethod
) {
val (instructionIndex, methodCallValue) = entry
@ -85,28 +87,28 @@ object SpoofSimCountryPatch : BaseTransformInstructionsPatch<Pair<Int, String>>(
mutableMethod.replaceInstruction(
instructionIndex + 1,
"const-string v$register, \"$methodCallValue\"",
"const-string v$register, \"$methodCallValue\""
)
}
private enum class MethodCall(
val reference: MethodReference,
val reference: MethodReference
) {
NetworkCountryIso(
ImmutableMethodReference(
"Landroid/telephony/TelephonyManager;",
"getNetworkCountryIso",
emptyList(),
"Ljava/lang/String;",
),
"Ljava/lang/String;"
)
),
SimCountryIso(
ImmutableMethodReference(
"Landroid/telephony/TelephonyManager;",
"getSimCountryIso",
emptyList(),
"Ljava/lang/String;",
),
),
"Ljava/lang/String;"
)
)
}
}

View file

@ -12,11 +12,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Pro unlock",
compatiblePackages = [CompatiblePackage("com.backdrops.wallpapers", ["4.52"])],
compatiblePackages = [CompatiblePackage("com.backdrops.wallpapers", ["4.52"])]
)
@Suppress("unused")
object ProUnlockPatch : BytecodePatch(
setOf(ProUnlockFingerprint),
setOf(ProUnlockFingerprint)
) {
override fun execute(context: BytecodeContext) {
ProUnlockFingerprint.result?.let { result ->
@ -28,7 +28,7 @@ object ProUnlockPatch : BytecodePatch(
result.scanResult.patternScanResult!!.endIndex,
"""
const/4 v$register, 0x1
""",
"""
)
}
} ?: throw ProUnlockFingerprint.exception

View file

@ -4,15 +4,16 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
internal object ProUnlockFingerprint : MethodFingerprint(
opcodes = listOf(
opcodes =
listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.IF_EQZ
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/backdrops/wallpapers/data/local/DatabaseHandlerIAB;" &&
methodDef.name == "lambda\$existPurchase\$0"
},
}
)

View file

@ -10,11 +10,11 @@ import app.revanced.util.exception
@Patch(
name = "Unlock pro",
compatiblePackages = [CompatiblePackage("com.candylink.openvpn")],
compatiblePackages = [CompatiblePackage("com.candylink.openvpn")]
)
@Suppress("unused")
object UnlockProPatch : BytecodePatch(
setOf(IsPremiumPurchasedFingerprint),
setOf(IsPremiumPurchasedFingerprint)
) {
override fun execute(context: BytecodeContext) {
IsPremiumPurchasedFingerprint.result?.mutableMethod?.addInstructions(
@ -22,7 +22,7 @@ object UnlockProPatch : BytecodePatch(
"""
const/4 v0, 0x1
return v0
""",
"""
) ?: throw IsPremiumPurchasedFingerprint.exception
}
}

View file

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

View file

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

View file

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

View file

@ -12,11 +12,11 @@ import app.revanced.util.exception
@Patch(
name = "Hide story ads",
description = "Hides the ads in the Facebook app stories.",
compatiblePackages = [CompatiblePackage("com.facebook.katana")],
compatiblePackages = [CompatiblePackage("com.facebook.katana")]
)
@Suppress("unused")
object HideStoryAdsPatch : BytecodePatch(
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint),
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint)
) {
override fun execute(context: BytecodeContext) =
setOf(FetchMoreAdsFingerprint, AdsInsertionFingerprint).forEach { fingerprint ->

View file

@ -7,9 +7,10 @@ internal abstract class FieldMethodFingerprint(fieldValue: String) : MethodFinge
returnType = "V",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "run" && classDef.fields.any any@{ field ->
if (field.name != "__redex_internal_original_name") return@any false
(field.initialValue as? StringEncodedValue)?.value == fieldValue
}
},
methodDef.name == "run" &&
classDef.fields.any any@{ field ->
if (field.name != "__redex_internal_original_name") return@any false
(field.initialValue as? StringEncodedValue)?.value == fieldValue
}
}
)

View file

@ -12,11 +12,11 @@ import app.revanced.util.exception
@Patch(
name = "Remove bootloader detection",
description = "Removes the check for an unlocked bootloader.",
compatiblePackages = [CompatiblePackage("at.gv.bmf.bmf2go")],
compatiblePackages = [CompatiblePackage("at.gv.bmf.bmf2go")]
)
@Suppress("unused")
object BootloaderDetectionPatch : BytecodePatch(
setOf(CreateKeyFingerprint, BootStateFingerprint),
setOf(CreateKeyFingerprint, BootStateFingerprint)
) {
override fun execute(context: BytecodeContext) {
arrayOf(CreateKeyFingerprint, BootStateFingerprint).forEach { fingerprint ->
@ -25,7 +25,7 @@ object BootloaderDetectionPatch : BytecodePatch(
"""
const/4 v0, 0x1
return v0
""",
"""
) ?: throw fingerprint.exception
}
}

View file

@ -8,7 +8,8 @@ import com.android.tools.smali.dexlib2.Opcode
internal object BootStateFingerprint : MethodFingerprint(
"Z",
accessFlags = AccessFlags.PUBLIC.value,
opcodes = listOf(
opcodes =
listOf(
Opcode.INVOKE_DIRECT,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_4,
@ -25,6 +26,6 @@ internal object BootStateFingerprint : MethodFingerprint(
Opcode.IF_NE,
Opcode.GOTO,
Opcode.MOVE,
Opcode.RETURN,
),
Opcode.RETURN
)
)

View file

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

View file

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

View file

@ -10,13 +10,14 @@ internal object RootDetectionFingerprint : MethodFingerprint(
"L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("L"),
opcodes = listOf(
opcodes =
listOf(
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT,
),
Opcode.RETURN_OBJECT
)
)

View file

@ -14,11 +14,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Remove device restrictions",
description = "Removes restrictions from using the app on any device. Requires mounting patched app over original.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.recorder")],
compatiblePackages = [CompatiblePackage("com.google.android.apps.recorder")]
)
@Suppress("unused")
object RemoveDeviceRestrictions : BytecodePatch(
setOf(OnApplicationCreateFingerprint),
setOf(OnApplicationCreateFingerprint)
) {
override fun execute(context: BytecodeContext) {
OnApplicationCreateFingerprint.result?.let {

View file

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

View file

@ -10,17 +10,18 @@ import app.revanced.util.exception
@Patch(
name = "Disable ads",
compatiblePackages = [CompatiblePackage("com.myprog.hexedit")],
compatiblePackages = [CompatiblePackage("com.myprog.hexedit")]
)
@Suppress("unused")
object DisableAdsPatch : BytecodePatch(
setOf(PrimaryAdsFingerprint),
setOf(PrimaryAdsFingerprint)
) {
override fun execute(context: BytecodeContext) = PrimaryAdsFingerprint.result?.mutableMethod?.replaceInstructions(
0,
"""
override fun execute(context: BytecodeContext) =
PrimaryAdsFingerprint.result?.mutableMethod?.replaceInstructions(
0,
"""
const/4 v0, 0x1
return v0
""",
) ?: throw PrimaryAdsFingerprint.exception
"""
) ?: throw PrimaryAdsFingerprint.exception
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -10,11 +10,11 @@ import app.revanced.util.exception
@Patch(
name = "Hide ads",
compatiblePackages = [CompatiblePackage("com.nis.app")],
compatiblePackages = [CompatiblePackage("com.nis.app")]
)
@Suppress("unused")
object HideAdsPatch : BytecodePatch(
setOf(InshortsAdsFingerprint),
setOf(InshortsAdsFingerprint)
) {
override fun execute(context: BytecodeContext) {
InshortsAdsFingerprint.result?.let { result ->
@ -23,7 +23,7 @@ object HideAdsPatch : BytecodePatch(
0,
"""
return-void
""",
"""
)
}
} ?: throw InshortsAdsFingerprint.exception

View file

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

View file

@ -15,15 +15,15 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch(
name = "Hide timeline ads",
compatiblePackages = [CompatiblePackage("com.instagram.android")],
compatiblePackages = [CompatiblePackage("com.instagram.android")]
)
@Suppress("unused")
object HideTimelineAdsPatch : BytecodePatch(
setOf(
ShowAdFingerprint,
IsAdCheckOneFingerprint,
IsAdCheckTwoFingerprint,
),
IsAdCheckTwoFingerprint
)
) {
override fun execute(context: BytecodeContext) {
// The exact function of the following methods is unknown.
@ -55,7 +55,7 @@ object HideTimelineAdsPatch : BytecodePatch(
const/4 v0, 0x0 # Returning false to hide the ad.
return v0
""",
ExternalLabel("not_an_ad", getInstruction(checkIndex)),
ExternalLabel("not_an_ad", getInstruction(checkIndex))
)
}
} ?: throw ShowAdFingerprint.exception

View file

@ -9,10 +9,11 @@ internal object IsAdCheckOneFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
opcodes = listOf(
opcodes =
listOf(
Opcode.XOR_INT_LIT8,
Opcode.IF_NE,
Opcode.RETURN,
Opcode.INVOKE_VIRTUAL,
),
Opcode.INVOKE_VIRTUAL
)
)

View file

@ -9,7 +9,8 @@ internal object IsAdCheckTwoFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("L"),
opcodes = listOf(
opcodes =
listOf(
Opcode.INVOKE_INTERFACE,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
@ -17,6 +18,6 @@ internal object IsAdCheckTwoFingerprint : MethodFingerprint(
Opcode.CONST_4,
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
),
Opcode.RETURN
)
)

View file

@ -9,13 +9,14 @@ internal object ShowAdFingerprint : MethodFingerprint(
"Z",
AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.FINAL,
listOf("L", "L", "Z", "Z"),
opcodes = listOf(
opcodes =
listOf(
Opcode.SGET_OBJECT,
Opcode.IF_NE,
Opcode.IF_NEZ,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.IF_NEZ,
Opcode.RETURN,
),
Opcode.RETURN
)
)

View file

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

View file

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

View file

@ -10,11 +10,11 @@ import app.revanced.util.exception
@Patch(
name = "Disable mandatory login",
compatiblePackages = [CompatiblePackage("com.adobe.lrmobile")],
compatiblePackages = [CompatiblePackage("com.adobe.lrmobile")]
)
@Suppress("unused")
object DisableMandatoryLoginPatch : BytecodePatch(
setOf(IsLoggedInFingerprint),
setOf(IsLoggedInFingerprint)
) {
override fun execute(context: BytecodeContext) {
IsLoggedInFingerprint.result?.mutableMethod?.apply {

View file

@ -8,12 +8,13 @@ import com.android.tools.smali.dexlib2.Opcode
internal object IsLoggedInFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.FINAL,
opcodes = listOf(
opcodes =
listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.SGET_OBJECT,
Opcode.IF_NE,
Opcode.CONST_4,
Opcode.GOTO,
),
Opcode.GOTO
)
)

View file

@ -10,11 +10,11 @@ import app.revanced.util.exception
@Patch(
name = "Unlock premium",
compatiblePackages = [CompatiblePackage("com.adobe.lrmobile")],
compatiblePackages = [CompatiblePackage("com.adobe.lrmobile")]
)
@Suppress("unused")
object UnlockPremiumPatch : BytecodePatch(
setOf(HasPurchasedFingerprint),
setOf(HasPurchasedFingerprint)
) {
override fun execute(context: BytecodeContext) {
// Set hasPremium = true.

View file

@ -9,10 +9,11 @@ internal object HasPurchasedFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
strings = listOf("isPurchaseDoneRecently = true, access platform profile present? = "),
opcodes = listOf(
opcodes =
listOf(
Opcode.SGET_OBJECT,
Opcode.CONST_4,
Opcode.CONST_4,
Opcode.CONST_4,
),
Opcode.CONST_4
)
)

View file

@ -9,7 +9,7 @@ import app.revanced.util.exception
@Patch(description = "Disables Firebase license validation.")
object LicenseValidationPatch : BytecodePatch(
setOf(LicenseValidationFingerprint),
setOf(LicenseValidationFingerprint)
) {
override fun execute(context: BytecodeContext) {
LicenseValidationFingerprint.result?.apply {
@ -18,7 +18,7 @@ object LicenseValidationPatch : BytecodePatch(
"""
const/4 p0, 0x1
return p0
""",
"""
)
} ?: throw LicenseValidationFingerprint.exception
}

View file

@ -9,7 +9,8 @@ internal object LicenseValidationFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("Landroid/content/Context;"),
opcodes = listOf(
opcodes =
listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_WIDE,
Opcode.INVOKE_STATIC,
@ -19,6 +20,6 @@ internal object LicenseValidationFingerprint : MethodFingerprint(
Opcode.CONST_4,
Opcode.RETURN,
Opcode.CONST_4,
Opcode.RETURN,
),
Opcode.RETURN
)
)

View file

@ -9,7 +9,7 @@ import app.revanced.util.exception
@Patch(description = "Disables detection of incorrect signature.")
object SignatureVerificationPatch : BytecodePatch(
setOf(VerifySignatureFingerprint),
setOf(VerifySignatureFingerprint)
) {
override fun execute(context: BytecodeContext) {
VerifySignatureFingerprint.result?.apply {
@ -18,7 +18,7 @@ object SignatureVerificationPatch : BytecodePatch(
"""
const/4 p0, 0x1
return p0
""",
"""
)
} ?: throw VerifySignatureFingerprint.exception
}

View file

@ -11,7 +11,8 @@ internal object VerifySignatureFingerprint : MethodFingerprint(
returnType = "Z",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
parameters = listOf("Landroid/app/Activity;"),
opcodes = listOf(
opcodes =
listOf(
Opcode.SGET_OBJECT,
Opcode.IF_NEZ,
Opcode.INVOKE_STATIC,
@ -30,6 +31,6 @@ internal object VerifySignatureFingerprint : MethodFingerprint(
Opcode.IF_EQZ,
Opcode.CONST_4,
Opcode.RETURN,
Opcode.ADD_INT_LIT8,
),
Opcode.ADD_INT_LIT8
)
)

View file

@ -14,7 +14,7 @@ import app.revanced.util.exception
name = "Unlock pro",
dependencies = [
SignatureVerificationPatch::class,
LicenseValidationPatch::class,
LicenseValidationPatch::class
],
compatiblePackages = [
CompatiblePackage(
@ -23,14 +23,14 @@ import app.revanced.util.exception
"4.6364",
"4.6370",
"4.6375",
"4.6377",
],
),
],
"4.6377"
]
)
]
)
@Suppress("unused")
object UnlockProVersionPatch : BytecodePatch(
setOf(IsFreeVersionFingerprint),
setOf(IsFreeVersionFingerprint)
) {
override fun execute(context: BytecodeContext) {
IsFreeVersionFingerprint.result?.apply {
@ -39,7 +39,7 @@ object UnlockProVersionPatch : BytecodePatch(
"""
sget-object p0, Ljava/lang/Boolean;->FALSE:Ljava/lang/Boolean;
return-object p0
""",
"""
)
} ?: throw IsFreeVersionFingerprint.exception
}

View file

@ -10,13 +10,14 @@ internal object IsFreeVersionFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
strings = listOf("free"),
parameters = listOf("Landroid/content/Context;"),
opcodes = listOf(
opcodes =
listOf(
Opcode.SGET,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_STRING,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
),
Opcode.IF_EQZ
)
)

View file

@ -6,12 +6,13 @@ import com.android.tools.smali.dexlib2.AccessFlags
internal object LoadInboxAdsFingerprint : MethodFingerprint(
returnType = "V",
strings = listOf(
strings =
listOf(
"ads_load_begin",
"inbox_ads_fetch_start",
"inbox_ads_fetch_start"
),
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/facebook/messaging/business/inboxads/plugins/inboxads/itemsupplier/InboxAdsItemSupplierImplementation;"
},
}
)

View file

@ -11,11 +11,11 @@ import app.revanced.util.exception
@Patch(
name = "Hide inbox ads",
description = "Hides ads in inbox.",
compatiblePackages = [CompatiblePackage("com.facebook.orca")],
compatiblePackages = [CompatiblePackage("com.facebook.orca")]
)
@Suppress("unused")
object HideInboxAdsPatch : BytecodePatch(
setOf(LoadInboxAdsFingerprint),
setOf(LoadInboxAdsFingerprint)
) {
override fun execute(context: BytecodeContext) {
LoadInboxAdsFingerprint.result?.mutableMethod?.apply {

View file

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

View file

@ -7,12 +7,13 @@ internal object SwitchMessangeInputEmojiButtonFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("L", "Z"),
strings = listOf("afterTextChanged", "expression_search"),
opcodes = listOf(
opcodes =
listOf(
Opcode.IGET_OBJECT,
Opcode.IF_EQZ,
Opcode.CONST_STRING,
Opcode.GOTO,
Opcode.CONST_STRING,
Opcode.GOTO,
),
Opcode.GOTO
)
)

View file

@ -13,11 +13,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Disable switching emoji to sticker",
description = "Disables switching from emoji to sticker search mode in message input field.",
compatiblePackages = [CompatiblePackage("com.facebook.orca")],
compatiblePackages = [CompatiblePackage("com.facebook.orca")]
)
@Suppress("unused")
object DisableSwitchingEmojiToStickerPatch : BytecodePatch(
setOf(SwitchMessangeInputEmojiButtonFingerprint),
setOf(SwitchMessangeInputEmojiButtonFingerprint)
) {
override fun execute(context: BytecodeContext) {
SwitchMessangeInputEmojiButtonFingerprint.result?.let {
@ -28,7 +28,7 @@ object DisableSwitchingEmojiToStickerPatch : BytecodePatch(
replaceInstruction(
setStringIndex,
"const-string v$targetRegister, \"expression\"",
"const-string v$targetRegister, \"expression\""
)
}
} ?: throw SwitchMessangeInputEmojiButtonFingerprint.exception

View file

@ -11,11 +11,11 @@ import app.revanced.util.exception
@Patch(
name = "Disable typing indicator",
description = "Disables the indicator while typing a message.",
compatiblePackages = [CompatiblePackage("com.facebook.orca")],
compatiblePackages = [CompatiblePackage("com.facebook.orca")]
)
@Suppress("unused")
object DisableTypingIndicatorPatch : BytecodePatch(
setOf(SendTypingIndicatorFingerprint),
setOf(SendTypingIndicatorFingerprint)
) {
override fun execute(context: BytecodeContext) {
SendTypingIndicatorFingerprint.result?.mutableMethod?.replaceInstruction(0, "return-void")

View file

@ -15,11 +15,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
name = "Force English locale",
description = "Forces wearable devices to use the English locale.",
compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")],
dependencies = [FixLoginPatch::class],
dependencies = [FixLoginPatch::class]
)
@Suppress("unused")
object ForceEnglishLocalePatch : BytecodePatch(
setOf(SyncBluetoothLanguageFingerprint),
setOf(SyncBluetoothLanguageFingerprint)
) {
override fun execute(context: BytecodeContext) {
SyncBluetoothLanguageFingerprint.result?.let {
@ -31,7 +31,7 @@ object ForceEnglishLocalePatch : BytecodePatch(
replaceInstruction(
resolvePhoneLocaleInstruction,
"const-string v$registerIndexToUpdate, \"en_gb\"",
"const-string v$registerIndexToUpdate, \"en_gb\""
)
}
} ?: throw SyncBluetoothLanguageFingerprint.exception

View file

@ -8,5 +8,5 @@ internal object SyncBluetoothLanguageFingerprint : MethodFingerprint(
methodDef.definingClass == "Lcom/xiaomi/fitness/devicesettings/DeviceSettingsSyncer;" &&
methodDef.name == "syncBluetoothLanguage"
},
opcodes = listOf(Opcode.MOVE_RESULT_OBJECT),
opcodes = listOf(Opcode.MOVE_RESULT_OBJECT)
)

View file

@ -11,16 +11,16 @@ import app.revanced.util.exception
@Patch(
name = "Fix login",
description = "Fixes login for uncertified Mi Fitness app",
compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")],
compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")]
)
@Suppress("unused")
object FixLoginPatch : BytecodePatch(
setOf(XiaomiAccountManagerConstructorFingerprint),
setOf(XiaomiAccountManagerConstructorFingerprint)
) {
override fun execute(context: BytecodeContext) {
XiaomiAccountManagerConstructorFingerprint.result?.mutableMethod?.addInstruction(
0,
"const/16 p2, 0x0",
"const/16 p2, 0x0"
) ?: throw XiaomiAccountManagerConstructorFingerprint.exception
}
}

View file

@ -9,8 +9,9 @@ internal object XiaomiAccountManagerConstructorFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/xiaomi/passport/accountmanager/XiaomiAccountManager;"
},
parameters = listOf(
parameters =
listOf(
"Landroid/content/Context;",
"Z",
),
"Z"
)
)

View file

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

View file

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

View file

@ -11,17 +11,18 @@ import app.revanced.util.exception
@Patch(
name = "Hide music video ads",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
)
@Suppress("unused")
object HideMusicVideoAds : BytecodePatch(
setOf(ShowMusicVideoAdsParentFingerprint),
setOf(ShowMusicVideoAdsParentFingerprint)
) {
override fun execute(context: BytecodeContext) {
ShowMusicVideoAdsParentFingerprint.result?.let {
val showMusicVideoAdsMethod = context
.toMethodWalker(it.mutableMethod)
.nextMethod(it.scanResult.patternScanResult!!.startIndex + 1, true).getMethod() as MutableMethod
val showMusicVideoAdsMethod =
context
.toMethodWalker(it.mutableMethod)
.nextMethod(it.scanResult.patternScanResult!!.startIndex + 1, true).getMethod() as MutableMethod
showMusicVideoAdsMethod.addInstruction(0, "const/4 p1, 0x0")
} ?: throw ShowMusicVideoAdsParentFingerprint.exception
@ -30,7 +31,7 @@ object HideMusicVideoAds : BytecodePatch(
@Deprecated("This patch class has been renamed to HideMusicVideoAds.")
object MusicVideoAdsPatch : BytecodePatch(
dependencies = setOf(HideMusicVideoAds::class),
dependencies = setOf(HideMusicVideoAds::class)
) {
override fun execute(context: BytecodeContext) {
}

View file

@ -4,10 +4,11 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
internal object ShowMusicVideoAdsParentFingerprint : MethodFingerprint(
opcodes = listOf(
opcodes =
listOf(
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT
),
strings = listOf("maybeRegenerateCpnAndStatsClient called unexpectedly, but no error."),
strings = listOf("maybeRegenerateCpnAndStatsClient called unexpectedly, but no error.")
)

View file

@ -11,11 +11,11 @@ import com.android.tools.smali.dexlib2.Opcode
@Patch(
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")]
)
@Deprecated("This patch is no longer needed as the feature is now enabled by default.")
object CodecsUnlockPatch : BytecodePatch(
setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint),
setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint)
) {
override fun execute(context: BytecodeContext) {
val codecsLockResult = CodecsLockFingerprint.result!!
@ -23,14 +23,15 @@ object CodecsUnlockPatch : BytecodePatch(
val implementation = codecsLockResult.mutableMethod.implementation!!
val scanResultStartIndex = codecsLockResult.scanResult.patternScanResult!!.startIndex
val instructionIndex = scanResultStartIndex +
if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) {
// for 5.16.xx and lower
-3
} else {
// since 5.17.xx
-2
}
val instructionIndex =
scanResultStartIndex +
if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) {
// for 5.16.xx and lower
-3
} else {
// since 5.17.xx
-2
}
val allCodecsResult = AllCodecsReferenceFingerprint.result!!
val allCodecsMethod =
@ -40,7 +41,7 @@ object CodecsUnlockPatch : BytecodePatch(
implementation.replaceInstruction(
instructionIndex,
"invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction(),
"invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction()
)
}
}

View file

@ -49,7 +49,7 @@ internal object AllCodecsReferenceFingerprint : MethodFingerprint(
Opcode.MOVE_EXCEPTION,
Opcode.INVOKE_SUPER,
Opcode.MOVE_RESULT_WIDE,
Opcode.RETURN_WIDE,
Opcode.RETURN_WIDE
),
listOf("itag"),
listOf("itag")
)

View file

@ -10,7 +10,8 @@ import com.android.tools.smali.dexlib2.Opcode
internal object CodecsLockFingerprint : MethodFingerprint(
"L",
AccessFlags.PUBLIC or AccessFlags.STATIC,
opcodes = listOf(
opcodes =
listOf(
Opcode.INVOKE_DIRECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
@ -24,7 +25,7 @@ internal object CodecsLockFingerprint : MethodFingerprint(
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_OBJECT,
Opcode.RETURN_OBJECT
),
strings = listOf("eac3_supported"),
strings = listOf("eac3_supported")
)

View file

@ -11,11 +11,11 @@ import app.revanced.util.exception
@Patch(
name = "Enable exclusive audio playback",
description = "Enables the option to play audio without video.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
)
@Suppress("unused")
object EnableExclusiveAudioPlayback : BytecodePatch(
setOf(AllowExclusiveAudioPlaybackFingerprint),
setOf(AllowExclusiveAudioPlaybackFingerprint)
) {
override fun execute(context: BytecodeContext) {
AllowExclusiveAudioPlaybackFingerprint.result?.mutableMethod?.apply {
@ -24,7 +24,7 @@ object EnableExclusiveAudioPlayback : BytecodePatch(
"""
const/4 v0, 0x1
return v0
""",
"""
)
} ?: throw AllowExclusiveAudioPlaybackFingerprint.exception
}

View file

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

View file

@ -14,11 +14,11 @@ import app.revanced.util.exception
name = "Permanent repeat",
description = "Permanently remember your repeating preference even if the playlist ends or another track is played.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
use = false,
use = false
)
@Suppress("unused")
object PermanentRepeatPatch : BytecodePatch(
setOf(RepeatTrackFingerprint),
setOf(RepeatTrackFingerprint)
) {
override fun execute(context: BytecodeContext) {
RepeatTrackFingerprint.result?.let {
@ -29,7 +29,7 @@ object PermanentRepeatPatch : BytecodePatch(
addInstructionsWithLabels(
startIndex,
"goto :repeat",
ExternalLabel("repeat", getInstruction(repeatIndex)),
ExternalLabel("repeat", getInstruction(repeatIndex))
)
}
} ?: throw RepeatTrackFingerprint.exception

View file

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

View file

@ -10,10 +10,11 @@ import app.revanced.util.exception
@Patch(
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.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
use = false,
use = false
)
@Suppress("unused")
object PermanentShufflePatch : BytecodePatch(setOf(DisableShuffleFingerprint)) {
@ -25,7 +26,7 @@ object PermanentShufflePatch : BytecodePatch(setOf(DisableShuffleFingerprint)) {
@Deprecated("This patch class has been renamed to PermanentShufflePatch.")
object PermanentShuffleTogglePatch : BytecodePatch(
dependencies = setOf(PermanentShufflePatch::class),
dependencies = setOf(PermanentShufflePatch::class)
) {
override fun execute(context: BytecodeContext) {
}

View file

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

View file

@ -14,11 +14,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
name = "Hide category bar",
description = "Hides the category bar at the top of the homepage.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
use = false,
use = false
)
@Suppress("unused")
object HideCategoryBar : BytecodePatch(
setOf(ConstructCategoryBarFingerprint),
setOf(ConstructCategoryBarFingerprint)
) {
override fun execute(context: BytecodeContext) {
ConstructCategoryBarFingerprint.result?.let {
@ -31,7 +31,7 @@ object HideCategoryBar : BytecodePatch(
"""
const/16 v2, 0x8
invoke-virtual {v$register, v2}, Landroid/view/View;->setVisibility(I)V
""",
"""
)
}
} ?: throw ConstructCategoryBarFingerprint.exception
@ -40,7 +40,7 @@ object HideCategoryBar : BytecodePatch(
@Deprecated("This patch class has been renamed to HideCategoryBar.")
object CompactHeaderPatch : BytecodePatch(
dependencies = setOf(HideCategoryBar::class),
dependencies = setOf(HideCategoryBar::class)
) {
override fun execute(context: BytecodeContext) {
}

View file

@ -18,6 +18,6 @@ internal object ConstructCategoryBarFingerprint : MethodFingerprint(
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.NEW_INSTANCE,
Opcode.INVOKE_DIRECT,
),
Opcode.INVOKE_DIRECT
)
)

View file

@ -13,19 +13,19 @@ import app.revanced.util.exception
@Patch(
name = "Minimized playback",
description = "Unlocks options for picture-in-picture and background playback.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
)
@Suppress("unused")
object MinimizedPlaybackPatch : BytecodePatch(
setOf(
KidsMinimizedPlaybackPolicyControllerFingerprint,
BackgroundPlaybackDisableFingerprint,
),
BackgroundPlaybackDisableFingerprint
)
) {
override fun execute(context: BytecodeContext) {
KidsMinimizedPlaybackPolicyControllerFingerprint.result?.mutableMethod?.addInstruction(
0,
"return-void",
"return-void"
) ?: throw KidsMinimizedPlaybackPolicyControllerFingerprint.exception
BackgroundPlaybackDisableFingerprint.result?.mutableMethod?.addInstructions(
@ -33,7 +33,7 @@ object MinimizedPlaybackPatch : BytecodePatch(
"""
const/4 v0, 0x1
return v0
""",
"""
) ?: throw BackgroundPlaybackDisableFingerprint.exception
}
}

View file

@ -18,6 +18,6 @@ internal object BackgroundPlaybackDisableFingerprint : MethodFingerprint(
Opcode.IGET_OBJECT,
Opcode.IF_NEZ,
Opcode.SGET_OBJECT,
Opcode.IGET,
),
Opcode.IGET
)
)

View file

@ -21,6 +21,6 @@ internal object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerp
Opcode.SGET_OBJECT,
Opcode.CONST_4,
Opcode.IF_NE,
Opcode.IPUT_BOOLEAN,
),
Opcode.IPUT_BOOLEAN
)
)

View file

@ -14,11 +14,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
@Patch(
name = "Hide 'Get Music Premium' label",
description = "Hides the red \"Get Music Premium\" label from the account menu.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
)
@Suppress("unused")
object HideGetPremiumPatch : BytecodePatch(
setOf(HideGetPremiumFingerprint),
setOf(HideGetPremiumFingerprint)
) {
override fun execute(context: BytecodeContext) {
HideGetPremiumFingerprint.result?.let {
@ -31,13 +31,13 @@ object HideGetPremiumPatch : BytecodePatch(
replaceInstruction(
insertIndex,
"const/16 v$visibilityRegister, 0x8",
"const/16 v$visibilityRegister, 0x8"
)
addInstruction(
insertIndex + 1,
"invoke-virtual {v$getPremiumViewRegister, v$visibilityRegister}, " +
"Landroid/view/View;->setVisibility(I)V",
"Landroid/view/View;->setVisibility(I)V"
)
}
} ?: throw HideGetPremiumFingerprint.exception

View file

@ -12,7 +12,7 @@ internal object HideGetPremiumFingerprint : MethodFingerprint(
listOf(
Opcode.IF_NEZ,
Opcode.CONST_16,
Opcode.INVOKE_VIRTUAL,
Opcode.INVOKE_VIRTUAL
),
listOf("FEmusic_history", "FEmusic_offline"),
listOf("FEmusic_history", "FEmusic_offline")
)

View file

@ -22,22 +22,24 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
@Patch(
name = "Remove upgrade button",
description = "Removes the upgrade tab from the pivot bar.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
)
@Suppress("unused")
object RemoveUpgradeButtonPatch : BytecodePatch(
setOf(PivotBarConstructorFingerprint),
setOf(PivotBarConstructorFingerprint)
) {
override fun execute(context: BytecodeContext) {
PivotBarConstructorFingerprint.result?.let {
it.mutableMethod.apply {
val pivotBarElementFieldReference = getInstruction(it.scanResult.patternScanResult!!.endIndex - 1)
.getReference<FieldReference>()
val pivotBarElementFieldReference =
getInstruction(it.scanResult.patternScanResult!!.endIndex - 1)
.getReference<FieldReference>()
val register = (getInstructions().first() as Instruction35c).registerC
// First compile all the needed instructions.
val instructionList = """
val instructionList =
"""
invoke-interface { v0 }, Ljava/util/List;->size()I
move-result v1
const/4 v2, 0x4
@ -50,7 +52,7 @@ object RemoveUpgradeButtonPatch : BytecodePatch(
// Replace the instruction to retain the label at given index.
replaceInstruction(
endIndex - 1,
instructionList[0], // invoke-interface.
instructionList[0] // invoke-interface.
)
// Do not forget to remove this instruction since we added it already.
instructionList.removeFirst()
@ -58,7 +60,7 @@ object RemoveUpgradeButtonPatch : BytecodePatch(
val exitInstruction = instructionList.last() // iput-object
addInstruction(
endIndex,
exitInstruction,
exitInstruction
)
// Do not forget to remove this instruction since we added it already.
instructionList.removeLast()
@ -70,13 +72,13 @@ object RemoveUpgradeButtonPatch : BytecodePatch(
Opcode.IF_LE,
1,
2,
newLabel(endIndex),
),
newLabel(endIndex)
)
)
addInstructions(
endIndex,
instructionList,
instructionList
)
}
} ?: throw PivotBarConstructorFingerprint.exception

View file

@ -14,6 +14,6 @@ internal object PivotBarConstructorFingerprint : MethodFingerprint(
Opcode.INVOKE_INTERFACE,
Opcode.GOTO,
Opcode.IPUT_OBJECT,
Opcode.RETURN_VOID,
),
Opcode.RETURN_VOID
)
)

View file

@ -11,7 +11,7 @@ import app.revanced.util.exception
@Patch(
name = "Bypass certificate checks",
description = "Bypasses certificate checks which prevent YouTube Music from working on Android Auto.",
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")]
)
@Suppress("unused")
object BypassCertificateChecksPatch : BytecodePatch(setOf(CheckCertificateFingerprint)) {
@ -22,7 +22,7 @@ object BypassCertificateChecksPatch : BytecodePatch(setOf(CheckCertificateFinger
"""
const/4 v0, 0x1
return v0
""",
"""
)
} ?: throw CheckCertificateFingerprint.exception
}

View file

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

View file

@ -14,25 +14,27 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
fromPackageName = MUSIC_PACKAGE_NAME,
toPackageName = REVANCED_MUSIC_PACKAGE_NAME,
primeMethodFingerprint = PrimeMethodFingerprint,
earlyReturnFingerprints = setOf(
earlyReturnFingerprints =
setOf(
ServiceCheckFingerprint,
GooglePlayUtilityFingerprint,
CastDynamiteModuleFingerprint,
CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint,
CastContextFetchFingerprint
),
mainActivityOnCreateFingerprint = ApplicationInitFingerprint,
integrationsPatchDependency = IntegrationsPatch::class,
gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch,
compatiblePackages = setOf(CompatiblePackage("com.google.android.apps.youtube.music")),
fingerprints = setOf(
fingerprints =
setOf(
ServiceCheckFingerprint,
GooglePlayUtilityFingerprint,
CastDynamiteModuleFingerprint,
CastDynamiteModuleV2Fingerprint,
CastContextFetchFingerprint,
PrimeMethodFingerprint,
),
PrimeMethodFingerprint
)
) {
override val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption
}

View file

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

View file

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

View file

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

View file

@ -8,11 +8,12 @@ internal object GooglePlayUtilityFingerprint : MethodFingerprint(
"I",
AccessFlags.PUBLIC or AccessFlags.STATIC,
listOf("L", "I"),
strings = listOf(
strings =
listOf(
"This should never happen.",
"MetadataValueReader",
"GooglePlayServicesUtil",
"com.android.vending",
"android.hardware.type.embedded",
),
"android.hardware.type.embedded"
)
)

View file

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

View file

@ -8,5 +8,5 @@ internal object ServiceCheckFingerprint : MethodFingerprint(
"V",
AccessFlags.PUBLIC or AccessFlags.STATIC,
listOf("L", "I"),
strings = listOf("Google Play Services not available"),
strings = listOf("Google Play Services not available")
)

View file

@ -6,5 +6,5 @@ import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
@Patch(requiresIntegrations = true)
object IntegrationsPatch : BaseIntegrationsPatch(
setOf(ApplicationInitFingerprint),
setOf(ApplicationInitFingerprint)
)

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