begin migration
This commit is contained in:
parent
b6cc108fba
commit
69a71fbd3a
16 changed files with 103 additions and 119 deletions
|
|
@ -13,7 +13,7 @@ retrofit = "3.0.0"
|
||||||
guava = "33.5.0-jre"
|
guava = "33.5.0-jre"
|
||||||
protobuf-javalite = "4.33.2"
|
protobuf-javalite = "4.33.2"
|
||||||
protoc = "4.33.2"
|
protoc = "4.33.2"
|
||||||
protobuf = "0.9.5"
|
protobuf = "0.9.6"
|
||||||
antlr4 = "4.13.2"
|
antlr4 = "4.13.2"
|
||||||
nanohttpd = "2.3.1"
|
nanohttpd = "2.3.1"
|
||||||
apksig = "8.12.3"
|
apksig = "8.12.3"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package app.revanced.patches.all.misc.activity.exportall
|
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(
|
@Suppress("unused", "ObjectPropertyName")
|
||||||
name = "Export all activities",
|
val `"Export all activities"` by creatingResourcePatch(
|
||||||
description = "Makes all app activities exportable.",
|
description = "Makes all app activities exportable.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package app.revanced.patches.all.misc.adb
|
package app.revanced.patches.all.misc.adb
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.replaceInstruction
|
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.patches.all.misc.transformation.transformInstructionsPatch
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
@ -26,31 +26,27 @@ private val SETTINGS_GLOBAL_GET_INT_OR_DEFAULT_METHOD_REFERENCE = ImmutableMetho
|
||||||
"I"
|
"I"
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun MethodReference.anyMethodSignatureMatches(vararg anyOf: MethodReference): Boolean {
|
private val getIntMethodReferences = listOf(
|
||||||
return anyOf.any {
|
SETTINGS_GLOBAL_GET_INT_OR_THROW_METHOD_REFERENCE,
|
||||||
MethodUtil.methodSignaturesMatch(it, this)
|
SETTINGS_GLOBAL_GET_INT_OR_DEFAULT_METHOD_REFERENCE
|
||||||
}
|
)
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused", "ObjectPropertyName")
|
||||||
val hideAdbStatusPatch = bytecodePatch(
|
val `Hide ADB status` by creatingBytecodePatch(
|
||||||
name = "Hide ADB status",
|
|
||||||
description = "Hides enabled development settings and/or ADB.",
|
description = "Hides enabled development settings and/or ADB.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
extendWith("extensions/all/misc/adb/hide-adb.rve")
|
extendWith("extensions/all/misc/adb/hide-adb.rve")
|
||||||
|
|
||||||
|
|
||||||
dependsOn(
|
dependsOn(
|
||||||
transformInstructionsPatch(
|
transformInstructionsPatch(
|
||||||
filterMap = filterMap@{ classDef, method, instruction, instructionIndex ->
|
filterMap = filterMap@{ classDef, method, instruction, instructionIndex ->
|
||||||
val reference = instruction
|
val reference = instruction
|
||||||
.takeIf { it.opcode == Opcode.INVOKE_STATIC }
|
.takeIf { it.opcode == Opcode.INVOKE_STATIC }
|
||||||
?.getReference<MethodReference>()
|
?.getReference<MethodReference>()
|
||||||
?.takeIf {
|
?.takeIf { reference ->
|
||||||
it.anyMethodSignatureMatches(
|
getIntMethodReferences.any { MethodUtil.methodSignaturesMatch(it, reference) }
|
||||||
SETTINGS_GLOBAL_GET_INT_OR_THROW_METHOD_REFERENCE,
|
|
||||||
SETTINGS_GLOBAL_GET_INT_OR_DEFAULT_METHOD_REFERENCE
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
?: return@filterMap null
|
?: return@filterMap null
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
package app.revanced.patches.all.misc.appicon
|
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.asSequence
|
||||||
import app.revanced.util.childElementsSequence
|
import app.revanced.util.childElementsSequence
|
||||||
import java.util.logging.Logger
|
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
import java.util.logging.Logger
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused", "ObjectPropertyName")
|
||||||
val hideAppIconPatch = resourcePatch(
|
val `Hide app icon` by creatingResourcePatch(
|
||||||
name = "Hide app icon",
|
|
||||||
description = "Hides the app icon from the Android launcher.",
|
description = "Hides the app icon from the Android launcher.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
|
|
@ -26,6 +25,7 @@ val hideAppIconPatch = resourcePatch(
|
||||||
"action" -> if (child.getAttribute("android:name") == "android.intent.action.MAIN") {
|
"action" -> if (child.getAttribute("android:name") == "android.intent.action.MAIN") {
|
||||||
hasMainAction = true
|
hasMainAction = true
|
||||||
}
|
}
|
||||||
|
|
||||||
"category" -> if (child.getAttribute("android:name") == "android.intent.category.LAUNCHER") {
|
"category" -> if (child.getAttribute("android:name") == "android.intent.category.LAUNCHER") {
|
||||||
launcherCategory = child
|
launcherCategory = child
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
package app.revanced.patches.all.misc.connectivity.location.hide
|
package app.revanced.patches.all.misc.connectivity.location.hide
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.replaceInstruction
|
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.IMethodCall
|
||||||
import app.revanced.patches.all.misc.transformation.fromMethodReference
|
import app.revanced.patches.all.misc.transformation.fromMethodReference
|
||||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
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.instruction.FiveRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused", "ObjectPropertyName")
|
||||||
val hideMockLocationPatch = bytecodePatch(
|
val `Hide mock location` by creatingBytecodePatch(
|
||||||
name = "Hide mock location",
|
|
||||||
description = "Prevents the app from knowing the device location is being mocked by a third party app.",
|
description = "Prevents the app from knowing the device location is being mocked by a third party app.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
package app.revanced.patches.all.misc.debugging
|
package app.revanced.patches.all.misc.debugging
|
||||||
|
|
||||||
import app.revanced.patcher.patch.resourcePatch
|
import app.revanced.patcher.patch.creatingResourcePatch
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
|
|
||||||
val enableAndroidDebuggingPatch = resourcePatch(
|
@Suppress("ObjectPropertyName", "unused")
|
||||||
name = "Enable Android debugging",
|
val `Enable Android debugging` by creatingResourcePatch(
|
||||||
description = "Enables Android debugging capabilities. This can slow down the app.",
|
description = "Enables Android debugging capabilities. This can slow down the app.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
package app.revanced.patches.all.misc.interaction.gestures
|
package app.revanced.patches.all.misc.interaction.gestures
|
||||||
|
|
||||||
import app.revanced.patcher.patch.resourcePatch
|
import app.revanced.patcher.patch.creatingResourcePatch
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused", "ObjectPropertyName")
|
||||||
val predictiveBackGesturePatch = resourcePatch(
|
val `Predictive back gesture` by creatingResourcePatch(
|
||||||
name = "Predictive back gesture",
|
|
||||||
description = "Enables the predictive back gesture introduced on Android 13.",
|
description = "Enables the predictive back gesture introduced on Android 13.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
|
@file:Suppress("ObjectPropertyName")
|
||||||
|
|
||||||
package app.revanced.patches.all.misc.network
|
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.patches.all.misc.debugging.enableAndroidDebuggingPatch
|
||||||
import app.revanced.util.Utils.trimIndentMultiline
|
import app.revanced.util.Utils.trimIndentMultiline
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val overrideCertificatePinningPatch = resourcePatch(
|
val `Override certificate pinning` by creatingResourcePatch(
|
||||||
name = "Override certificate pinning",
|
|
||||||
description = "Overrides certificate pinning, allowing to inspect traffic via a proxy.",
|
description = "Overrides certificate pinning, allowing to inspect traffic via a proxy.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package app.revanced.patches.all.misc.screencapture
|
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.patcher.patch.resourcePatch
|
||||||
import app.revanced.patches.all.misc.transformation.IMethodCall
|
import app.revanced.patches.all.misc.transformation.IMethodCall
|
||||||
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
|
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"
|
"Lapp/revanced/extension/all/misc/screencapture/removerestriction/RemoveScreenCaptureRestrictionPatch"
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
|
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused", "ObjectPropertyName")
|
||||||
val removeScreenCaptureRestrictionPatch = bytecodePatch(
|
val `Remove screen capture restriction` by creatingBytecodePatch(
|
||||||
name = "Remove screen capture restriction",
|
|
||||||
description = "Removes the restriction of capturing audio from apps that normally wouldn't allow it.",
|
description = "Removes the restriction of capturing audio from apps that normally wouldn't allow it.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package app.revanced.patches.all.misc.screenshot
|
package app.revanced.patches.all.misc.screenshot
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
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.IMethodCall
|
||||||
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
|
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
|
||||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
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"
|
"Lapp/revanced/extension/all/misc/screenshot/removerestriction/RemoveScreenshotRestrictionPatch"
|
||||||
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
|
private const val EXTENSION_CLASS_DESCRIPTOR = "$EXTENSION_CLASS_DESCRIPTOR_PREFIX;"
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused", "ObjectPropertyName")
|
||||||
val removeScreenshotRestrictionPatch = bytecodePatch(
|
val `Remove screenshot restriction` by creatingBytecodePatch(
|
||||||
name = "Remove screenshot restriction",
|
|
||||||
description = "Removes the restriction of taking screenshots in apps that normally wouldn't allow it.",
|
description = "Removes the restriction of taking screenshots in apps that normally wouldn't allow it.",
|
||||||
use = false,
|
use = false,
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
private var getApplicationContextIndex = -1
|
private var getApplicationContextIndex = -1
|
||||||
|
|
||||||
internal val startActivityInitHook = extensionHook(
|
internal val startActivityInitHook = extensionHook(
|
||||||
insertIndexResolver = { method ->
|
getInsertIndex = { method ->
|
||||||
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow {
|
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow {
|
||||||
getReference<MethodReference>()?.name == "getApplicationContext"
|
getReference<MethodReference>()?.name == "getApplicationContext"
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplicationContextIndex + 2 // Below the move-result-object instruction.
|
getApplicationContextIndex + 2 // Below the move-result-object instruction.
|
||||||
},
|
},
|
||||||
contextRegisterResolver = { method ->
|
getContextRegister = { method ->
|
||||||
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1)
|
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1)
|
||||||
as OneRegisterInstruction
|
as OneRegisterInstruction
|
||||||
"v${moveResultInstruction.registerA}"
|
"v${moveResultInstruction.registerA}"
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
private var getApplicationContextIndex = -1
|
private var getApplicationContextIndex = -1
|
||||||
|
|
||||||
internal val homeActivityInitHook = extensionHook(
|
internal val homeActivityInitHook = extensionHook(
|
||||||
insertIndexResolver = { method ->
|
getInsertIndex = { method ->
|
||||||
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow {
|
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow {
|
||||||
getReference<MethodReference>()?.name == "getApplicationContext"
|
getReference<MethodReference>()?.name == "getApplicationContext"
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplicationContextIndex + 2 // Below the move-result-object instruction.
|
getApplicationContextIndex + 2 // Below the move-result-object instruction.
|
||||||
},
|
},
|
||||||
contextRegisterResolver = { method ->
|
getContextRegister = { method ->
|
||||||
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1)
|
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1)
|
||||||
as OneRegisterInstruction
|
as OneRegisterInstruction
|
||||||
"v${moveResultInstruction.registerA}"
|
"v${moveResultInstruction.registerA}"
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
package app.revanced.patches.shared.misc.extension
|
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
|
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)
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||||
returns("Ljava/lang/String;")
|
returnType("Ljava/lang/String;")
|
||||||
parameters()
|
parameterTypes()
|
||||||
custom { method, _ ->
|
|
||||||
method.name == "getPatchesReleaseVersion" && method.definingClass == EXTENSION_CLASS_DESCRIPTOR
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
package app.revanced.patches.shared.misc.extension
|
package app.revanced.patches.shared.misc.extension
|
||||||
|
|
||||||
|
import app.revanced.patcher.*
|
||||||
import app.revanced.patcher.BytecodePatchContextClassDefMatching.firstMutableClassDef
|
import app.revanced.patcher.BytecodePatchContextClassDefMatching.firstMutableClassDef
|
||||||
import app.revanced.patcher.Fingerprint
|
import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMutableMethodDeclaratively
|
||||||
import app.revanced.patcher.FingerprintBuilder
|
|
||||||
import app.revanced.patcher.extensions.addInstruction
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
import app.revanced.patcher.fingerprint
|
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.util.returnEarly
|
import app.revanced.util.returnEarly
|
||||||
|
|
@ -49,52 +48,52 @@ fun sharedExtensionPatch(
|
||||||
hooks.forEach { hook -> hook()(EXTENSION_CLASS_DESCRIPTOR) }
|
hooks.forEach { hook -> hook()(EXTENSION_CLASS_DESCRIPTOR) }
|
||||||
|
|
||||||
// Modify Utils method to include the patches release version.
|
// Modify Utils method to include the patches release version.
|
||||||
revancedUtilsPatchesVersionFingerprint.method.apply {
|
/**
|
||||||
/**
|
* @return The file path for the jar this classfile is contained inside.
|
||||||
* @return The file path for the jar this classfile is contained inside.
|
*/
|
||||||
*/
|
fun getCurrentJarFilePath(): String {
|
||||||
fun getCurrentJarFilePath(): String {
|
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
|
||||||
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
|
val classUrl = object {}::class.java.classLoader?.getResource(className)
|
||||||
val classUrl = object {}::class.java.classLoader?.getResource(className)
|
if (classUrl != null) {
|
||||||
if (classUrl != null) {
|
val urlString = classUrl.toString()
|
||||||
val urlString = classUrl.toString()
|
|
||||||
|
|
||||||
if (urlString.startsWith("jar:file:")) {
|
if (urlString.startsWith("jar:file:")) {
|
||||||
val end = urlString.lastIndexOf('!')
|
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.")
|
|
||||||
}
|
}
|
||||||
|
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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(
|
class ExtensionHook internal constructor(
|
||||||
internal val fingerprint: Fingerprint,
|
private val getInsertIndex: Method.() -> Int,
|
||||||
private val insertIndexResolver: context(BytecodePatchContext) (Method) -> Int,
|
private val getContextRegister: Method.() -> String,
|
||||||
private val contextRegisterResolver: context(BytecodePatchContext) (Method) -> String,
|
private val predicate: DeclarativePredicate<Method>,
|
||||||
) {
|
) {
|
||||||
context(_: BytecodePatchContext)
|
context(context: BytecodePatchContext)
|
||||||
operator fun invoke(extensionClassDescriptor: String) {
|
operator fun invoke(extensionClassDescriptor: String) {
|
||||||
val insertIndex = insertIndexResolver(fingerprint.method)
|
val method = context.firstMutableMethodDeclaratively(predicate = predicate)
|
||||||
val contextRegister = contextRegisterResolver(fingerprint.method)
|
val insertIndex = method.getInsertIndex()
|
||||||
|
val contextRegister = method.getContextRegister()
|
||||||
|
|
||||||
fingerprint.method.addInstruction(
|
method.addInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"invoke-static/range { $contextRegister .. $contextRegister }, " +
|
"invoke-static/range { $contextRegister .. $contextRegister }, " +
|
||||||
"$extensionClassDescriptor->setContext(Landroid/content/Context;)V",
|
"$extensionClassDescriptor->setContext(Landroid/content/Context;)V",
|
||||||
|
|
@ -103,19 +102,10 @@ class ExtensionHook internal constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun extensionHook(
|
fun extensionHook(
|
||||||
insertIndexResolver: context(BytecodePatchContext) (Method) -> Int = { 0 },
|
getInsertIndex: Method.() -> Int = { 0 },
|
||||||
contextRegisterResolver: context(BytecodePatchContext) (Method) -> String = { "p0" },
|
getContextRegister: Method.() -> String = { "p0" },
|
||||||
fingerprint: Fingerprint,
|
predicate: DeclarativePredicate<Method>,
|
||||||
) = ExtensionHook(fingerprint, insertIndexResolver, contextRegisterResolver)
|
) = ExtensionHook(getInsertIndex, getContextRegister, predicate)
|
||||||
|
|
||||||
fun extensionHook(
|
|
||||||
insertIndexResolver: context(BytecodePatchContext) (Method) -> Int = { 0 },
|
|
||||||
contextRegisterResolver: context(BytecodePatchContext) (Method) -> String = { "p0" },
|
|
||||||
fingerprintBuilderBlock: FingerprintBuilder.() -> Unit,
|
|
||||||
) = {
|
|
||||||
->
|
|
||||||
ExtensionHook(fingerprint(block = fingerprintBuilderBlock), insertIndexResolver, contextRegisterResolver)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an extension hook from a non-obfuscated activity, which typically is the main activity
|
* 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;`
|
* @param activityClassType Either the full activity class type such as `Lcom/company/MainActivity;`
|
||||||
* or the 'ends with' string for the activity such as `/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(';')) {
|
if (!activityClassType.endsWith(';')) {
|
||||||
throw IllegalArgumentException("Activity class type does not end with semicolon: $activityClassType")
|
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')
|
val fullClassType = activityClassType.startsWith('L')
|
||||||
|
|
||||||
return extensionHook {
|
return extensionHook {
|
||||||
returns("V")
|
name("onCreate")
|
||||||
parameters("Landroid/os/Bundle;")
|
|
||||||
custom { method, classDef ->
|
if (fullClassType) definingClass(activityClassType)
|
||||||
method.name == "onCreate" &&
|
else definingClass { endsWith(activityClassType) }
|
||||||
if (fullClassType) classDef.type == activityClassType
|
|
||||||
else classDef.type.endsWith(activityClassType)
|
returnType("V")
|
||||||
}
|
parameterTypes("Landroid/os/Bundle;")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ internal val mainActivityOnCreateHook = extensionHook { mainActivityOnCreateFing
|
||||||
internal val loadOrbitLibraryHook = extensionHook {
|
internal val loadOrbitLibraryHook = extensionHook {
|
||||||
// FIXME: Creating this is a mess and needs refactoring.
|
// FIXME: Creating this is a mess and needs refactoring.
|
||||||
extensionHook(
|
extensionHook(
|
||||||
insertIndexResolver = {
|
getInsertIndex = {
|
||||||
loadOrbitLibraryFingerprint.stringMatches.last().index
|
loadOrbitLibraryFingerprint.stringMatches.last().index
|
||||||
},
|
},
|
||||||
contextRegisterResolver = { method ->
|
getContextRegister = { method ->
|
||||||
val contextReferenceIndex = method.indexOfFirstInstruction {
|
val contextReferenceIndex = method.indexOfFirstInstruction {
|
||||||
getReference<FieldReference>()?.type == "Landroid/content/Context;"
|
getReference<FieldReference>()?.type == "Landroid/content/Context;"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ internal val initHook = activityOnCreateExtensionHook(
|
||||||
* This class is called from startup code titled "BPEA RunnableGuardLancet".
|
* This class is called from startup code titled "BPEA RunnableGuardLancet".
|
||||||
*/
|
*/
|
||||||
internal val jatoInitHook = extensionHook(
|
internal val jatoInitHook = extensionHook(
|
||||||
contextRegisterResolver = { "p1" }
|
getContextRegister = { "p1" }
|
||||||
) {
|
) {
|
||||||
parameters("Landroid/content/Context;")
|
parameters("Landroid/content/Context;")
|
||||||
custom { method, classDef ->
|
custom { method, classDef ->
|
||||||
|
|
@ -24,7 +24,7 @@ internal val jatoInitHook = extensionHook(
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val storeRegionInitHook = extensionHook(
|
internal val storeRegionInitHook = extensionHook(
|
||||||
contextRegisterResolver = { "p1" }
|
getContextRegister = { "p1" }
|
||||||
) {
|
) {
|
||||||
parameters("Landroid/content/Context;")
|
parameters("Landroid/content/Context;")
|
||||||
custom { method, classDef ->
|
custom { method, classDef ->
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue