begin migration

This commit is contained in:
oSumAtrIX
2026-01-08 11:56:03 +01:00
parent b6cc108fba
commit 69a71fbd3a
16 changed files with 103 additions and 119 deletions

View File

@@ -13,7 +13,7 @@ retrofit = "3.0.0"
guava = "33.5.0-jre"
protobuf-javalite = "4.33.2"
protoc = "4.33.2"
protobuf = "0.9.5"
protobuf = "0.9.6"
antlr4 = "4.13.2"
nanohttpd = "2.3.1"
apksig = "8.12.3"

View File

@@ -1,10 +1,10 @@
package app.revanced.patches.all.misc.activity.exportall
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.creatingResourcePatch
@Suppress("unused")
val exportAllActivitiesPatch = resourcePatch(
name = "Export all activities",
@Suppress("unused", "ObjectPropertyName")
val `"Export all activities"` by creatingResourcePatch(
description = "Makes all app activities exportable.",
use = false,
) {

View File

@@ -1,7 +1,7 @@
package app.revanced.patches.all.misc.adb
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.creatingBytecodePatch
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.Opcode
@@ -26,31 +26,27 @@ private val SETTINGS_GLOBAL_GET_INT_OR_DEFAULT_METHOD_REFERENCE = ImmutableMetho
"I"
)
private fun MethodReference.anyMethodSignatureMatches(vararg anyOf: MethodReference): Boolean {
return anyOf.any {
MethodUtil.methodSignaturesMatch(it, this)
}
}
private val getIntMethodReferences = listOf(
SETTINGS_GLOBAL_GET_INT_OR_THROW_METHOD_REFERENCE,
SETTINGS_GLOBAL_GET_INT_OR_DEFAULT_METHOD_REFERENCE
)
@Suppress("unused")
val hideAdbStatusPatch = bytecodePatch(
name = "Hide ADB status",
@Suppress("unused", "ObjectPropertyName")
val `Hide ADB status` by creatingBytecodePatch(
description = "Hides enabled development settings and/or ADB.",
use = false,
) {
extendWith("extensions/all/misc/adb/hide-adb.rve")
dependsOn(
transformInstructionsPatch(
filterMap = filterMap@{ classDef, method, instruction, instructionIndex ->
val reference = instruction
.takeIf { it.opcode == Opcode.INVOKE_STATIC }
?.getReference<MethodReference>()
?.takeIf {
it.anyMethodSignatureMatches(
SETTINGS_GLOBAL_GET_INT_OR_THROW_METHOD_REFERENCE,
SETTINGS_GLOBAL_GET_INT_OR_DEFAULT_METHOD_REFERENCE
)
?.takeIf { reference ->
getIntMethodReferences.any { MethodUtil.methodSignaturesMatch(it, reference) }
}
?: return@filterMap null

View File

@@ -1,14 +1,13 @@
package app.revanced.patches.all.misc.appicon
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.creatingResourcePatch
import app.revanced.util.asSequence
import app.revanced.util.childElementsSequence
import java.util.logging.Logger
import org.w3c.dom.Element
import java.util.logging.Logger
@Suppress("unused")
val hideAppIconPatch = resourcePatch(
name = "Hide app icon",
@Suppress("unused", "ObjectPropertyName")
val `Hide app icon` by creatingResourcePatch(
description = "Hides the app icon from the Android launcher.",
use = false,
) {
@@ -26,6 +25,7 @@ val hideAppIconPatch = resourcePatch(
"action" -> if (child.getAttribute("android:name") == "android.intent.action.MAIN") {
hasMainAction = true
}
"category" -> if (child.getAttribute("android:name") == "android.intent.category.LAUNCHER") {
launcherCategory = child
}

View File

@@ -3,7 +3,7 @@
package app.revanced.patches.all.misc.connectivity.location.hide
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.creatingBytecodePatch
import app.revanced.patches.all.misc.transformation.IMethodCall
import app.revanced.patches.all.misc.transformation.fromMethodReference
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
@@ -11,9 +11,8 @@ import app.revanced.util.getReference
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@Suppress("unused")
val hideMockLocationPatch = bytecodePatch(
name = "Hide mock location",
@Suppress("unused", "ObjectPropertyName")
val `Hide mock location` by creatingBytecodePatch(
description = "Prevents the app from knowing the device location is being mocked by a third party app.",
use = false,
) {

View File

@@ -1,10 +1,10 @@
package app.revanced.patches.all.misc.debugging
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.creatingResourcePatch
import org.w3c.dom.Element
val enableAndroidDebuggingPatch = resourcePatch(
name = "Enable Android debugging",
@Suppress("ObjectPropertyName", "unused")
val `Enable Android debugging` by creatingResourcePatch(
description = "Enables Android debugging capabilities. This can slow down the app.",
use = false,
) {

View File

@@ -1,10 +1,9 @@
package app.revanced.patches.all.misc.interaction.gestures
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.creatingResourcePatch
@Suppress("unused")
val predictiveBackGesturePatch = resourcePatch(
name = "Predictive back gesture",
@Suppress("unused", "ObjectPropertyName")
val `Predictive back gesture` by creatingResourcePatch(
description = "Enables the predictive back gesture introduced on Android 13.",
use = false,
) {

View File

@@ -1,14 +1,15 @@
@file:Suppress("ObjectPropertyName")
package app.revanced.patches.all.misc.network
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patcher.patch.creatingResourcePatch
import app.revanced.patches.all.misc.debugging.enableAndroidDebuggingPatch
import app.revanced.util.Utils.trimIndentMultiline
import org.w3c.dom.Element
import java.io.File
@Suppress("unused")
val overrideCertificatePinningPatch = resourcePatch(
name = "Override certificate pinning",
val `Override certificate pinning` by creatingResourcePatch(
description = "Overrides certificate pinning, allowing to inspect traffic via a proxy.",
use = false,
) {

View File

@@ -1,6 +1,6 @@
package app.revanced.patches.all.misc.screencapture
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.creatingBytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.all.misc.transformation.IMethodCall
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
@@ -28,9 +28,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/extension/all/misc/screencapture/removerestriction/RemoveScreenCaptureRestrictionPatch"
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
@Suppress("unused")
val removeScreenCaptureRestrictionPatch = bytecodePatch(
name = "Remove screen capture restriction",
@Suppress("unused", "ObjectPropertyName")
val `Remove screen capture restriction` by creatingBytecodePatch(
description = "Removes the restriction of capturing audio from apps that normally wouldn't allow it.",
use = false,
) {

View File

@@ -1,7 +1,7 @@
package app.revanced.patches.all.misc.screenshot
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patcher.patch.creatingBytecodePatch
import app.revanced.patches.all.misc.transformation.IMethodCall
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
@@ -13,9 +13,8 @@ private const val EXTENSION_CLASS_DESCRIPTOR_PREFIX =
"Lapp/revanced/extension/all/misc/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
@Suppress("unused")
val removeScreenshotRestrictionPatch = bytecodePatch(
name = "Remove screenshot restriction",
@Suppress("unused", "ObjectPropertyName")
val `Remove screenshot restriction` by creatingBytecodePatch(
description = "Removes the restriction of taking screenshots in apps that normally wouldn't allow it.",
use = false,
) {

View File

@@ -10,14 +10,14 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private var getApplicationContextIndex = -1
internal val startActivityInitHook = extensionHook(
insertIndexResolver = { method ->
getInsertIndex = { method ->
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "getApplicationContext"
}
getApplicationContextIndex + 2 // Below the move-result-object instruction.
},
contextRegisterResolver = { method ->
getContextRegister = { method ->
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1)
as OneRegisterInstruction
"v${moveResultInstruction.registerA}"

View File

@@ -10,14 +10,14 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private var getApplicationContextIndex = -1
internal val homeActivityInitHook = extensionHook(
insertIndexResolver = { method ->
getInsertIndex = { method ->
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow {
getReference<MethodReference>()?.name == "getApplicationContext"
}
getApplicationContextIndex + 2 // Below the move-result-object instruction.
},
contextRegisterResolver = { method ->
getContextRegister = { method ->
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1)
as OneRegisterInstruction
"v${moveResultInstruction.registerA}"

View File

@@ -1,13 +1,14 @@
package app.revanced.patches.shared.misc.extension
import app.revanced.patcher.fingerprint
import app.revanced.patcher.*
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
import app.revanced.patcher.patch.BytecodePatchContext
import com.android.tools.smali.dexlib2.AccessFlags
internal val revancedUtilsPatchesVersionFingerprint = fingerprint {
internal val BytecodePatchContext.getPatchesReleaseVersionMethod by gettingFirstMutableMethodDeclaratively {
name("getPatchesReleaseVersion")
definingClass(EXTENSION_CLASS_DESCRIPTOR)
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Ljava/lang/String;")
parameters()
custom { method, _ ->
method.name == "getPatchesReleaseVersion" && method.definingClass == EXTENSION_CLASS_DESCRIPTOR
}
returnType("Ljava/lang/String;")
parameterTypes()
}

View File

@@ -1,10 +1,9 @@
package app.revanced.patches.shared.misc.extension
import app.revanced.patcher.*
import app.revanced.patcher.BytecodePatchContextClassDefMatching.firstMutableClassDef
import app.revanced.patcher.Fingerprint
import app.revanced.patcher.FingerprintBuilder
import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMutableMethodDeclaratively
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.fingerprint
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.util.returnEarly
@@ -49,52 +48,52 @@ fun sharedExtensionPatch(
hooks.forEach { hook -> hook()(EXTENSION_CLASS_DESCRIPTOR) }
// Modify Utils method to include the patches release version.
revancedUtilsPatchesVersionFingerprint.method.apply {
/**
* @return The file path for the jar this classfile is contained inside.
*/
fun getCurrentJarFilePath(): String {
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
val classUrl = object {}::class.java.classLoader?.getResource(className)
if (classUrl != null) {
val urlString = classUrl.toString()
/**
* @return The file path for the jar this classfile is contained inside.
*/
fun getCurrentJarFilePath(): String {
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
val classUrl = object {}::class.java.classLoader?.getResource(className)
if (classUrl != null) {
val urlString = classUrl.toString()
if (urlString.startsWith("jar:file:")) {
val end = urlString.lastIndexOf('!')
if (urlString.startsWith("jar:file:")) {
val end = urlString.lastIndexOf('!')
return URLDecoder.decode(urlString.substring("jar:file:".length, end), "UTF-8")
}
return URLDecoder.decode(urlString.substring("jar:file:".length, end), "UTF-8")
}
throw IllegalStateException("Not running from inside a JAR file.")
}
/**
* @return The value for the manifest entry,
* or "Unknown" if the entry does not exist or is blank.
*/
@Suppress("SameParameterValue")
fun getPatchesManifestEntry(attributeKey: String) = JarFile(getCurrentJarFilePath()).use { jarFile ->
jarFile.manifest.mainAttributes.entries.firstOrNull { it.key.toString() == attributeKey }?.value?.toString()
?: "Unknown"
}
val manifestValue = getPatchesManifestEntry("Version")
returnEarly(manifestValue)
throw IllegalStateException("Not running from inside a JAR file.")
}
/**
* @return The value for the manifest entry,
* or "Unknown" if the entry does not exist or is blank.
*/
@Suppress("SameParameterValue")
fun getPatchesManifestEntry(attributeKey: String) = JarFile(getCurrentJarFilePath()).use { jarFile ->
jarFile.manifest.mainAttributes.entries.firstOrNull { it.key.toString() == attributeKey }?.value?.toString()
?: "Unknown"
}
val manifestValue = getPatchesManifestEntry("Version")
getPatchesReleaseVersionMethod.returnEarly(manifestValue)
}
}
class ExtensionHook internal constructor(
internal val fingerprint: Fingerprint,
private val insertIndexResolver: context(BytecodePatchContext) (Method) -> Int,
private val contextRegisterResolver: context(BytecodePatchContext) (Method) -> String,
private val getInsertIndex: Method.() -> Int,
private val getContextRegister: Method.() -> String,
private val predicate: DeclarativePredicate<Method>,
) {
context(_: BytecodePatchContext)
context(context: BytecodePatchContext)
operator fun invoke(extensionClassDescriptor: String) {
val insertIndex = insertIndexResolver(fingerprint.method)
val contextRegister = contextRegisterResolver(fingerprint.method)
val method = context.firstMutableMethodDeclaratively(predicate = predicate)
val insertIndex = method.getInsertIndex()
val contextRegister = method.getContextRegister()
fingerprint.method.addInstruction(
method.addInstruction(
insertIndex,
"invoke-static/range { $contextRegister .. $contextRegister }, " +
"$extensionClassDescriptor->setContext(Landroid/content/Context;)V",
@@ -103,19 +102,10 @@ class ExtensionHook internal constructor(
}
fun extensionHook(
insertIndexResolver: context(BytecodePatchContext) (Method) -> Int = { 0 },
contextRegisterResolver: context(BytecodePatchContext) (Method) -> String = { "p0" },
fingerprint: Fingerprint,
) = ExtensionHook(fingerprint, insertIndexResolver, contextRegisterResolver)
fun extensionHook(
insertIndexResolver: context(BytecodePatchContext) (Method) -> Int = { 0 },
contextRegisterResolver: context(BytecodePatchContext) (Method) -> String = { "p0" },
fingerprintBuilderBlock: FingerprintBuilder.() -> Unit,
) = {
->
ExtensionHook(fingerprint(block = fingerprintBuilderBlock), insertIndexResolver, contextRegisterResolver)
}
getInsertIndex: Method.() -> Int = { 0 },
getContextRegister: Method.() -> String = { "p0" },
predicate: DeclarativePredicate<Method>,
) = ExtensionHook(getInsertIndex, getContextRegister, predicate)
/**
* Creates an extension hook from a non-obfuscated activity, which typically is the main activity
@@ -124,7 +114,7 @@ fun extensionHook(
* @param activityClassType Either the full activity class type such as `Lcom/company/MainActivity;`
* or the 'ends with' string for the activity such as `/MainActivity;`
*/
fun activityOnCreateExtensionHook(activityClassType: String): () -> ExtensionHook {
fun activityOnCreateExtensionHook(activityClassType: String): ExtensionHook {
if (!activityClassType.endsWith(';')) {
throw IllegalArgumentException("Activity class type does not end with semicolon: $activityClassType")
}
@@ -132,12 +122,12 @@ fun activityOnCreateExtensionHook(activityClassType: String): () -> ExtensionHoo
val fullClassType = activityClassType.startsWith('L')
return extensionHook {
returns("V")
parameters("Landroid/os/Bundle;")
custom { method, classDef ->
method.name == "onCreate" &&
if (fullClassType) classDef.type == activityClassType
else classDef.type.endsWith(activityClassType)
}
name("onCreate")
if (fullClassType) definingClass(activityClassType)
else definingClass { endsWith(activityClassType) }
returnType("V")
parameterTypes("Landroid/os/Bundle;")
}
}

View File

@@ -13,10 +13,10 @@ internal val mainActivityOnCreateHook = extensionHook { mainActivityOnCreateFing
internal val loadOrbitLibraryHook = extensionHook {
// FIXME: Creating this is a mess and needs refactoring.
extensionHook(
insertIndexResolver = {
getInsertIndex = {
loadOrbitLibraryFingerprint.stringMatches.last().index
},
contextRegisterResolver = { method ->
getContextRegister = { method ->
val contextReferenceIndex = method.indexOfFirstInstruction {
getReference<FieldReference>()?.type == "Landroid/content/Context;"
}

View File

@@ -14,7 +14,7 @@ internal val initHook = activityOnCreateExtensionHook(
* This class is called from startup code titled "BPEA RunnableGuardLancet".
*/
internal val jatoInitHook = extensionHook(
contextRegisterResolver = { "p1" }
getContextRegister = { "p1" }
) {
parameters("Landroid/content/Context;")
custom { method, classDef ->
@@ -24,7 +24,7 @@ internal val jatoInitHook = extensionHook(
}
internal val storeRegionInitHook = extensionHook(
contextRegisterResolver = { "p1" }
getContextRegister = { "p1" }
) {
parameters("Landroid/content/Context;")
custom { method, classDef ->