mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2024-11-10 01:01:56 +01:00
chore: Changes from gradle ktlintformat
task
This commit is contained in:
parent
57012c0e58
commit
e925ed6eb3
616 changed files with 3063 additions and 2614 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ internal object IsPremiumPurchasedFingerprint : MethodFingerprint(
|
|||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("PreferenceProvider;") &&
|
||||
methodDef.name == "isPremiumPurchased"
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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 ->
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -8,5 +8,5 @@ internal object OnApplicationCreateFingerprint : MethodFingerprint(
|
|||
if (methodDef.name != "onCreate") return@custom false
|
||||
|
||||
classDef.type.endsWith("RecorderApplication;")
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -5,5 +5,5 @@ import app.revanced.patcher.fingerprint.MethodFingerprint
|
|||
internal object PrimaryAdsFingerprint : MethodFingerprint(
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("PreferencesHelper;") && methodDef.name == "isAdsDisabled"
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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
|
||||
""",
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;") }
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -9,5 +9,5 @@ internal object AttestationSupportedCheckFingerprint : MethodFingerprint(
|
|||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.name == "attestationSupportCheck" &&
|
||||
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -9,5 +9,5 @@ internal object BootloaderCheckFingerprint : MethodFingerprint(
|
|||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.name == "bootloaderCheck" &&
|
||||
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -9,5 +9,5 @@ internal object RootCheckFingerprint : MethodFingerprint(
|
|||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.name == "rootCheck" &&
|
||||
methodDef.definingClass.endsWith("/DeviceIntegrityCheck;")
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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
|
||||
""",
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,5 +9,5 @@ internal object SpoofSignatureFingerprint : MethodFingerprint(
|
|||
accessFlags = AccessFlags.PRIVATE.value,
|
||||
customFingerprint = { methodDef, _ ->
|
||||
methodDef.definingClass.endsWith("/SL2Step1Task;") && methodDef.name == "getPubKey"
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,5 +8,5 @@ internal object IrplusAdsFingerprint : MethodFingerprint(
|
|||
"V",
|
||||
AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||
listOf("L", "Z"),
|
||||
strings = listOf("TAGGED"),
|
||||
strings = listOf("TAGGED")
|
||||
)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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;"
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
""",
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;")
|
||||
},
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -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.")
|
||||
)
|
||||
|
|
|
@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -20,6 +20,6 @@ internal object AllowExclusiveAudioPlaybackFingerprint : MethodFingerprint(
|
|||
Opcode.GOTO,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.RETURN,
|
||||
),
|
||||
Opcode.RETURN
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,6 +17,6 @@ internal object RepeatTrackFingerprint : MethodFingerprint(
|
|||
Opcode.SGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.IF_NEZ,
|
||||
),
|
||||
Opcode.IF_NEZ
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@ internal object DisableShuffleFingerprint : MethodFingerprint(
|
|||
Opcode.SGET_OBJECT,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.IGET_OBJECT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
),
|
||||
Opcode.INVOKE_VIRTUAL
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -18,6 +18,6 @@ internal object ConstructCategoryBarFingerprint : MethodFingerprint(
|
|||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.NEW_INSTANCE,
|
||||
Opcode.INVOKE_DIRECT,
|
||||
),
|
||||
Opcode.INVOKE_DIRECT
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,6 @@ internal object BackgroundPlaybackDisableFingerprint : MethodFingerprint(
|
|||
Opcode.IGET_OBJECT,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.SGET_OBJECT,
|
||||
Opcode.IGET,
|
||||
),
|
||||
Opcode.IGET
|
||||
)
|
||||
)
|
||||
|
|
|
@ -21,6 +21,6 @@ internal object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerp
|
|||
Opcode.SGET_OBJECT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_NE,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
),
|
||||
Opcode.IPUT_BOOLEAN
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -14,6 +14,6 @@ internal object PivotBarConstructorFingerprint : MethodFingerprint(
|
|||
Opcode.INVOKE_INTERFACE,
|
||||
Opcode.GOTO,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.RETURN_VOID,
|
||||
),
|
||||
Opcode.RETURN_VOID
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.")
|
||||
)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
|
|
|
@ -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: ")
|
||||
)
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
)
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue