diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 2d6d258..0000000 --- a/.editorconfig +++ /dev/null @@ -1,3 +0,0 @@ -[*.{kt,kts}] -ktlint_code_style = intellij_idea -ktlint_standard_no-wildcard-imports = disabled \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9dbd27a..adfa9bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,124 +1,19 @@ -### Java template -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* - -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Generated files -.idea/**/contentModel.xml - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -.idea/artifacts -.idea/compiler.xml -.idea/jarRepositories.xml -.idea/modules.xml -.idea/*.iml -.idea/modules *.iml -*.ipr - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ -.idea/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser - -### Gradle template +.kotlin .gradle **/build/ +xcuserdata !src/**/build/ - -# Ignore Gradle GUI config -gradle-app.setting - -# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) -!gradle-wrapper.jar - -# Cache of project -.gradletasknamecache - -# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 -# gradle/wrapper/gradle-wrapper.properties - -# Avoid ignoring test resources -!src/test/resources/* - -# Dependency directories +local.properties +.idea +.DS_Store +captures +.externalNativeBuild +.cxx +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcodeproj/project.xcworkspace/ +!*.xcworkspace/contents.xcworkspacedata +**/xcshareddata/WorkspaceSettings.xcsettings node_modules/ - -# Gradle props, to avoid sharing the gpr key -gradle.properties diff --git a/build.gradle.kts b/build.gradle.kts index b6fc031..7728dea 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,119 +1,5 @@ -import org.jetbrains.kotlin.gradle.dsl.JvmTarget - plugins { - alias(libs.plugins.kotlin) - alias(libs.plugins.binary.compatibility.validator) - `maven-publish` - signing -} - -group = "app.revanced" - -tasks { - processResources { - expand("projectVersion" to project.version) - } - - test { - useJUnitPlatform() - testLogging { - events("PASSED", "SKIPPED", "FAILED") - } - } -} - -repositories { - mavenCentral() - google() - maven { - // A repository must be specified for some reason. "registry" is a dummy. - url = uri("https://maven.pkg.github.com/revanced/registry") - credentials { - username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR") - password = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN") - } - } -} - -dependencies { - // TODO: Convert project to KMP. - compileOnly(libs.android) { - // Exclude, otherwise the org.w3c.dom API breaks. - exclude(group = "xerces", module = "xmlParserAPIs") - } - - implementation(libs.apktool.lib) - implementation(libs.kotlin.reflect) - implementation(libs.kotlinx.coroutines.core) - implementation(libs.multidexlib2) - implementation(libs.smali) - implementation(libs.xpp3) - - testImplementation(libs.mockk) - testImplementation(libs.kotlin.test) -} - -kotlin { - compilerOptions { - jvmTarget.set(JvmTarget.JVM_11) - - freeCompilerArgs = listOf("-Xcontext-parameters") - } -} - -java { - targetCompatibility = JavaVersion.VERSION_11 - - withSourcesJar() -} - -publishing { - repositories { - maven { - name = "GitHubPackages" - url = uri("https://maven.pkg.github.com/revanced/revanced-patcher") - credentials { - username = System.getenv("GITHUB_ACTOR") - password = System.getenv("GITHUB_TOKEN") - } - } - } - - publications { - create("revanced-patcher-publication") { - from(components["java"]) - - version = project.version.toString() - - pom { - name = "ReVanced Patcher" - description = "Patcher used by ReVanced." - url = "https://revanced.app" - - licenses { - license { - name = "GNU General Public License v3.0" - url = "https://www.gnu.org/licenses/gpl-3.0.en.html" - } - } - developers { - developer { - id = "ReVanced" - name = "ReVanced" - email = "contact@revanced.app" - } - } - scm { - connection = "scm:git:git://github.com/revanced/revanced-patcher.git" - developerConnection = "scm:git:git@github.com:revanced/revanced-patcher.git" - url = "https://github.com/revanced/revanced-patcher" - } - } - } - } -} - -signing { - useGpgCmd() - sign(publishing.publications["revanced-patcher-publication"]) -} + alias(libs.plugins.android.kotlin.multiplatform.library) apply false + alias(libs.plugins.kotlinMultiplatform) apply false + alias(libs.plugins.vanniktech.mavenPublish) apply false +} \ No newline at end of file diff --git a/api/revanced-patcher.api b/core/api/android/core.api similarity index 56% rename from api/revanced-patcher.api rename to core/api/android/core.api index 689e331..059d0c4 100644 --- a/api/revanced-patcher.api +++ b/core/api/android/core.api @@ -1,29 +1,27 @@ -public final class app/revanced/patcher/AnyInstruction : app/revanced/patcher/InstructionFilter { - public fun getLocation ()Lapp/revanced/patcher/InstructionLocation; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z +public final class app/revanced/patcher/CachedReadOnlyProperty : kotlin/properties/ReadOnlyProperty { + public fun getValue (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; } -public final class app/revanced/patcher/CheckCastFilter : app/revanced/patcher/OpcodeFilter { - public final fun getComparison ()Lapp/revanced/patcher/StringComparisonType; - public final fun getType ()Lkotlin/jvm/functions/Function0; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z +public final class app/revanced/patcher/Composition { + public final fun getIndices ()Ljava/util/List; + public final fun getMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getStrings ()Ljava/util/List; } -public final class app/revanced/patcher/FieldAccessFilter : app/revanced/patcher/OpcodesFilter { - public final fun getDefiningClass ()Ljava/lang/String; - public final fun getName ()Ljava/lang/String; - public final fun getType ()Ljava/lang/String; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z +public final class app/revanced/patcher/DeclarativePredicateBuilder { + public final fun all (Ljava/lang/Object;)Z + public final fun any (Ljava/lang/Object;)Z + public final fun anyOf (Lkotlin/jvm/functions/Function1;)V + public final fun predicate (Lkotlin/jvm/functions/Function1;)V } public final class app/revanced/patcher/Fingerprint { - public final fun clearMatch ()V - public final fun getClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; - public final fun getClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; - public final fun getInstructionMatches (Lapp/revanced/patcher/patch/BytecodePatchContext;)Ljava/util/List; - public final fun getInstructionMatchesOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Ljava/util/List; - public final fun getMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/dex/mutable/MutableMethod; - public final fun getMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/dex/mutable/MutableMethod; + public final fun getClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public final fun getClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public final fun getMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public final fun getOriginalClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; public final fun getOriginalClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; public final fun getOriginalMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/Method; @@ -32,24 +30,19 @@ public final class app/revanced/patcher/Fingerprint { public final fun getPatternMatchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/Match$PatternMatch; public final fun getStringMatches (Lapp/revanced/patcher/patch/BytecodePatchContext;)Ljava/util/List; public final fun getStringMatchesOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Ljava/util/List; - public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/Match; public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/Match; public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; - public final fun matchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/Match; public final fun matchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; - public final fun matchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/Match; public final fun matchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/Match; - public final fun patchException ()Lapp/revanced/patcher/patch/PatchException; + public final fun matchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; } public final class app/revanced/patcher/FingerprintBuilder { public fun ()V public final fun accessFlags (I)V public final fun accessFlags ([Lcom/android/tools/smali/dexlib2/AccessFlags;)V - public final fun build ()Lapp/revanced/patcher/Fingerprint; public final fun custom (Lkotlin/jvm/functions/Function2;)V - public final fun instructions ([Lapp/revanced/patcher/InstructionFilter;)V public final fun opcodes (Ljava/lang/String;)V public final fun opcodes ([Lcom/android/tools/smali/dexlib2/Opcode;)V public final fun parameters ([Ljava/lang/String;)V @@ -58,159 +51,39 @@ public final class app/revanced/patcher/FingerprintBuilder { } public final class app/revanced/patcher/FingerprintKt { - public static final fun fingerprint (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/Fingerprint; + public static final fun fingerprint (ILkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/Fingerprint; + public static synthetic fun fingerprint$default (ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/Fingerprint; } public final class app/revanced/patcher/IndexedMatcher : app/revanced/patcher/Matcher { public fun ()V - public final fun after (IILkotlin/jvm/functions/Function1;)Z - public static synthetic fun after$default (Lapp/revanced/patcher/IndexedMatcher;IILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Z public final fun contains (Ljava/lang/Object;)Z - public fun contains (Lkotlin/jvm/functions/Function1;)Z - public final fun first (Lkotlin/jvm/functions/Function1;)Z + public fun contains (Lkotlin/jvm/functions/Function3;)Z public final fun getIndices ()Ljava/util/List; + public final fun getNextIndex ()Ljava/lang/Integer; public final fun indexOf (Ljava/lang/Object;)I - public fun indexOf (Lkotlin/jvm/functions/Function1;)I + public fun indexOf (Lkotlin/jvm/functions/Function3;)I public fun invoke (Ljava/lang/Iterable;)Z public final fun lastIndexOf (Ljava/lang/Object;)I - public fun lastIndexOf (Lkotlin/jvm/functions/Function1;)I - public final fun remove (I)Lkotlin/jvm/functions/Function1; + public fun lastIndexOf (Lkotlin/jvm/functions/Function3;)I + public final fun remove (I)Lkotlin/jvm/functions/Function3; public final fun remove (Ljava/lang/Object;)Z - public fun remove (Lkotlin/jvm/functions/Function1;)Z - public fun removeAt (I)Lkotlin/jvm/functions/Function1; -} - -public abstract interface class app/revanced/patcher/InstructionFilter { - public fun getLocation ()Lapp/revanced/patcher/InstructionLocation; - public abstract fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z -} - -public final class app/revanced/patcher/InstructionFilter$DefaultImpls { - public static fun getLocation (Lapp/revanced/patcher/InstructionFilter;)Lapp/revanced/patcher/InstructionLocation; -} - -public final class app/revanced/patcher/InstructionFilterKt { - public static final fun anyInstruction ([Lapp/revanced/patcher/InstructionFilter;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/AnyInstruction; - public static synthetic fun anyInstruction$default ([Lapp/revanced/patcher/InstructionFilter;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/AnyInstruction; - public static final fun checkCast (Ljava/lang/String;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/CheckCastFilter; - public static final fun checkCast (Ljava/lang/String;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/CheckCastFilter; - public static final fun checkCast (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/CheckCastFilter; - public static final fun checkCast (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/CheckCastFilter; - public static synthetic fun checkCast$default (Ljava/lang/String;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/CheckCastFilter; - public static synthetic fun checkCast$default (Ljava/lang/String;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/CheckCastFilter; - public static synthetic fun checkCast$default (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/CheckCastFilter; - public static synthetic fun checkCast$default (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/CheckCastFilter; - public static final fun fieldAccess (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/FieldAccessFilter; - public static final fun fieldAccess (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/FieldAccessFilter; - public static final fun fieldAccess (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/FieldAccessFilter; - public static final fun fieldAccess (Ljava/lang/String;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/FieldAccessFilter; - public static synthetic fun fieldAccess$default (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/FieldAccessFilter; - public static synthetic fun fieldAccess$default (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/FieldAccessFilter; - public static synthetic fun fieldAccess$default (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/FieldAccessFilter; - public static synthetic fun fieldAccess$default (Ljava/lang/String;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/FieldAccessFilter; - public static final fun literal (DLjava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/LiteralFilter; - public static final fun literal (FLjava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/LiteralFilter; - public static final fun literal (ILjava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/LiteralFilter; - public static final fun literal (JLjava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/LiteralFilter; - public static final fun literal (Lkotlin/jvm/functions/Function0;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/LiteralFilter; - public static synthetic fun literal$default (DLjava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/LiteralFilter; - public static synthetic fun literal$default (FLjava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/LiteralFilter; - public static synthetic fun literal$default (ILjava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/LiteralFilter; - public static synthetic fun literal$default (JLjava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/LiteralFilter; - public static synthetic fun literal$default (Lkotlin/jvm/functions/Function0;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/LiteralFilter; - public static final fun methodCall (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/MethodCallFilter; - public static final fun methodCall (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/MethodCallFilter; - public static final fun methodCall (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/MethodCallFilter; - public static final fun methodCall (Ljava/lang/String;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/MethodCallFilter; - public static synthetic fun methodCall$default (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/MethodCallFilter; - public static synthetic fun methodCall$default (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/MethodCallFilter; - public static synthetic fun methodCall$default (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/MethodCallFilter; - public static synthetic fun methodCall$default (Ljava/lang/String;Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/MethodCallFilter; - public static final fun newInstance (Ljava/lang/String;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/NewInstanceFilter; - public static final fun newInstance (Ljava/lang/String;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/NewInstanceFilter; - public static final fun newInstance (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/NewInstanceFilter; - public static final fun newInstance (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/NewInstanceFilter; - public static synthetic fun newInstance$default (Ljava/lang/String;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/NewInstanceFilter; - public static synthetic fun newInstance$default (Ljava/lang/String;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/NewInstanceFilter; - public static synthetic fun newInstance$default (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/NewInstanceFilter; - public static synthetic fun newInstance$default (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/NewInstanceFilter; - public static final fun opcode (Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/OpcodeFilter; - public static synthetic fun opcode$default (Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/OpcodeFilter; - public static final fun string (Ljava/lang/String;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/StringFilter; - public static final fun string (Ljava/lang/String;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/StringFilter; - public static final fun string (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/StringFilter; - public static final fun string (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;)Lapp/revanced/patcher/StringFilter; - public static synthetic fun string$default (Ljava/lang/String;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/StringFilter; - public static synthetic fun string$default (Ljava/lang/String;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/StringFilter; - public static synthetic fun string$default (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/StringFilter; - public static synthetic fun string$default (Lkotlin/jvm/functions/Function0;Lapp/revanced/patcher/StringComparisonType;Lapp/revanced/patcher/InstructionLocation;ILjava/lang/Object;)Lapp/revanced/patcher/StringFilter; -} - -public abstract interface class app/revanced/patcher/InstructionLocation { - public abstract fun indexIsValidForMatching (II)Z -} - -public final class app/revanced/patcher/InstructionLocation$MatchAfterAnywhere : app/revanced/patcher/InstructionLocation { - public fun ()V - public fun indexIsValidForMatching (II)Z -} - -public final class app/revanced/patcher/InstructionLocation$MatchAfterAtLeast : app/revanced/patcher/InstructionLocation { - public fun (I)V - public final fun getMinimumDistanceFromLastInstruction ()I - public fun indexIsValidForMatching (II)Z - public final fun setMinimumDistanceFromLastInstruction (I)V -} - -public final class app/revanced/patcher/InstructionLocation$MatchAfterImmediately : app/revanced/patcher/InstructionLocation { - public fun ()V - public fun indexIsValidForMatching (II)Z -} - -public final class app/revanced/patcher/InstructionLocation$MatchAfterRange : app/revanced/patcher/InstructionLocation { - public fun (II)V - public final fun getMaximumDistanceFromLastInstruction ()I - public final fun getMinimumDistanceFromLastInstruction ()I - public fun indexIsValidForMatching (II)Z -} - -public final class app/revanced/patcher/InstructionLocation$MatchAfterWithin : app/revanced/patcher/InstructionLocation { - public fun (I)V - public final fun getMatchDistance ()I - public fun indexIsValidForMatching (II)Z -} - -public final class app/revanced/patcher/InstructionLocation$MatchFirst : app/revanced/patcher/InstructionLocation { - public fun ()V - public fun indexIsValidForMatching (II)Z + public fun remove (Lkotlin/jvm/functions/Function3;)Z + public fun removeAt (I)Lkotlin/jvm/functions/Function3; + public final fun setNextIndex (Ljava/lang/Integer;)V } public abstract interface annotation class app/revanced/patcher/InternalApi : java/lang/annotation/Annotation { } -public final class app/revanced/patcher/LiteralFilter : app/revanced/patcher/OpcodesFilter { - public final fun getLiteral ()Lkotlin/jvm/functions/Function0; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z -} - public final class app/revanced/patcher/Match { - public final fun getClassDef ()Lapp/revanced/patcher/dex/mutable/MutableClassDef; + public final fun getClassDef ()Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public final fun getContext ()Lapp/revanced/patcher/patch/BytecodePatchContext; - public final fun getInstructionMatches ()Ljava/util/List; - public final fun getInstructionMatchesOrNull ()Ljava/util/List; - public final fun getMethod ()Lapp/revanced/patcher/dex/mutable/MutableMethod; + public final fun getMethod ()Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public final fun getOriginalClassDef ()Lcom/android/tools/smali/dexlib2/iface/ClassDef; public final fun getOriginalMethod ()Lcom/android/tools/smali/dexlib2/iface/Method; public final fun getPatternMatch ()Lapp/revanced/patcher/Match$PatternMatch; public final fun getStringMatches ()Ljava/util/List; - public final fun getStringMatchesOrNull ()Ljava/util/List; -} - -public final class app/revanced/patcher/Match$InstructionMatch { - public final fun getFilter ()Lapp/revanced/patcher/InstructionFilter; - public final fun getIndex ()I - public final fun getInstruction ()Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction; - public final fun getInstruction ()Ljava/lang/Object; } public final class app/revanced/patcher/Match$PatternMatch { @@ -255,31 +128,13 @@ public abstract class app/revanced/patcher/Matcher : java/util/List, kotlin/jvm/ public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; } -public final class app/revanced/patcher/Matcher$MatchContext : java/util/Map, kotlin/jvm/internal/markers/KMutableMap { - public fun clear ()V - public final fun containsKey (Ljava/lang/Object;)Z - public fun containsKey (Ljava/lang/String;)Z - public fun containsValue (Ljava/lang/Object;)Z - public final fun entrySet ()Ljava/util/Set; - public final fun get (Ljava/lang/Object;)Ljava/lang/Object; - public fun get (Ljava/lang/String;)Ljava/lang/Object; - public fun getEntries ()Ljava/util/Set; - public fun getKeys ()Ljava/util/Set; - public fun getSize ()I - public fun getValues ()Ljava/util/Collection; - public fun isEmpty ()Z - public final fun keySet ()Ljava/util/Set; - public synthetic fun put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun put (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; - public fun putAll (Ljava/util/Map;)V - public final fun remove (Ljava/lang/Object;)Ljava/lang/Object; - public fun remove (Ljava/lang/String;)Ljava/lang/Object; - public final fun size ()I - public final fun values ()Ljava/util/Collection; -} - public final class app/revanced/patcher/MatchingKt { - public static final fun a (Lapp/revanced/patcher/patch/BytecodePatchContext;)V + public static final fun accessFlags (Lapp/revanced/patcher/DeclarativePredicateBuilder;[Lcom/android/tools/smali/dexlib2/AccessFlags;)V + public static final fun after (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static final fun after (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; + public static synthetic fun after$default (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun after$default (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun allOf ([Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; public static final fun anyAnnotation (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z public static final fun anyAnnotation (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z public static final fun anyClassDef (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z @@ -292,101 +147,142 @@ public final class app/revanced/patcher/MatchingKt { public static final fun anyInstruction (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z public static final fun anyInterface (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z public static final fun anyMethod (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyOf ([Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; public static final fun anyParameter (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z public static final fun anyParameterType (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z public static final fun anyStaticField (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z public static final fun anyTryBlock (Lcom/android/tools/smali/dexlib2/iface/MethodImplementation;Lkotlin/jvm/functions/Function1;)Z public static final fun anyVirtualMethod (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun custom (Lapp/revanced/patcher/DeclarativePredicateBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun declarativePredicate (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z + public static final fun field (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun field (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun field$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun field$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; public static final fun firstClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; public static final fun firstClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; public static synthetic fun firstClassDef$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; - public static final fun firstClassDefMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; - public static final fun firstClassDefMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; - public static synthetic fun firstClassDefMutable$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; - public static final fun firstClassDefMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; - public static final fun firstClassDefMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; - public static synthetic fun firstClassDefMutableOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; + public static final fun firstClassDefByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static synthetic fun firstClassDefMutable$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static synthetic fun firstClassDefMutableOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public static final fun firstClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; public static final fun firstClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; public static synthetic fun firstClassDefOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; public static final fun firstMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; public static final fun firstMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; - public static final fun firstMethod (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; public static synthetic fun firstMethod$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/iface/Method; - public static final fun firstMethodMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableMethod; - public static final fun firstMethodMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableMethod; - public static final fun firstMethodMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableMethod; - public static synthetic fun firstMethodMutable$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/dex/mutable/MutableMethod; - public static final fun firstMethodMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableMethod; - public static final fun firstMethodMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableMethod; - public static final fun firstMethodMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/dex/mutable/MutableMethod; - public static synthetic fun firstMethodMutableOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/dex/mutable/MutableMethod; + public static final fun firstMethodByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodComposite ([Ljava/lang/String;Lkotlin/jvm/functions/Function5;)Lapp/revanced/patcher/Composition; + public static final fun firstMethodMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static synthetic fun firstMethodMutable$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static synthetic fun firstMethodMutableOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public static final fun firstMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; public static final fun firstMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; - public static final fun firstMethodOrNull (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; public static synthetic fun firstMethodOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/iface/Method; - public static final fun gettingFirstClassDef (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstClassDef (Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun gettingFirstClassDef$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstClassDefMutable (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstClassDefMutable (Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun gettingFirstClassDefMutable$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstClassDefMutableOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstClassDefMutableOrNull (Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun gettingFirstClassDefMutableOrNull$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstClassDefOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstClassDefOrNull (Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun gettingFirstClassDefOrNull$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstMethod (Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstMethod ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun gettingFirstMethod$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstMethodMutable (Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstMethodMutable ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun gettingFirstMethodMutable$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstMethodMutableOrNull (Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstMethodMutableOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun gettingFirstMethodMutableOrNull$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstMethodOrNull (Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static final fun gettingFirstMethodOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/properties/ReadOnlyProperty; - public static synthetic fun gettingFirstMethodOrNull$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun getM ()Lapp/revanced/patcher/Composition; + public static final fun gettingFirstClassDef (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDef (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstClassDef$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefByDeclarativePredicate (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefByDeclarativePredicate (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefByDeclarativePredicateOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefByDeclarativePredicateOrNull (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutable (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutable (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstClassDefMutable$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableByDeclarativePredicate (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableByDeclarativePredicate (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableByDeclarativePredicateOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableByDeclarativePredicateOrNull (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableOrNull (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstClassDefMutableOrNull$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefOrNull (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstClassDefOrNull$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethod (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethod ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstMethod$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodByDeclarativePredicate (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodByDeclarativePredicate ([Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodByDeclarativePredicateOrNull (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodByDeclarativePredicateOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutable (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutable ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstMethodMutable$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableByDeclarativePredicate (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableByDeclarativePredicate ([Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableByDeclarativePredicateOrNull (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableByDeclarativePredicateOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableOrNull (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstMethodMutableOrNull$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodOrNull (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstMethodOrNull$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun head (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static final fun head (Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; public static final fun implementation (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z public static final fun indexedMatcher ()Lapp/revanced/patcher/IndexedMatcher; public static final fun indexedMatcher (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/IndexedMatcher; - public static final fun invoke (Lapp/revanced/patcher/Matcher$MatchContext;Lapp/revanced/patcher/IndexedMatcher;Ljava/lang/Iterable;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Z - public static final fun matchIndexed (Lapp/revanced/patcher/Matcher$MatchContext;Ljava/lang/Iterable;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Z + public static final fun instruction (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static final fun instructions (Lapp/revanced/patcher/IndexedMatcher;Lapp/revanced/patcher/DeclarativePredicateBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun instructions (Lapp/revanced/patcher/IndexedMatcher;Lapp/revanced/patcher/DeclarativePredicateBuilder;[Lkotlin/jvm/functions/Function3;)V + public static final fun invoke (Lcom/android/tools/smali/dexlib2/Opcode;)Lkotlin/jvm/functions/Function3; + public static final fun invoke (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static synthetic fun invoke$default (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun literal (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun literal (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun literal$default (JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun literal$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; public static final fun matchIndexed (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z - public static final fun matchers (Lapp/revanced/patcher/patch/BytecodePatchContext;)V -} - -public final class app/revanced/patcher/MethodCallFilter : app/revanced/patcher/OpcodesFilter { - public final fun getDefiningClass ()Ljava/lang/String; - public final fun getName ()Ljava/lang/String; - public final fun getParameters ()Ljava/util/List; - public final fun getReturnType ()Ljava/lang/String; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z -} - -public final class app/revanced/patcher/NewInstanceFilter : app/revanced/patcher/OpcodesFilter { - public final fun getComparison ()Lapp/revanced/patcher/StringComparisonType; - public final fun getType ()Lkotlin/jvm/functions/Function0; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z -} - -public class app/revanced/patcher/OpcodeFilter : app/revanced/patcher/InstructionFilter { - public fun (Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;)V - public synthetic fun (Lcom/android/tools/smali/dexlib2/Opcode;Lapp/revanced/patcher/InstructionLocation;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun getLocation ()Lapp/revanced/patcher/InstructionLocation; - public final fun getOpcode ()Lcom/android/tools/smali/dexlib2/Opcode; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z -} - -public class app/revanced/patcher/OpcodesFilter : app/revanced/patcher/InstructionFilter { - protected fun (Ljava/util/EnumSet;Lapp/revanced/patcher/InstructionLocation;)V - public synthetic fun (Ljava/util/EnumSet;Lapp/revanced/patcher/InstructionLocation;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - protected fun (Ljava/util/List;Lapp/revanced/patcher/InstructionLocation;)V - public fun getLocation ()Lapp/revanced/patcher/InstructionLocation; - public final fun getOpcodes ()Ljava/util/EnumSet; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z + public static final fun method (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun method (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun method$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun method$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun noneOf ([Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; + public static final fun parameterTypes (Lapp/revanced/patcher/DeclarativePredicateBuilder;[Ljava/lang/String;)V + public static final fun reference (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun reference (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun reference$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun reference$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun registers (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static final fun registers ([ILkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static synthetic fun registers$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun registers$default ([ILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun rememberedDeclarativePredicate (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z + public static final fun rememberedMatchIndexed (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z + public static final fun returns (Lapp/revanced/patcher/DeclarativePredicateBuilder;Ljava/lang/String;)V + public static final fun string (Ljava/util/List;Lapp/revanced/patcher/DeclarativePredicateBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun string (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun string$default (Ljava/util/List;Lapp/revanced/patcher/DeclarativePredicateBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun string$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun type (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun type (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun type$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun type$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun unaryPlus (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/jvm/functions/Function3;)Z } public final class app/revanced/patcher/PackageMetadata { @@ -432,348 +328,23 @@ public final class app/revanced/patcher/PatcherResult$PatchedResources { public final fun getResourcesApk ()Ljava/io/File; } -public final class app/revanced/patcher/StringComparisonType : java/lang/Enum { - public static final field CONTAINS Lapp/revanced/patcher/StringComparisonType; - public static final field ENDS_WITH Lapp/revanced/patcher/StringComparisonType; - public static final field EQUALS Lapp/revanced/patcher/StringComparisonType; - public static final field STARTS_WITH Lapp/revanced/patcher/StringComparisonType; - public final fun compare (Ljava/lang/String;Ljava/lang/String;)Z - public static fun getEntries ()Lkotlin/enums/EnumEntries; - public static fun valueOf (Ljava/lang/String;)Lapp/revanced/patcher/StringComparisonType; - public static fun values ()[Lapp/revanced/patcher/StringComparisonType; -} - -public final class app/revanced/patcher/StringFilter : app/revanced/patcher/OpcodesFilter { - public final fun getComparison ()Lapp/revanced/patcher/StringComparisonType; - public final fun getString ()Lkotlin/jvm/functions/Function0; - public fun matches (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Z -} - -public final class app/revanced/patcher/dex/mutable/MutableAnnotation : com/android/tools/smali/dexlib2/base/BaseAnnotation { - public static final field Companion Lapp/revanced/patcher/dex/mutable/MutableAnnotation$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/Annotation;)V - public fun getElements ()Ljava/util/Set; - public fun getType ()Ljava/lang/String; - public fun getVisibility ()I -} - -public final class app/revanced/patcher/dex/mutable/MutableAnnotation$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Annotation;)Lapp/revanced/patcher/dex/mutable/MutableAnnotation; -} - -public final class app/revanced/patcher/dex/mutable/MutableAnnotationElement : com/android/tools/smali/dexlib2/base/BaseAnnotationElement { - public static final field Companion Lapp/revanced/patcher/dex/mutable/MutableAnnotationElement$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/AnnotationElement;)V - public fun getName ()Ljava/lang/String; - public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue; - public final fun setName (Ljava/lang/String;)V - public final fun setValue (Lapp/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue;)V -} - -public final class app/revanced/patcher/dex/mutable/MutableAnnotationElement$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/AnnotationElement;)Lapp/revanced/patcher/dex/mutable/MutableAnnotationElement; -} - -public final class app/revanced/patcher/dex/mutable/MutableClassDef : com/android/tools/smali/dexlib2/base/reference/BaseTypeReference, com/android/tools/smali/dexlib2/iface/ClassDef { - public static final field Companion Lapp/revanced/patcher/dex/mutable/MutableClassDef$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)V - public final fun charAt (I)C - public fun get (I)C - public fun getAccessFlags ()I - public fun getAnnotations ()Ljava/util/Set; - public synthetic fun getDirectMethods ()Ljava/lang/Iterable; - public fun getDirectMethods ()Ljava/util/Set; - public synthetic fun getFields ()Ljava/lang/Iterable; - public fun getFields ()Ljava/util/Set; - public synthetic fun getInstanceFields ()Ljava/lang/Iterable; - public fun getInstanceFields ()Ljava/util/Set; - public fun getInterfaces ()Ljava/util/List; - public fun getLength ()I - public synthetic fun getMethods ()Ljava/lang/Iterable; - public fun getMethods ()Ljava/util/Set; - public fun getSourceFile ()Ljava/lang/String; - public synthetic fun getStaticFields ()Ljava/lang/Iterable; - public fun getStaticFields ()Ljava/util/Set; - public fun getSuperclass ()Ljava/lang/String; - public fun getType ()Ljava/lang/String; - public synthetic fun getVirtualMethods ()Ljava/lang/Iterable; - public fun getVirtualMethods ()Ljava/util/Set; - public final fun length ()I - public final fun setAccessFlags (I)V - public final fun setSourceFile (Ljava/lang/String;)V - public final fun setSuperClass (Ljava/lang/String;)V - public final fun setType (Ljava/lang/String;)V -} - -public final class app/revanced/patcher/dex/mutable/MutableClassDef$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; -} - -public final class app/revanced/patcher/dex/mutable/MutableField : com/android/tools/smali/dexlib2/base/reference/BaseFieldReference, com/android/tools/smali/dexlib2/iface/Field { - public static final field Companion Lapp/revanced/patcher/dex/mutable/MutableField$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/Field;)V - public fun getAccessFlags ()I - public fun getAnnotations ()Ljava/util/Set; - public fun getDefiningClass ()Ljava/lang/String; - public fun getHiddenApiRestrictions ()Ljava/util/Set; - public fun getInitialValue ()Lapp/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue; - public synthetic fun getInitialValue ()Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue; - public fun getName ()Ljava/lang/String; - public fun getType ()Ljava/lang/String; - public final fun setAccessFlags (I)V - public final fun setDefiningClass (Ljava/lang/String;)V - public final fun setInitialValue (Lapp/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue;)V - public final fun setName (Ljava/lang/String;)V - public final fun setType (Ljava/lang/String;)V -} - -public final class app/revanced/patcher/dex/mutable/MutableField$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Field;)Lapp/revanced/patcher/dex/mutable/MutableField; -} - -public final class app/revanced/patcher/dex/mutable/MutableMethod : com/android/tools/smali/dexlib2/base/reference/BaseMethodReference, com/android/tools/smali/dexlib2/iface/Method { - public static final field Companion Lapp/revanced/patcher/dex/mutable/MutableMethod$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/Method;)V - public fun getAccessFlags ()I - public fun getAnnotations ()Ljava/util/Set; - public fun getDefiningClass ()Ljava/lang/String; - public fun getHiddenApiRestrictions ()Ljava/util/Set; - public fun getImplementation ()Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation; - public synthetic fun getImplementation ()Lcom/android/tools/smali/dexlib2/iface/MethodImplementation; - public fun getName ()Ljava/lang/String; - public fun getParameterTypes ()Ljava/util/List; - public fun getParameters ()Ljava/util/List; - public fun getReturnType ()Ljava/lang/String; - public final fun setAccessFlags (I)V - public final fun setDefiningClass (Ljava/lang/String;)V - public final fun setName (Ljava/lang/String;)V - public final fun setReturnType (Ljava/lang/String;)V -} - -public final class app/revanced/patcher/dex/mutable/MutableMethod$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/dex/mutable/MutableMethod; -} - -public final class app/revanced/patcher/dex/mutable/MutableMethodParameter : com/android/tools/smali/dexlib2/base/BaseMethodParameter, com/android/tools/smali/dexlib2/iface/MethodParameter { - public static final field Companion Lapp/revanced/patcher/dex/mutable/MutableMethodParameter$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/MethodParameter;)V - public final fun charAt (I)C - public fun get (I)C - public fun getAnnotations ()Ljava/util/Set; - public fun getLength ()I - public fun getName ()Ljava/lang/String; - public fun getSignature ()Ljava/lang/String; - public fun getType ()Ljava/lang/String; - public final fun length ()I -} - -public final class app/revanced/patcher/dex/mutable/MutableMethodParameter$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/MethodParameter;)Lapp/revanced/patcher/dex/mutable/MutableMethodParameter; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableAnnotationEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseAnnotationEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableAnnotationEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/AnnotationEncodedValue;)V - public fun getElements ()Ljava/util/Set; - public fun getType ()Ljava/lang/String; - public final fun setType (Ljava/lang/String;)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableAnnotationEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/AnnotationEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableAnnotationEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableArrayEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseArrayEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableArrayEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)V - public fun getValue ()Ljava/util/List; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableArrayEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableArrayEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableBooleanEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseBooleanEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableBooleanEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/BooleanEncodedValue;)V - public fun getValue ()Z - public final fun setValue (Z)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableBooleanEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/BooleanEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableBooleanEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseByteEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)V - public fun getValue ()B - public final fun setValue (B)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableCharEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseCharEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableCharEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/CharEncodedValue;)V - public fun getValue ()C - public final fun setValue (C)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableCharEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/CharEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableCharEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableDoubleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseDoubleEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableDoubleEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/DoubleEncodedValue;)V - public fun getValue ()D - public final fun setValue (D)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableDoubleEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/DoubleEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableDoubleEncodedValue; -} - -public abstract interface class app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue : com/android/tools/smali/dexlib2/iface/value/EncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue$Companion; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableEnumEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseEnumEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableEnumEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/EnumEncodedValue;)V - public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference; - public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference;)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableEnumEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EnumEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableEnumEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableFieldEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFieldEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableFieldEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/FieldEncodedValue;)V - public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference; - public fun getValueType ()I - public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference;)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableFieldEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FieldEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableFieldEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableFloatEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFloatEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableFloatEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/FloatEncodedValue;)V - public fun getValue ()F - public final fun setValue (F)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableFloatEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FloatEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableFloatEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableIntEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseIntEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableIntEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/IntEncodedValue;)V - public fun getValue ()I - public final fun setValue (I)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableIntEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/IntEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableIntEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableLongEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseLongEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableLongEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/LongEncodedValue;)V - public fun getValue ()J - public final fun setValue (J)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableLongEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/LongEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableLongEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableMethodEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableMethodEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodEncodedValue;)V - public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference; - public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableMethodEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableMethodEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableMethodHandleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodHandleEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableMethodHandleEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodHandleEncodedValue;)V - public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodHandleReference; - public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodHandleReference;)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableMethodHandleEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodHandleEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableMethodHandleEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableMethodTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodTypeEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableMethodTypeEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodTypeEncodedValue;)V - public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodProtoReference; - public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodProtoReference;)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableMethodTypeEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodTypeEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableMethodTypeEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableNullEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseNullEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableNullEncodedValue$Companion; - public fun ()V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableNullEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableShortEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseShortEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableShortEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/ShortEncodedValue;)V - public fun getValue ()S - public final fun setValue (S)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableShortEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ShortEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableShortEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableStringEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseStringEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableStringEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/StringEncodedValue;)V - public fun getValue ()Ljava/lang/String; - public final fun setValue (Ljava/lang/String;)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableStringEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue; -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseTypeEncodedValue, app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue { - public static final field Companion Lapp/revanced/patcher/dex/mutable/encodedValue/MutableTypeEncodedValue$Companion; - public fun (Lcom/android/tools/smali/dexlib2/iface/value/TypeEncodedValue;)V - public fun getValue ()Ljava/lang/String; - public final fun setValue (Ljava/lang/String;)V -} - -public final class app/revanced/patcher/dex/mutable/encodedValue/MutableTypeEncodedValue$Companion { - public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/TypeEncodedValue;)Lapp/revanced/patcher/dex/mutable/encodedValue/MutableTypeEncodedValue; +public final class app/revanced/patcher/PredicateContext : java/util/Map, kotlin/jvm/internal/markers/KMutableMap { + public fun clear ()V + public fun containsKey (Ljava/lang/Object;)Z + public fun containsValue (Ljava/lang/Object;)Z + public final fun entrySet ()Ljava/util/Set; + public fun get (Ljava/lang/Object;)Ljava/lang/Object; + public fun getEntries ()Ljava/util/Set; + public fun getKeys ()Ljava/util/Set; + public fun getSize ()I + public fun getValues ()Ljava/util/Collection; + public fun isEmpty ()Z + public final fun keySet ()Ljava/util/Set; + public fun put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun putAll (Ljava/util/Map;)V + public fun remove (Ljava/lang/Object;)Ljava/lang/Object; + public final fun size ()I + public final fun values ()Ljava/util/Collection; } public final class app/revanced/patcher/extensions/ExternalLabel { @@ -786,66 +357,58 @@ public final class app/revanced/patcher/extensions/ExternalLabel { } public final class app/revanced/patcher/extensions/InstructionKt { - public static final fun fieldReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Ljava/lang/String;)Z - public static final fun fieldReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Lkotlin/jvm/functions/Function1;)Z public static final fun getFieldReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference; public static final fun getMethodReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference; public static final fun getReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/Reference; + public static final fun getString (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Ljava/lang/String; public static final fun getStringReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/StringReference; + public static final fun getType (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Ljava/lang/String; public static final fun getTypeReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/TypeReference; public static final fun getWideLiteral (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Ljava/lang/Long; - public static final fun methodReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;)Z - public static final fun methodReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Lkotlin/jvm/functions/Function1;)Z - public static final fun opcode (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Lcom/android/tools/smali/dexlib2/Opcode;)Z - public static final fun reference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Lkotlin/jvm/functions/Function1;)Z - public static final fun reference2 (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Lkotlin/jvm/functions/Function1;)Z - public static final fun string (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Ljava/lang/String;)Z - public static final fun string (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Lkotlin/jvm/functions/Function1;)Z - public static final fun type (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Ljava/lang/String;)Z - public static final fun type (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;Lkotlin/jvm/functions/Function1;)Z - public static final fun wideLiteral (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;J)Z + public static final fun toInstructions (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;)Ljava/util/List; + public static synthetic fun toInstructions$default (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/Object;)Ljava/util/List; } public final class app/revanced/patcher/extensions/MethodKt { public static final fun accessFlags (Lcom/android/tools/smali/dexlib2/iface/Method;[Lcom/android/tools/smali/dexlib2/AccessFlags;)Z - public static final fun addInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V - public static final fun addInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILjava/lang/String;)V - public static final fun addInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V - public static final fun addInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;Ljava/lang/String;)V - public static final fun addInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILjava/lang/String;)V - public static final fun addInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILjava/util/List;)V - public static final fun addInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;Ljava/lang/String;)V - public static final fun addInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;Ljava/util/List;)V + public static final fun addInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V + public static final fun addInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;)V + public static final fun addInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V + public static final fun addInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;Ljava/lang/String;)V public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;Ljava/util/List;)V - public static final fun addInstructionsWithLabels (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILjava/lang/String;[Lapp/revanced/patcher/extensions/ExternalLabel;)V - public static final fun getInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction; - public static final fun getInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;I)Ljava/lang/Object; + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/util/List;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;Ljava/lang/String;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;Ljava/util/List;)V + public static final fun addInstructionsWithLabels (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;[Lapp/revanced/patcher/extensions/ExternalLabel;)V public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction; public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)Ljava/lang/Object; public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;I)Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction; public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;I)Ljava/lang/Object; public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/iface/MethodImplementation;I)Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction; public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/iface/MethodImplementation;I)Ljava/lang/Object; - public static final fun getInstructionOrNull (Lapp/revanced/patcher/dex/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction; - public static final fun getInstructionOrNull (Lapp/revanced/patcher/dex/mutable/MutableMethod;I)Ljava/lang/Object; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Ljava/lang/Object; public static final fun getInstructionOrNull (Lcom/android/tools/smali/dexlib2/iface/Method;I)Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction; public static final fun getInstructionOrNull (Lcom/android/tools/smali/dexlib2/iface/Method;I)Ljava/lang/Object; - public static final fun getInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;)Ljava/util/List; + public static final fun getInstructionOrNull (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction; + public static final fun getInstructionOrNull (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Ljava/lang/Object; public static final fun getInstructions (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Iterable; - public static final fun getInstructionsOrNull (Lapp/revanced/patcher/dex/mutable/MutableMethod;)Ljava/util/List; + public static final fun getInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;)Ljava/util/List; public static final fun getInstructionsOrNull (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Iterable; - public static final fun newLabel (Lapp/revanced/patcher/dex/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/Label; - public static final fun removeInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;I)V - public static final fun removeInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;I)V - public static final fun removeInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;II)V + public static final fun getInstructionsOrNull (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;)Ljava/util/List; + public static final fun newLabel (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/Label; + public static final fun removeInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)V public static final fun removeInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)V public static final fun removeInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;II)V - public static final fun replaceInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V - public static final fun replaceInstruction (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILjava/lang/String;)V - public static final fun replaceInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILjava/lang/String;)V - public static final fun replaceInstructions (Lapp/revanced/patcher/dex/mutable/MutableMethod;ILjava/util/List;)V + public static final fun removeInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)V + public static final fun removeInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;II)V + public static final fun replaceInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V + public static final fun replaceInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;)V public static final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V + public static final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;)V + public static final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/util/List;)V } public final class app/revanced/patcher/patch/BytecodePatch : app/revanced/patcher/patch/Patch { @@ -854,7 +417,7 @@ public final class app/revanced/patcher/patch/BytecodePatch : app/revanced/patch } public final class app/revanced/patcher/patch/BytecodePatchBuilder : app/revanced/patcher/patch/PatchBuilder { - public synthetic fun build$revanced_patcher ()Lapp/revanced/patcher/patch/Patch; + public synthetic fun build$core ()Lapp/revanced/patcher/patch/Patch; public final fun extendWith (Ljava/lang/String;)Lapp/revanced/patcher/patch/BytecodePatchBuilder; public final fun getExtensionInputStream ()Ljava/util/function/Supplier; public final fun setExtensionInputStream (Ljava/util/function/Supplier;)V @@ -864,11 +427,35 @@ public final class app/revanced/patcher/patch/BytecodePatchContext : app/revance public fun close ()V public synthetic fun get ()Ljava/lang/Object; public fun get ()Ljava/util/Set; - public final fun getClassDefs ()Ljava/util/Set; - public final fun mutable (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/dex/mutable/MutableClassDef; + public final fun getClassDefs ()Lapp/revanced/patcher/patch/BytecodePatchContext$ClassDefs; public final fun navigate (Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;)Lapp/revanced/patcher/util/MethodNavigator; } +public final class app/revanced/patcher/patch/BytecodePatchContext$ClassDefs : java/util/Set, kotlin/jvm/internal/markers/KMutableSet { + public fun (Lapp/revanced/patcher/patch/BytecodePatchContext;)V + public fun add (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z + public synthetic fun add (Ljava/lang/Object;)Z + public fun addAll (Ljava/util/Collection;)Z + public fun clear ()V + public fun contains (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z + public final fun contains (Ljava/lang/Object;)Z + public fun containsAll (Ljava/util/Collection;)Z + public final fun get (Ljava/lang/String;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public final fun getMethodsByString ()Ljava/util/Map; + public final fun getOrReplaceMutable (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public fun getSize ()I + public fun isEmpty ()Z + public fun iterator ()Ljava/util/Iterator; + public fun remove (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z + public final fun remove (Ljava/lang/Object;)Z + public fun removeAll (Ljava/util/Collection;)Z + public fun removeIf (Ljava/util/function/Predicate;)Z + public fun retainAll (Ljava/util/Collection;)Z + public final fun size ()I + public fun toArray ()[Ljava/lang/Object; + public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; +} + public final class app/revanced/patcher/patch/Option { public fun (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/reflect/KType;Lkotlin/jvm/functions/Function2;)V public synthetic fun (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/reflect/KType;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -1048,18 +635,23 @@ public final class app/revanced/patcher/patch/PatchKt { public static synthetic fun gettingRawResourcePatch$default (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; public static final fun gettingResourcePatch (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty; public static synthetic fun gettingResourcePatch$default (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; - public static final fun loadPatchesFromDex (Ljava/util/Set;Ljava/io/File;)Lapp/revanced/patcher/patch/PatchLoader$Dex; - public static synthetic fun loadPatchesFromDex$default (Ljava/util/Set;Ljava/io/File;ILjava/lang/Object;)Lapp/revanced/patcher/patch/PatchLoader$Dex; - public static final fun loadPatchesFromJar (Ljava/util/Set;)Lapp/revanced/patcher/patch/PatchLoader$Jar; public static final fun rawResourcePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/RawResourcePatch; public static synthetic fun rawResourcePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/RawResourcePatch; public static final fun resourcePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/ResourcePatch; public static synthetic fun resourcePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch; } -public abstract class app/revanced/patcher/patch/PatchLoader : java/util/Set, kotlin/jvm/internal/markers/KMappedMarker { - public synthetic fun (Ljava/util/Map;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun (Ljava/util/Set;Lkotlin/jvm/functions/Function1;Ljava/lang/ClassLoader;Lkotlin/jvm/internal/DefaultConstructorMarker;)V +public final class app/revanced/patcher/patch/PatchResult { + public final fun getException ()Lapp/revanced/patcher/patch/PatchException; + public final fun getPatch ()Lapp/revanced/patcher/patch/Patch; +} + +public final class app/revanced/patcher/patch/Patch_androidKt { + public static final fun isPatch (Ljava/lang/Class;)Z + public static final fun loadPatches (Ljava/util/Set;)Lapp/revanced/patcher/patch/Patches; +} + +public final class app/revanced/patcher/patch/Patches : java/util/Set, kotlin/jvm/internal/markers/KMappedMarker { public fun add (Lapp/revanced/patcher/patch/Patch;)Z public synthetic fun add (Ljava/lang/Object;)Z public fun addAll (Ljava/util/Collection;)Z @@ -1067,7 +659,7 @@ public abstract class app/revanced/patcher/patch/PatchLoader : java/util/Set, ko public fun contains (Lapp/revanced/patcher/patch/Patch;)Z public final fun contains (Ljava/lang/Object;)Z public fun containsAll (Ljava/util/Collection;)Z - public final fun getByPatchesFile ()Ljava/util/Map; + public final fun getPatchesByFile ()Ljava/util/Map; public fun getSize ()I public fun isEmpty ()Z public fun iterator ()Ljava/util/Iterator; @@ -1079,26 +671,12 @@ public abstract class app/revanced/patcher/patch/PatchLoader : java/util/Set, ko public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; } -public final class app/revanced/patcher/patch/PatchLoader$Dex : app/revanced/patcher/patch/PatchLoader { - public fun (Ljava/util/Set;Ljava/io/File;)V - public synthetic fun (Ljava/util/Set;Ljava/io/File;ILkotlin/jvm/internal/DefaultConstructorMarker;)V -} - -public final class app/revanced/patcher/patch/PatchLoader$Jar : app/revanced/patcher/patch/PatchLoader { - public fun (Ljava/util/Set;)V -} - -public final class app/revanced/patcher/patch/PatchResult { - public final fun getException ()Lapp/revanced/patcher/patch/PatchException; - public final fun getPatch ()Lapp/revanced/patcher/patch/Patch; -} - public final class app/revanced/patcher/patch/RawResourcePatch : app/revanced/patcher/patch/Patch { public fun toString ()Ljava/lang/String; } public final class app/revanced/patcher/patch/RawResourcePatchBuilder : app/revanced/patcher/patch/PatchBuilder { - public synthetic fun build$revanced_patcher ()Lapp/revanced/patcher/patch/Patch; + public synthetic fun build$core ()Lapp/revanced/patcher/patch/Patch; } public final class app/revanced/patcher/patch/ResourcePatch : app/revanced/patcher/patch/Patch { @@ -1106,7 +684,7 @@ public final class app/revanced/patcher/patch/ResourcePatch : app/revanced/patch } public final class app/revanced/patcher/patch/ResourcePatchBuilder : app/revanced/patcher/patch/PatchBuilder { - public synthetic fun build$revanced_patcher ()Lapp/revanced/patcher/patch/Patch; + public synthetic fun build$core ()Lapp/revanced/patcher/patch/Patch; } public final class app/revanced/patcher/patch/ResourcePatchContext : app/revanced/patcher/patch/PatchContext { @@ -1192,16 +770,339 @@ public final class app/revanced/patcher/util/Document : java/io/Closeable, org/w } public final class app/revanced/patcher/util/MethodNavigator { - public final fun getValue (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/reflect/KProperty;)Lapp/revanced/patcher/dex/mutable/MutableMethod; + public final fun getValue (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/reflect/KProperty;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public final fun original (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/Method; - public final fun stop (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/dex/mutable/MutableMethod; + public final fun stop (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public final fun to (Lapp/revanced/patcher/patch/BytecodePatchContext;ILkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/MethodNavigator; public final fun to (Lapp/revanced/patcher/patch/BytecodePatchContext;[I)Lapp/revanced/patcher/util/MethodNavigator; public static synthetic fun to$default (Lapp/revanced/patcher/util/MethodNavigator;Lapp/revanced/patcher/patch/BytecodePatchContext;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/util/MethodNavigator; } -public final class app/revanced/patcher/util/SmaliKt { - public static final fun toInstructions (Ljava/lang/String;Lapp/revanced/patcher/dex/mutable/MutableMethod;)Ljava/util/List; - public static synthetic fun toInstructions$default (Ljava/lang/String;Lapp/revanced/patcher/dex/mutable/MutableMethod;ILjava/lang/Object;)Ljava/util/List; +public final class com/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseAnnotationEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/AnnotationEncodedValue;)V + public fun getElements ()Ljava/util/Set; + public fun getType ()Ljava/lang/String; + public final fun setType (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/AnnotationEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseArrayEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)V + public fun getValue ()Ljava/util/List; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseBooleanEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/BooleanEncodedValue;)V + public fun getValue ()Z + public final fun setValue (Z)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/BooleanEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseByteEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)V + public fun getValue ()B + public final fun setValue (B)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseCharEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/CharEncodedValue;)V + public fun getValue ()C + public final fun setValue (C)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/CharEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseDoubleEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/DoubleEncodedValue;)V + public fun getValue ()D + public final fun setValue (D)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/DoubleEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue; +} + +public abstract interface class com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue : com/android/tools/smali/dexlib2/iface/value/EncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue$Companion; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseEnumEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/EnumEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference; + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EnumEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFieldEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/FieldEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference; + public fun getValueType ()I + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FieldEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFloatEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/FloatEncodedValue;)V + public fun getValue ()F + public final fun setValue (F)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FloatEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseIntEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/IntEncodedValue;)V + public fun getValue ()I + public final fun setValue (I)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/IntEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseLongEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/LongEncodedValue;)V + public fun getValue ()J + public final fun setValue (J)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/LongEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference; + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodHandleEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodHandleEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodHandleReference; + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodHandleReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodHandleEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodTypeEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodTypeEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodProtoReference; + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodProtoReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodTypeEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseNullEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue$Companion; + public fun ()V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseShortEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/ShortEncodedValue;)V + public fun getValue ()S + public final fun setValue (S)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ShortEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseStringEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/StringEncodedValue;)V + public fun getValue ()Ljava/lang/String; + public final fun setValue (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseTypeEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/TypeEncodedValue;)V + public fun getValue ()Ljava/lang/String; + public final fun setValue (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/TypeEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableAnnotation : com/android/tools/smali/dexlib2/base/BaseAnnotation { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableAnnotation$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/Annotation;)V + public fun getElements ()Ljava/util/Set; + public fun getType ()Ljava/lang/String; + public fun getVisibility ()I +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableAnnotation$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Annotation;)Lcom/android/tools/smali/dexlib2/mutable/MutableAnnotation; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableAnnotationElement : com/android/tools/smali/dexlib2/base/BaseAnnotationElement { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableAnnotationElement$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/AnnotationElement;)V + public fun getName ()Ljava/lang/String; + public synthetic fun getValue ()Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue; + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue; + public final fun setName (Ljava/lang/String;)V + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue;)V +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableAnnotationElement$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/AnnotationElement;)Lcom/android/tools/smali/dexlib2/mutable/MutableAnnotationElement; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableClassDef : com/android/tools/smali/dexlib2/base/reference/BaseTypeReference, com/android/tools/smali/dexlib2/iface/ClassDef { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)V + public final fun charAt (I)C + public fun get (I)C + public fun getAccessFlags ()I + public fun getAnnotations ()Ljava/util/Set; + public synthetic fun getDirectMethods ()Ljava/lang/Iterable; + public fun getDirectMethods ()Ljava/util/Set; + public synthetic fun getFields ()Ljava/lang/Iterable; + public fun getFields ()Ljava/util/Set; + public synthetic fun getInstanceFields ()Ljava/lang/Iterable; + public fun getInstanceFields ()Ljava/util/Set; + public fun getInterfaces ()Ljava/util/List; + public fun getLength ()I + public synthetic fun getMethods ()Ljava/lang/Iterable; + public fun getMethods ()Ljava/util/Set; + public fun getSourceFile ()Ljava/lang/String; + public synthetic fun getStaticFields ()Ljava/lang/Iterable; + public fun getStaticFields ()Ljava/util/Set; + public fun getSuperclass ()Ljava/lang/String; + public fun getType ()Ljava/lang/String; + public synthetic fun getVirtualMethods ()Ljava/lang/Iterable; + public fun getVirtualMethods ()Ljava/util/Set; + public final fun length ()I + public final fun setAccessFlags (I)V + public final fun setSourceFile (Ljava/lang/String;)V + public final fun setSuperClass (Ljava/lang/String;)V + public final fun setType (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableClassDef$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableField : com/android/tools/smali/dexlib2/base/reference/BaseFieldReference, com/android/tools/smali/dexlib2/iface/Field { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableField$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/Field;)V + public fun getAccessFlags ()I + public fun getAnnotations ()Ljava/util/Set; + public fun getDefiningClass ()Ljava/lang/String; + public fun getHiddenApiRestrictions ()Ljava/util/Set; + public synthetic fun getInitialValue ()Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue; + public fun getInitialValue ()Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue; + public fun getName ()Ljava/lang/String; + public fun getType ()Ljava/lang/String; + public final fun setAccessFlags (I)V + public final fun setDefiningClass (Ljava/lang/String;)V + public final fun setInitialValue (Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue;)V + public final fun setName (Ljava/lang/String;)V + public final fun setType (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableField$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Field;)Lcom/android/tools/smali/dexlib2/mutable/MutableField; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableMethod : com/android/tools/smali/dexlib2/base/reference/BaseMethodReference, com/android/tools/smali/dexlib2/iface/Method { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableMethod$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/Method;)V + public fun getAccessFlags ()I + public fun getAnnotations ()Ljava/util/Set; + public fun getDefiningClass ()Ljava/lang/String; + public fun getHiddenApiRestrictions ()Ljava/util/Set; + public fun getImplementation ()Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation; + public synthetic fun getImplementation ()Lcom/android/tools/smali/dexlib2/iface/MethodImplementation; + public fun getName ()Ljava/lang/String; + public fun getParameterTypes ()Ljava/util/List; + public fun getParameters ()Ljava/util/List; + public fun getReturnType ()Ljava/lang/String; + public final fun setAccessFlags (I)V + public final fun setDefiningClass (Ljava/lang/String;)V + public final fun setName (Ljava/lang/String;)V + public final fun setReturnType (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableMethod$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Method;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableMethodParameter : com/android/tools/smali/dexlib2/base/BaseMethodParameter, com/android/tools/smali/dexlib2/iface/MethodParameter { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableMethodParameter$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/MethodParameter;)V + public final fun charAt (I)C + public fun get (I)C + public fun getAnnotations ()Ljava/util/Set; + public fun getLength ()I + public fun getName ()Ljava/lang/String; + public fun getSignature ()Ljava/lang/String; + public fun getType ()Ljava/lang/String; + public final fun length ()I +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableMethodParameter$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/MethodParameter;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethodParameter; } diff --git a/core/api/jvm/core.api b/core/api/jvm/core.api new file mode 100644 index 0000000..b11a860 --- /dev/null +++ b/core/api/jvm/core.api @@ -0,0 +1,1108 @@ +public final class app/revanced/patcher/CachedReadOnlyProperty : kotlin/properties/ReadOnlyProperty { + public fun getValue (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; +} + +public final class app/revanced/patcher/Composition { + public final fun getIndices ()Ljava/util/List; + public final fun getMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getStrings ()Ljava/util/List; +} + +public final class app/revanced/patcher/DeclarativePredicateBuilder { + public final fun all (Ljava/lang/Object;)Z + public final fun any (Ljava/lang/Object;)Z + public final fun anyOf (Lkotlin/jvm/functions/Function1;)V + public final fun predicate (Lkotlin/jvm/functions/Function1;)V +} + +public final class app/revanced/patcher/Fingerprint { + public final fun getClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public final fun getClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public final fun getMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getOriginalClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public final fun getOriginalClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public final fun getOriginalMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/Method; + public final fun getOriginalMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/Method; + public final fun getPatternMatch (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/Match$PatternMatch; + public final fun getPatternMatchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lapp/revanced/patcher/Match$PatternMatch; + public final fun getStringMatches (Lapp/revanced/patcher/patch/BytecodePatchContext;)Ljava/util/List; + public final fun getStringMatchesOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Ljava/util/List; + public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; + public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/Match; + public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; + public final fun matchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; + public final fun matchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/Match; + public final fun matchOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; +} + +public final class app/revanced/patcher/FingerprintBuilder { + public fun ()V + public final fun accessFlags (I)V + public final fun accessFlags ([Lcom/android/tools/smali/dexlib2/AccessFlags;)V + public final fun custom (Lkotlin/jvm/functions/Function2;)V + public final fun opcodes (Ljava/lang/String;)V + public final fun opcodes ([Lcom/android/tools/smali/dexlib2/Opcode;)V + public final fun parameters ([Ljava/lang/String;)V + public final fun returns (Ljava/lang/String;)V + public final fun strings ([Ljava/lang/String;)V +} + +public final class app/revanced/patcher/FingerprintKt { + public static final fun fingerprint (ILkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/Fingerprint; + public static synthetic fun fingerprint$default (ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/Fingerprint; +} + +public final class app/revanced/patcher/IndexedMatcher : app/revanced/patcher/Matcher { + public fun ()V + public final fun contains (Ljava/lang/Object;)Z + public fun contains (Lkotlin/jvm/functions/Function3;)Z + public final fun getIndices ()Ljava/util/List; + public final fun getNextIndex ()Ljava/lang/Integer; + public final fun indexOf (Ljava/lang/Object;)I + public fun indexOf (Lkotlin/jvm/functions/Function3;)I + public fun invoke (Ljava/lang/Iterable;)Z + public final fun lastIndexOf (Ljava/lang/Object;)I + public fun lastIndexOf (Lkotlin/jvm/functions/Function3;)I + public final fun remove (I)Lkotlin/jvm/functions/Function3; + public final fun remove (Ljava/lang/Object;)Z + public fun remove (Lkotlin/jvm/functions/Function3;)Z + public fun removeAt (I)Lkotlin/jvm/functions/Function3; + public final fun setNextIndex (Ljava/lang/Integer;)V +} + +public abstract interface annotation class app/revanced/patcher/InternalApi : java/lang/annotation/Annotation { +} + +public final class app/revanced/patcher/Match { + public final fun getClassDef ()Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public final fun getContext ()Lapp/revanced/patcher/patch/BytecodePatchContext; + public final fun getMethod ()Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getOriginalClassDef ()Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public final fun getOriginalMethod ()Lcom/android/tools/smali/dexlib2/iface/Method; + public final fun getPatternMatch ()Lapp/revanced/patcher/Match$PatternMatch; + public final fun getStringMatches ()Ljava/util/List; +} + +public final class app/revanced/patcher/Match$PatternMatch { + public final fun getEndIndex ()I + public final fun getStartIndex ()I +} + +public final class app/revanced/patcher/Match$StringMatch { + public final fun getIndex ()I + public final fun getString ()Ljava/lang/String; +} + +public abstract class app/revanced/patcher/Matcher : java/util/List, kotlin/jvm/internal/markers/KMutableList { + public fun ()V + public fun add (ILjava/lang/Object;)V + public fun add (Ljava/lang/Object;)Z + public fun addAll (ILjava/util/Collection;)Z + public fun addAll (Ljava/util/Collection;)Z + public fun clear ()V + public fun contains (Ljava/lang/Object;)Z + public fun containsAll (Ljava/util/Collection;)Z + public fun get (I)Ljava/lang/Object; + public final fun getMatchIndex ()I + public fun getSize ()I + public fun indexOf (Ljava/lang/Object;)I + public abstract fun invoke (Ljava/lang/Iterable;)Z + public fun isEmpty ()Z + public fun iterator ()Ljava/util/Iterator; + public fun lastIndexOf (Ljava/lang/Object;)I + public fun listIterator ()Ljava/util/ListIterator; + public fun listIterator (I)Ljava/util/ListIterator; + public final fun remove (I)Ljava/lang/Object; + public fun remove (Ljava/lang/Object;)Z + public fun removeAll (Ljava/util/Collection;)Z + public fun removeAt (I)Ljava/lang/Object; + public fun retainAll (Ljava/util/Collection;)Z + public fun set (ILjava/lang/Object;)Ljava/lang/Object; + protected final fun setMatchIndex (I)V + public final fun size ()I + public fun subList (II)Ljava/util/List; + public fun toArray ()[Ljava/lang/Object; + public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; +} + +public final class app/revanced/patcher/MatchingKt { + public static final fun accessFlags (Lapp/revanced/patcher/DeclarativePredicateBuilder;[Lcom/android/tools/smali/dexlib2/AccessFlags;)V + public static final fun after (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static final fun after (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; + public static synthetic fun after$default (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun after$default (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/ranges/IntRange;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun allOf ([Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; + public static final fun anyAnnotation (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyAnnotation (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyClassDef (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyDebugItem (Lcom/android/tools/smali/dexlib2/iface/MethodImplementation;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyDirectMethod (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyField (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyHiddenApiRestriction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyInstanceField (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyInstruction (Lcom/android/tools/smali/dexlib2/iface/MethodImplementation;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyInstruction (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyInterface (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyMethod (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyOf ([Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; + public static final fun anyParameter (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyParameterType (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyStaticField (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyTryBlock (Lcom/android/tools/smali/dexlib2/iface/MethodImplementation;Lkotlin/jvm/functions/Function1;)Z + public static final fun anyVirtualMethod (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lkotlin/jvm/functions/Function1;)Z + public static final fun custom (Lapp/revanced/patcher/DeclarativePredicateBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun declarativePredicate (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z + public static final fun field (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun field (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun field$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun field$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun firstClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static synthetic fun firstClassDef$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static synthetic fun firstClassDefMutable$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static synthetic fun firstClassDefMutableOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public static final fun firstClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static synthetic fun firstClassDefOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public static final fun firstMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static synthetic fun firstMethod$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodComposite ([Ljava/lang/String;Lkotlin/jvm/functions/Function5;)Lapp/revanced/patcher/Composition; + public static final fun firstMethodMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutable (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static synthetic fun firstMethodMutable$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableByDeclarativePredicate (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableByDeclarativePredicateOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodMutableOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static synthetic fun firstMethodMutableOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public static final fun firstMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun firstMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static synthetic fun firstMethodOrNull$default (Lapp/revanced/patcher/patch/BytecodePatchContext;[Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/iface/Method; + public static final fun getM ()Lapp/revanced/patcher/Composition; + public static final fun gettingFirstClassDef (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDef (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstClassDef$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefByDeclarativePredicate (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefByDeclarativePredicate (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefByDeclarativePredicateOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefByDeclarativePredicateOrNull (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutable (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutable (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstClassDefMutable$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableByDeclarativePredicate (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableByDeclarativePredicate (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableByDeclarativePredicateOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableByDeclarativePredicateOrNull (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefMutableOrNull (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstClassDefMutableOrNull$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefOrNull (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstClassDefOrNull (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstClassDefOrNull$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethod (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethod ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstMethod$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodByDeclarativePredicate (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodByDeclarativePredicate ([Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodByDeclarativePredicateOrNull (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodByDeclarativePredicateOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutable (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutable ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstMethodMutable$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableByDeclarativePredicate (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableByDeclarativePredicate ([Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableByDeclarativePredicateOrNull (Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableByDeclarativePredicateOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function3;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableOrNull (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodMutableOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstMethodMutableOrNull$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodOrNull (Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun gettingFirstMethodOrNull ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static synthetic fun gettingFirstMethodOrNull$default ([Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/CachedReadOnlyProperty; + public static final fun head (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static final fun head (Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; + public static final fun implementation (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z + public static final fun indexedMatcher ()Lapp/revanced/patcher/IndexedMatcher; + public static final fun indexedMatcher (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/IndexedMatcher; + public static final fun instruction (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static final fun instructions (Lapp/revanced/patcher/IndexedMatcher;Lapp/revanced/patcher/DeclarativePredicateBuilder;Lkotlin/jvm/functions/Function1;)V + public static final fun instructions (Lapp/revanced/patcher/IndexedMatcher;Lapp/revanced/patcher/DeclarativePredicateBuilder;[Lkotlin/jvm/functions/Function3;)V + public static final fun invoke (Lcom/android/tools/smali/dexlib2/Opcode;)Lkotlin/jvm/functions/Function3; + public static final fun invoke (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static synthetic fun invoke$default (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun literal (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun literal (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun literal$default (JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun literal$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun matchIndexed (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z + public static final fun method (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun method (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun method$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun method$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun noneOf ([Lkotlin/jvm/functions/Function3;)Lkotlin/jvm/functions/Function3; + public static final fun parameterTypes (Lapp/revanced/patcher/DeclarativePredicateBuilder;[Ljava/lang/String;)V + public static final fun reference (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun reference (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun reference$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun reference$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun registers (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static final fun registers ([ILkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static synthetic fun registers$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun registers$default ([ILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun rememberedDeclarativePredicate (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z + public static final fun rememberedMatchIndexed (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z + public static final fun returns (Lapp/revanced/patcher/DeclarativePredicateBuilder;Ljava/lang/String;)V + public static final fun string (Ljava/util/List;Lapp/revanced/patcher/DeclarativePredicateBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun string (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun string$default (Ljava/util/List;Lapp/revanced/patcher/DeclarativePredicateBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun string$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun type (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function3; + public static final fun type (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function3; + public static synthetic fun type$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static synthetic fun type$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function3; + public static final fun unaryPlus (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/jvm/functions/Function3;)Z +} + +public final class app/revanced/patcher/PackageMetadata { + public final fun getPackageName ()Ljava/lang/String; + public final fun getPackageVersion ()Ljava/lang/String; +} + +public final class app/revanced/patcher/Patcher : java/io/Closeable { + public fun (Lapp/revanced/patcher/PatcherConfig;)V + public fun close ()V + public final fun get ()Lapp/revanced/patcher/PatcherResult; + public final fun getContext ()Lapp/revanced/patcher/PatcherContext; + public final fun invoke ()Lkotlinx/coroutines/flow/Flow; + public final fun plusAssign (Ljava/util/Set;)V +} + +public final class app/revanced/patcher/PatcherConfig { + public fun (Ljava/io/File;Ljava/io/File;Ljava/io/File;Ljava/lang/String;)V + public synthetic fun (Ljava/io/File;Ljava/io/File;Ljava/io/File;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V +} + +public final class app/revanced/patcher/PatcherContext : java/io/Closeable { + public fun close ()V + public final fun getPackageMetadata ()Lapp/revanced/patcher/PackageMetadata; +} + +public final class app/revanced/patcher/PatcherResult { + public final fun getDexFiles ()Ljava/util/Set; + public final fun getResources ()Lapp/revanced/patcher/PatcherResult$PatchedResources; +} + +public final class app/revanced/patcher/PatcherResult$PatchedDexFile { + public final fun getName ()Ljava/lang/String; + public final fun getStream ()Ljava/io/InputStream; +} + +public final class app/revanced/patcher/PatcherResult$PatchedResources { + public final fun getDeleteResources ()Ljava/util/Set; + public final fun getDoNotCompress ()Ljava/util/Set; + public final fun getOtherResources ()Ljava/io/File; + public final fun getResourcesApk ()Ljava/io/File; +} + +public final class app/revanced/patcher/PredicateContext : java/util/Map, kotlin/jvm/internal/markers/KMutableMap { + public fun clear ()V + public fun containsKey (Ljava/lang/Object;)Z + public fun containsValue (Ljava/lang/Object;)Z + public final fun entrySet ()Ljava/util/Set; + public fun get (Ljava/lang/Object;)Ljava/lang/Object; + public fun getEntries ()Ljava/util/Set; + public fun getKeys ()Ljava/util/Set; + public fun getSize ()I + public fun getValues ()Ljava/util/Collection; + public fun isEmpty ()Z + public final fun keySet ()Ljava/util/Set; + public fun put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun putAll (Ljava/util/Map;)V + public fun remove (Ljava/lang/Object;)Ljava/lang/Object; + public final fun size ()I + public final fun values ()Ljava/util/Collection; +} + +public final class app/revanced/patcher/extensions/ExternalLabel { + public fun (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)V + public final fun copy (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lapp/revanced/patcher/extensions/ExternalLabel; + public static synthetic fun copy$default (Lapp/revanced/patcher/extensions/ExternalLabel;Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;ILjava/lang/Object;)Lapp/revanced/patcher/extensions/ExternalLabel; + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class app/revanced/patcher/extensions/InstructionKt { + public static final fun getFieldReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference; + public static final fun getMethodReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference; + public static final fun getReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/Reference; + public static final fun getString (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Ljava/lang/String; + public static final fun getStringReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/StringReference; + public static final fun getType (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Ljava/lang/String; + public static final fun getTypeReference (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lcom/android/tools/smali/dexlib2/iface/reference/TypeReference; + public static final fun getWideLiteral (Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Ljava/lang/Long; + public static final fun toInstructions (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;)Ljava/util/List; + public static synthetic fun toInstructions$default (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/Object;)Ljava/util/List; +} + +public final class app/revanced/patcher/extensions/MethodKt { + public static final fun accessFlags (Lcom/android/tools/smali/dexlib2/iface/Method;[Lcom/android/tools/smali/dexlib2/AccessFlags;)Z + public static final fun addInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V + public static final fun addInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;)V + public static final fun addInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V + public static final fun addInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;Ljava/lang/String;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;Ljava/util/List;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/util/List;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;Ljava/lang/String;)V + public static final fun addInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;Ljava/util/List;)V + public static final fun addInstructionsWithLabels (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;[Lapp/revanced/patcher/extensions/ExternalLabel;)V + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)Ljava/lang/Object; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;I)Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;I)Ljava/lang/Object; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/iface/MethodImplementation;I)Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/iface/MethodImplementation;I)Ljava/lang/Object; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction; + public static final fun getInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Ljava/lang/Object; + public static final fun getInstructionOrNull (Lcom/android/tools/smali/dexlib2/iface/Method;I)Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction; + public static final fun getInstructionOrNull (Lcom/android/tools/smali/dexlib2/iface/Method;I)Ljava/lang/Object; + public static final fun getInstructionOrNull (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction; + public static final fun getInstructionOrNull (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Ljava/lang/Object; + public static final fun getInstructions (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Iterable; + public static final fun getInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;)Ljava/util/List; + public static final fun getInstructionsOrNull (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Iterable; + public static final fun getInstructionsOrNull (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;)Ljava/util/List; + public static final fun newLabel (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/Label; + public static final fun removeInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)V + public static final fun removeInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)V + public static final fun removeInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;II)V + public static final fun removeInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;I)V + public static final fun removeInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;II)V + public static final fun replaceInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V + public static final fun replaceInstruction (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;)V + public static final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V + public static final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/lang/String;)V + public static final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/mutable/MutableMethod;ILjava/util/List;)V +} + +public final class app/revanced/patcher/patch/BytecodePatch : app/revanced/patcher/patch/Patch { + public final fun getExtensionInputStream ()Ljava/util/function/Supplier; + public fun toString ()Ljava/lang/String; +} + +public final class app/revanced/patcher/patch/BytecodePatchBuilder : app/revanced/patcher/patch/PatchBuilder { + public synthetic fun build$core ()Lapp/revanced/patcher/patch/Patch; + public final fun extendWith (Ljava/lang/String;)Lapp/revanced/patcher/patch/BytecodePatchBuilder; + public final fun getExtensionInputStream ()Ljava/util/function/Supplier; + public final fun setExtensionInputStream (Ljava/util/function/Supplier;)V +} + +public final class app/revanced/patcher/patch/BytecodePatchContext : app/revanced/patcher/patch/PatchContext, java/io/Closeable { + public fun close ()V + public synthetic fun get ()Ljava/lang/Object; + public fun get ()Ljava/util/Set; + public final fun getClassDefs ()Lapp/revanced/patcher/patch/BytecodePatchContext$ClassDefs; + public final fun navigate (Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;)Lapp/revanced/patcher/util/MethodNavigator; +} + +public final class app/revanced/patcher/patch/BytecodePatchContext$ClassDefs : java/util/Set, kotlin/jvm/internal/markers/KMutableSet { + public fun (Lapp/revanced/patcher/patch/BytecodePatchContext;)V + public fun add (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z + public synthetic fun add (Ljava/lang/Object;)Z + public fun addAll (Ljava/util/Collection;)Z + public fun clear ()V + public fun contains (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z + public final fun contains (Ljava/lang/Object;)Z + public fun containsAll (Ljava/util/Collection;)Z + public final fun get (Ljava/lang/String;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; + public final fun getMethodsByString ()Ljava/util/Map; + public final fun getOrReplaceMutable (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; + public fun getSize ()I + public fun isEmpty ()Z + public fun iterator ()Ljava/util/Iterator; + public fun remove (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z + public final fun remove (Ljava/lang/Object;)Z + public fun removeAll (Ljava/util/Collection;)Z + public fun removeIf (Ljava/util/function/Predicate;)Z + public fun retainAll (Ljava/util/Collection;)Z + public final fun size ()I + public fun toArray ()[Ljava/lang/Object; + public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; +} + +public final class app/revanced/patcher/patch/Option { + public fun (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/reflect/KType;Lkotlin/jvm/functions/Function2;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/reflect/KType;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;ZLkotlin/reflect/KType;Lkotlin/jvm/functions/Function2;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;ZLkotlin/reflect/KType;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getDefault ()Ljava/lang/Object; + public final fun getDescription ()Ljava/lang/String; + public final fun getKey ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getRequired ()Z + public final fun getTitle ()Ljava/lang/String; + public final fun getType ()Lkotlin/reflect/KType; + public final fun getValidator ()Lkotlin/jvm/functions/Function2; + public final fun getValue ()Ljava/lang/Object; + public final fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; + public final fun getValues ()Ljava/util/Map; + public final fun reset ()V + public final fun setValue (Ljava/lang/Object;)V + public final fun setValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;Ljava/lang/Object;)V + public fun toString ()Ljava/lang/String; +} + +public abstract class app/revanced/patcher/patch/OptionException : java/lang/Exception { + public synthetic fun (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V +} + +public final class app/revanced/patcher/patch/OptionException$InvalidValueTypeException : app/revanced/patcher/patch/OptionException { + public fun (Ljava/lang/String;Ljava/lang/String;)V +} + +public final class app/revanced/patcher/patch/OptionException$OptionNotFoundException : app/revanced/patcher/patch/OptionException { + public fun (Ljava/lang/String;)V +} + +public final class app/revanced/patcher/patch/OptionException$ValueRequiredException : app/revanced/patcher/patch/OptionException { + public fun (Lapp/revanced/patcher/patch/Option;)V +} + +public final class app/revanced/patcher/patch/OptionException$ValueValidationException : app/revanced/patcher/patch/OptionException { + public fun (Ljava/lang/Object;Lapp/revanced/patcher/patch/Option;)V +} + +public final class app/revanced/patcher/patch/OptionKt { + public static final fun booleanOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun booleanOption (Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun booleanOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun booleanOption$default (Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun booleansOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun booleansOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun booleansOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun booleansOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun floatOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun floatOption (Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun floatOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun floatOption$default (Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun floatsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun floatsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun intOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun intOption (Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun intOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun intOption$default (Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun intsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun intsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun intsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun intsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun longOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun longOption (Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun longOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun longOption$default (Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun longsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun longsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun longsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun longsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun stringOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun stringOption (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun stringOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun stringOption$default (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static final fun stringsOption (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static final fun stringsOption (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun stringsOption$default (Lapp/revanced/patcher/patch/PatchBuilder;Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public static synthetic fun stringsOption$default (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lapp/revanced/patcher/patch/Option; +} + +public final class app/revanced/patcher/patch/Options : java/util/Map, kotlin/jvm/internal/markers/KMappedMarker { + public fun clear ()V + public synthetic fun compute (Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object; + public fun compute (Ljava/lang/String;Ljava/util/function/BiFunction;)Lapp/revanced/patcher/patch/Option; + public synthetic fun computeIfAbsent (Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object; + public fun computeIfAbsent (Ljava/lang/String;Ljava/util/function/Function;)Lapp/revanced/patcher/patch/Option; + public synthetic fun computeIfPresent (Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object; + public fun computeIfPresent (Ljava/lang/String;Ljava/util/function/BiFunction;)Lapp/revanced/patcher/patch/Option; + public final fun containsKey (Ljava/lang/Object;)Z + public fun containsKey (Ljava/lang/String;)Z + public fun containsValue (Lapp/revanced/patcher/patch/Option;)Z + public final fun containsValue (Ljava/lang/Object;)Z + public final fun entrySet ()Ljava/util/Set; + public final fun get (Ljava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public final synthetic fun get (Ljava/lang/Object;)Ljava/lang/Object; + public fun get (Ljava/lang/String;)Lapp/revanced/patcher/patch/Option; + public fun getEntries ()Ljava/util/Set; + public fun getKeys ()Ljava/util/Set; + public fun getSize ()I + public fun getValues ()Ljava/util/Collection; + public fun isEmpty ()Z + public final fun keySet ()Ljava/util/Set; + public synthetic fun merge (Ljava/lang/Object;Ljava/lang/Object;Ljava/util/function/BiFunction;)Ljava/lang/Object; + public fun merge (Ljava/lang/String;Lapp/revanced/patcher/patch/Option;Ljava/util/function/BiFunction;)Lapp/revanced/patcher/patch/Option; + public synthetic fun put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun put (Ljava/lang/String;Lapp/revanced/patcher/patch/Option;)Lapp/revanced/patcher/patch/Option; + public fun putAll (Ljava/util/Map;)V + public synthetic fun putIfAbsent (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun putIfAbsent (Ljava/lang/String;Lapp/revanced/patcher/patch/Option;)Lapp/revanced/patcher/patch/Option; + public fun remove (Ljava/lang/Object;)Lapp/revanced/patcher/patch/Option; + public synthetic fun remove (Ljava/lang/Object;)Ljava/lang/Object; + public fun remove (Ljava/lang/Object;Ljava/lang/Object;)Z + public synthetic fun replace (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun replace (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z + public fun replace (Ljava/lang/String;Lapp/revanced/patcher/patch/Option;)Lapp/revanced/patcher/patch/Option; + public fun replace (Ljava/lang/String;Lapp/revanced/patcher/patch/Option;Lapp/revanced/patcher/patch/Option;)Z + public fun replaceAll (Ljava/util/function/BiFunction;)V + public final fun set (Ljava/lang/String;Ljava/lang/Object;)V + public final fun size ()I + public final fun values ()Ljava/util/Collection; +} + +public abstract class app/revanced/patcher/patch/Patch { + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZLjava/util/Set;Ljava/util/Set;Ljava/util/Set;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun execute (Lapp/revanced/patcher/patch/PatchContext;)V + public final fun finalize (Lapp/revanced/patcher/patch/PatchContext;)V + public final fun getCompatiblePackages ()Ljava/util/Set; + public final fun getDependencies ()Ljava/util/Set; + public final fun getDescription ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getOptions ()Lapp/revanced/patcher/patch/Options; + public final fun getUse ()Z + public fun toString ()Ljava/lang/String; +} + +public abstract class app/revanced/patcher/patch/PatchBuilder { + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun compatibleWith ([Ljava/lang/String;)V + public final fun compatibleWith ([Lkotlin/Pair;)V + public final fun dependsOn ([Lapp/revanced/patcher/patch/Patch;)V + public final fun execute (Lkotlin/jvm/functions/Function1;)V + public final fun finalize (Lkotlin/jvm/functions/Function1;)V + protected final fun getCompatiblePackages ()Ljava/util/Set; + protected final fun getDependencies ()Ljava/util/Set; + protected final fun getDescription ()Ljava/lang/String; + protected final fun getExecutionBlock ()Lkotlin/jvm/functions/Function1; + protected final fun getFinalizeBlock ()Lkotlin/jvm/functions/Function1; + protected final fun getName ()Ljava/lang/String; + protected final fun getOptions ()Ljava/util/Set; + protected final fun getUse ()Z + public final fun invoke (Lapp/revanced/patcher/patch/Option;)Lapp/revanced/patcher/patch/Option; + public final fun invoke (Ljava/lang/String;[Ljava/lang/String;)Lkotlin/Pair; + protected final fun setCompatiblePackages (Ljava/util/Set;)V + protected final fun setDependencies (Ljava/util/Set;)V + protected final fun setExecutionBlock (Lkotlin/jvm/functions/Function1;)V + protected final fun setFinalizeBlock (Lkotlin/jvm/functions/Function1;)V +} + +public abstract interface class app/revanced/patcher/patch/PatchContext : java/util/function/Supplier { +} + +public final class app/revanced/patcher/patch/PatchException : java/lang/Exception { + public fun (Ljava/lang/String;)V + public fun (Ljava/lang/String;Ljava/lang/Throwable;)V + public fun (Ljava/lang/Throwable;)V +} + +public final class app/revanced/patcher/patch/PatchKt { + public static final fun bytecodePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch; + public static synthetic fun bytecodePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch; + public static final fun gettingBytecodePatch (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun gettingBytecodePatch$default (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun gettingRawResourcePatch (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun gettingRawResourcePatch$default (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun gettingResourcePatch (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun gettingResourcePatch$default (Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun rawResourcePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/RawResourcePatch; + public static synthetic fun rawResourcePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/RawResourcePatch; + public static final fun resourcePatch (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/ResourcePatch; + public static synthetic fun resourcePatch$default (Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/ResourcePatch; +} + +public final class app/revanced/patcher/patch/PatchResult { + public final fun getException ()Lapp/revanced/patcher/patch/PatchException; + public final fun getPatch ()Lapp/revanced/patcher/patch/Patch; +} + +public final class app/revanced/patcher/patch/Patch_jvmKt { + public static final fun isPatch (Ljava/lang/Class;)Z + public static final fun loadPatches (Ljava/util/Set;)Lapp/revanced/patcher/patch/Patches; +} + +public final class app/revanced/patcher/patch/Patches : java/util/Set, kotlin/jvm/internal/markers/KMappedMarker { + public fun add (Lapp/revanced/patcher/patch/Patch;)Z + public synthetic fun add (Ljava/lang/Object;)Z + public fun addAll (Ljava/util/Collection;)Z + public fun clear ()V + public fun contains (Lapp/revanced/patcher/patch/Patch;)Z + public final fun contains (Ljava/lang/Object;)Z + public fun containsAll (Ljava/util/Collection;)Z + public final fun getPatchesByFile ()Ljava/util/Map; + public fun getSize ()I + public fun isEmpty ()Z + public fun iterator ()Ljava/util/Iterator; + public fun remove (Ljava/lang/Object;)Z + public fun removeAll (Ljava/util/Collection;)Z + public fun retainAll (Ljava/util/Collection;)Z + public final fun size ()I + public fun toArray ()[Ljava/lang/Object; + public fun toArray ([Ljava/lang/Object;)[Ljava/lang/Object; +} + +public final class app/revanced/patcher/patch/RawResourcePatch : app/revanced/patcher/patch/Patch { + public fun toString ()Ljava/lang/String; +} + +public final class app/revanced/patcher/patch/RawResourcePatchBuilder : app/revanced/patcher/patch/PatchBuilder { + public synthetic fun build$core ()Lapp/revanced/patcher/patch/Patch; +} + +public final class app/revanced/patcher/patch/ResourcePatch : app/revanced/patcher/patch/Patch { + public fun toString ()Ljava/lang/String; +} + +public final class app/revanced/patcher/patch/ResourcePatchBuilder : app/revanced/patcher/patch/PatchBuilder { + public synthetic fun build$core ()Lapp/revanced/patcher/patch/Patch; +} + +public final class app/revanced/patcher/patch/ResourcePatchContext : app/revanced/patcher/patch/PatchContext { + public final fun delete (Ljava/lang/String;)Z + public final fun document (Ljava/io/InputStream;)Lapp/revanced/patcher/util/Document; + public final fun document (Ljava/lang/String;)Lapp/revanced/patcher/util/Document; + public fun get ()Lapp/revanced/patcher/PatcherResult$PatchedResources; + public synthetic fun get ()Ljava/lang/Object; + public final fun get (Ljava/lang/String;Z)Ljava/io/File; + public static synthetic fun get$default (Lapp/revanced/patcher/patch/ResourcePatchContext;Ljava/lang/String;ZILjava/lang/Object;)Ljava/io/File; +} + +public final class app/revanced/patcher/util/Document : java/io/Closeable, org/w3c/dom/Document { + public fun adoptNode (Lorg/w3c/dom/Node;)Lorg/w3c/dom/Node; + public fun appendChild (Lorg/w3c/dom/Node;)Lorg/w3c/dom/Node; + public fun cloneNode (Z)Lorg/w3c/dom/Node; + public fun close ()V + public fun compareDocumentPosition (Lorg/w3c/dom/Node;)S + public fun createAttribute (Ljava/lang/String;)Lorg/w3c/dom/Attr; + public fun createAttributeNS (Ljava/lang/String;Ljava/lang/String;)Lorg/w3c/dom/Attr; + public fun createCDATASection (Ljava/lang/String;)Lorg/w3c/dom/CDATASection; + public fun createComment (Ljava/lang/String;)Lorg/w3c/dom/Comment; + public fun createDocumentFragment ()Lorg/w3c/dom/DocumentFragment; + public fun createElement (Ljava/lang/String;)Lorg/w3c/dom/Element; + public fun createElementNS (Ljava/lang/String;Ljava/lang/String;)Lorg/w3c/dom/Element; + public fun createEntityReference (Ljava/lang/String;)Lorg/w3c/dom/EntityReference; + public fun createProcessingInstruction (Ljava/lang/String;Ljava/lang/String;)Lorg/w3c/dom/ProcessingInstruction; + public fun createTextNode (Ljava/lang/String;)Lorg/w3c/dom/Text; + public fun getAttributes ()Lorg/w3c/dom/NamedNodeMap; + public fun getBaseURI ()Ljava/lang/String; + public fun getChildNodes ()Lorg/w3c/dom/NodeList; + public fun getDoctype ()Lorg/w3c/dom/DocumentType; + public fun getDocumentElement ()Lorg/w3c/dom/Element; + public fun getDocumentURI ()Ljava/lang/String; + public fun getDomConfig ()Lorg/w3c/dom/DOMConfiguration; + public fun getElementById (Ljava/lang/String;)Lorg/w3c/dom/Element; + public fun getElementsByTagName (Ljava/lang/String;)Lorg/w3c/dom/NodeList; + public fun getElementsByTagNameNS (Ljava/lang/String;Ljava/lang/String;)Lorg/w3c/dom/NodeList; + public fun getFeature (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; + public fun getFirstChild ()Lorg/w3c/dom/Node; + public fun getImplementation ()Lorg/w3c/dom/DOMImplementation; + public fun getInputEncoding ()Ljava/lang/String; + public fun getLastChild ()Lorg/w3c/dom/Node; + public fun getLocalName ()Ljava/lang/String; + public fun getNamespaceURI ()Ljava/lang/String; + public fun getNextSibling ()Lorg/w3c/dom/Node; + public fun getNodeName ()Ljava/lang/String; + public fun getNodeType ()S + public fun getNodeValue ()Ljava/lang/String; + public fun getOwnerDocument ()Lorg/w3c/dom/Document; + public fun getParentNode ()Lorg/w3c/dom/Node; + public fun getPrefix ()Ljava/lang/String; + public fun getPreviousSibling ()Lorg/w3c/dom/Node; + public fun getStrictErrorChecking ()Z + public fun getTextContent ()Ljava/lang/String; + public fun getUserData (Ljava/lang/String;)Ljava/lang/Object; + public fun getXmlEncoding ()Ljava/lang/String; + public fun getXmlStandalone ()Z + public fun getXmlVersion ()Ljava/lang/String; + public fun hasAttributes ()Z + public fun hasChildNodes ()Z + public fun importNode (Lorg/w3c/dom/Node;Z)Lorg/w3c/dom/Node; + public fun insertBefore (Lorg/w3c/dom/Node;Lorg/w3c/dom/Node;)Lorg/w3c/dom/Node; + public fun isDefaultNamespace (Ljava/lang/String;)Z + public fun isEqualNode (Lorg/w3c/dom/Node;)Z + public fun isSameNode (Lorg/w3c/dom/Node;)Z + public fun isSupported (Ljava/lang/String;Ljava/lang/String;)Z + public fun lookupNamespaceURI (Ljava/lang/String;)Ljava/lang/String; + public fun lookupPrefix (Ljava/lang/String;)Ljava/lang/String; + public fun normalize ()V + public fun normalizeDocument ()V + public fun removeChild (Lorg/w3c/dom/Node;)Lorg/w3c/dom/Node; + public fun renameNode (Lorg/w3c/dom/Node;Ljava/lang/String;Ljava/lang/String;)Lorg/w3c/dom/Node; + public fun replaceChild (Lorg/w3c/dom/Node;Lorg/w3c/dom/Node;)Lorg/w3c/dom/Node; + public fun setDocumentURI (Ljava/lang/String;)V + public fun setNodeValue (Ljava/lang/String;)V + public fun setPrefix (Ljava/lang/String;)V + public fun setStrictErrorChecking (Z)V + public fun setTextContent (Ljava/lang/String;)V + public fun setUserData (Ljava/lang/String;Ljava/lang/Object;Lorg/w3c/dom/UserDataHandler;)Ljava/lang/Object; + public fun setXmlStandalone (Z)V + public fun setXmlVersion (Ljava/lang/String;)V +} + +public final class app/revanced/patcher/util/MethodNavigator { + public final fun getValue (Lapp/revanced/patcher/patch/BytecodePatchContext;Lkotlin/reflect/KProperty;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun original (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/iface/Method; + public final fun stop (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun to (Lapp/revanced/patcher/patch/BytecodePatchContext;ILkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/MethodNavigator; + public final fun to (Lapp/revanced/patcher/patch/BytecodePatchContext;[I)Lapp/revanced/patcher/util/MethodNavigator; + public static synthetic fun to$default (Lapp/revanced/patcher/util/MethodNavigator;Lapp/revanced/patcher/patch/BytecodePatchContext;ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/util/MethodNavigator; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseAnnotationEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/AnnotationEncodedValue;)V + public fun getElements ()Ljava/util/Set; + public fun getType ()Ljava/lang/String; + public final fun setType (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/AnnotationEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseArrayEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)V + public fun getValue ()Ljava/util/List; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseBooleanEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/BooleanEncodedValue;)V + public fun getValue ()Z + public final fun setValue (Z)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/BooleanEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseByteEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)V + public fun getValue ()B + public final fun setValue (B)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseCharEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/CharEncodedValue;)V + public fun getValue ()C + public final fun setValue (C)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/CharEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseDoubleEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/DoubleEncodedValue;)V + public fun getValue ()D + public final fun setValue (D)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/DoubleEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue; +} + +public abstract interface class com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue : com/android/tools/smali/dexlib2/iface/value/EncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue$Companion; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseEnumEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/EnumEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference; + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EnumEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFieldEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/FieldEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference; + public fun getValueType ()I + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/FieldReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FieldEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFloatEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/FloatEncodedValue;)V + public fun getValue ()F + public final fun setValue (F)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FloatEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseIntEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/IntEncodedValue;)V + public fun getValue ()I + public final fun setValue (I)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/IntEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseLongEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/LongEncodedValue;)V + public fun getValue ()J + public final fun setValue (J)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/LongEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference; + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodHandleEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodHandleEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodHandleReference; + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodHandleReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodHandleEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodTypeEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/MethodTypeEncodedValue;)V + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/reference/MethodProtoReference; + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/reference/MethodProtoReference;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodTypeEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseNullEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue$Companion; + public fun ()V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseShortEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/ShortEncodedValue;)V + public fun getValue ()S + public final fun setValue (S)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ShortEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseStringEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/StringEncodedValue;)V + public fun getValue ()Ljava/lang/String; + public final fun setValue (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseTypeEncodedValue, com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue { + public static final field Companion Lcom/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/value/TypeEncodedValue;)V + public fun getValue ()Ljava/lang/String; + public final fun setValue (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/TypeEncodedValue;)Lcom/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableAnnotation : com/android/tools/smali/dexlib2/base/BaseAnnotation { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableAnnotation$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/Annotation;)V + public fun getElements ()Ljava/util/Set; + public fun getType ()Ljava/lang/String; + public fun getVisibility ()I +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableAnnotation$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Annotation;)Lcom/android/tools/smali/dexlib2/mutable/MutableAnnotation; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableAnnotationElement : com/android/tools/smali/dexlib2/base/BaseAnnotationElement { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableAnnotationElement$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/AnnotationElement;)V + public fun getName ()Ljava/lang/String; + public synthetic fun getValue ()Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue; + public fun getValue ()Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue; + public final fun setName (Ljava/lang/String;)V + public final fun setValue (Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue;)V +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableAnnotationElement$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/AnnotationElement;)Lcom/android/tools/smali/dexlib2/mutable/MutableAnnotationElement; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableClassDef : com/android/tools/smali/dexlib2/base/reference/BaseTypeReference, com/android/tools/smali/dexlib2/iface/ClassDef { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)V + public final fun charAt (I)C + public fun get (I)C + public fun getAccessFlags ()I + public fun getAnnotations ()Ljava/util/Set; + public synthetic fun getDirectMethods ()Ljava/lang/Iterable; + public fun getDirectMethods ()Ljava/util/Set; + public synthetic fun getFields ()Ljava/lang/Iterable; + public fun getFields ()Ljava/util/Set; + public synthetic fun getInstanceFields ()Ljava/lang/Iterable; + public fun getInstanceFields ()Ljava/util/Set; + public fun getInterfaces ()Ljava/util/List; + public fun getLength ()I + public synthetic fun getMethods ()Ljava/lang/Iterable; + public fun getMethods ()Ljava/util/Set; + public fun getSourceFile ()Ljava/lang/String; + public synthetic fun getStaticFields ()Ljava/lang/Iterable; + public fun getStaticFields ()Ljava/util/Set; + public fun getSuperclass ()Ljava/lang/String; + public fun getType ()Ljava/lang/String; + public synthetic fun getVirtualMethods ()Ljava/lang/Iterable; + public fun getVirtualMethods ()Ljava/util/Set; + public final fun length ()I + public final fun setAccessFlags (I)V + public final fun setSourceFile (Ljava/lang/String;)V + public final fun setSuperClass (Ljava/lang/String;)V + public final fun setType (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableClassDef$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableField : com/android/tools/smali/dexlib2/base/reference/BaseFieldReference, com/android/tools/smali/dexlib2/iface/Field { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableField$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/Field;)V + public fun getAccessFlags ()I + public fun getAnnotations ()Ljava/util/Set; + public fun getDefiningClass ()Ljava/lang/String; + public fun getHiddenApiRestrictions ()Ljava/util/Set; + public synthetic fun getInitialValue ()Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue; + public fun getInitialValue ()Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue; + public fun getName ()Ljava/lang/String; + public fun getType ()Ljava/lang/String; + public final fun setAccessFlags (I)V + public final fun setDefiningClass (Ljava/lang/String;)V + public final fun setInitialValue (Lcom/android/tools/smali/dexlib2/iface/value/MutableEncodedValue;)V + public final fun setName (Ljava/lang/String;)V + public final fun setType (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableField$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Field;)Lcom/android/tools/smali/dexlib2/mutable/MutableField; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableMethod : com/android/tools/smali/dexlib2/base/reference/BaseMethodReference, com/android/tools/smali/dexlib2/iface/Method { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableMethod$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/Method;)V + public fun getAccessFlags ()I + public fun getAnnotations ()Ljava/util/Set; + public fun getDefiningClass ()Ljava/lang/String; + public fun getHiddenApiRestrictions ()Ljava/util/Set; + public fun getImplementation ()Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation; + public synthetic fun getImplementation ()Lcom/android/tools/smali/dexlib2/iface/MethodImplementation; + public fun getName ()Ljava/lang/String; + public fun getParameterTypes ()Ljava/util/List; + public fun getParameters ()Ljava/util/List; + public fun getReturnType ()Ljava/lang/String; + public final fun setAccessFlags (I)V + public final fun setDefiningClass (Ljava/lang/String;)V + public final fun setName (Ljava/lang/String;)V + public final fun setReturnType (Ljava/lang/String;)V +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableMethod$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Method;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableMethodParameter : com/android/tools/smali/dexlib2/base/BaseMethodParameter, com/android/tools/smali/dexlib2/iface/MethodParameter { + public static final field Companion Lcom/android/tools/smali/dexlib2/mutable/MutableMethodParameter$Companion; + public fun (Lcom/android/tools/smali/dexlib2/iface/MethodParameter;)V + public final fun charAt (I)C + public fun get (I)C + public fun getAnnotations ()Ljava/util/Set; + public fun getLength ()I + public fun getName ()Ljava/lang/String; + public fun getSignature ()Ljava/lang/String; + public fun getType ()Ljava/lang/String; + public final fun length ()I +} + +public final class com/android/tools/smali/dexlib2/mutable/MutableMethodParameter$Companion { + public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/MethodParameter;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethodParameter; +} + diff --git a/core/build.gradle.kts b/core/build.gradle.kts new file mode 100644 index 0000000..1186b90 --- /dev/null +++ b/core/build.gradle.kts @@ -0,0 +1,109 @@ +import com.android.build.api.dsl.androidLibrary +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation + +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.android.kotlin.multiplatform.library) + alias(libs.plugins.vanniktech.mavenPublish) +} + +group = "app.revanced" + +kotlin { + @OptIn(ExperimentalAbiValidation::class) + abiValidation { + enabled = true + } + + jvm() + androidLibrary { + namespace = "app.revanced.patcher" + compileSdk = libs.versions.android.compileSdk.get().toInt() + minSdk = libs.versions.android.minSdk.get().toInt() + + withHostTestBuilder {}.configure {} + withDeviceTestBuilder { + sourceSetTreeName = "test" + } + + compilations.configureEach { + compilerOptions.configure { + jvmTarget.set( + JvmTarget.JVM_11 + ) + } + } + } + sourceSets { + commonMain.dependencies { + implementation(libs.apktool.lib) + implementation(libs.kotlin.reflect) + implementation(libs.kotlinx.coroutines.core) + implementation(libs.multidexlib2) + implementation(libs.smali) + implementation(libs.xpp3) + } + + jvmTest.dependencies { + implementation(libs.mockk) + implementation(libs.kotlin.test) + } + } + compilerOptions { + freeCompilerArgs = listOf("-Xcontext-parameters") + } +} + +tasks { + named("jvmProcessResources") { + expand("projectVersion" to project.version) + } + + named("jvmTest") { + useJUnitPlatform() + } +} + +mavenPublishing { + publishing { + repositories { + maven { + name = "githubPackages" + url = uri("https://maven.pkg.github.com/revanced/revanced-patcher") + credentials(PasswordCredentials::class) + } + } + } + + signAllPublications() + extensions.getByType().useGpgCmd() + + coordinates(group.toString(), project.name, version.toString()) + + pom { + name = "ReVanced Patcher" + description = "Patcher used by ReVanced." + inceptionYear = "2022" + url = "https://revanced.app" + licenses { + license { + name = "GNU General Public License v3.0" + url = "https://www.gnu.org/licenses/gpl-3.0.en.html" + } + } + developers { + developer { + id = "ReVanced" + name = "ReVanced" + email = "contact@revanced.app" + } + } + scm { + connection = "scm:git:git://github.com/revanced/revanced-patcher.git" + developerConnection = "scm:git:git@github.com:revanced/revanced-patcher.git" + url = "https://github.com/revanced/revanced-patcher" + } + } +} + diff --git a/core/src/androidMain/kotlin/app/revanced/patcher/patch/Patch.android.kt b/core/src/androidMain/kotlin/app/revanced/patcher/patch/Patch.android.kt new file mode 100644 index 0000000..f3ee873 --- /dev/null +++ b/core/src/androidMain/kotlin/app/revanced/patcher/patch/Patch.android.kt @@ -0,0 +1,32 @@ +package app.revanced.patcher.patch + +import dalvik.system.DexClassLoader +import lanchon.multidexlib2.BasicDexFileNamer +import lanchon.multidexlib2.MultiDexIO +import java.io.File + +actual val Class<*>.isPatch get() = Patch::class.java.isAssignableFrom(this) + +/** + * Loads patches from DEX files declared as public static fields + * or returned by public static and non-parametrized methods. + * Patches with no name are not loaded. + * + * @param patchesFiles The DEX files to load the patches from. + * + * @return The loaded patches. + */ +actual fun loadPatches(patchesFiles: Set) = loadPatches( + patchesFiles, + { patchBundle -> + MultiDexIO.readDexFile(true, patchBundle, BasicDexFileNamer(), null, null).classes + .map { classDef -> + classDef.type.substring(1, classDef.length - 1) + } + }, + DexClassLoader( + patchesFiles.joinToString(File.pathSeparator) { it.absolutePath }, + null, + null, null + ) +) diff --git a/core/src/androidMain/kotlin/collections/MutableMap.android.kt b/core/src/androidMain/kotlin/collections/MutableMap.android.kt new file mode 100644 index 0000000..8ff5cb0 --- /dev/null +++ b/core/src/androidMain/kotlin/collections/MutableMap.android.kt @@ -0,0 +1,7 @@ +package collections + +actual fun MutableMap.kmpMerge( + key: K, + value: V, + remappingFunction: (oldValue: V, newValue: V) -> V +) = merge(key, value, remappingFunction) \ No newline at end of file diff --git a/core/src/androidMain/kotlin/java/io/File.android.kt b/core/src/androidMain/kotlin/java/io/File.android.kt new file mode 100644 index 0000000..9f4d938 --- /dev/null +++ b/core/src/androidMain/kotlin/java/io/File.android.kt @@ -0,0 +1,8 @@ +package java.io + +import java.nio.charset.Charset + +internal actual fun File.kmpResolve(child: String) = resolve(child) +internal actual fun File.kmpDeleteRecursively() = deleteRecursively() +internal actual fun File.kmpInputStream() = inputStream() +internal actual fun File.kmpBufferedWriter(charset: Charset) = bufferedWriter(charset) \ No newline at end of file diff --git a/core/src/commonMain/kotlin/app/revanced/patcher/Fingerprint.kt b/core/src/commonMain/kotlin/app/revanced/patcher/Fingerprint.kt new file mode 100644 index 0000000..ad46187 --- /dev/null +++ b/core/src/commonMain/kotlin/app/revanced/patcher/Fingerprint.kt @@ -0,0 +1,598 @@ +@file:Suppress("unused", "MemberVisibilityCanBePrivate") + +package app.revanced.patcher + +import app.revanced.patcher.extensions.instructionsOrNull +import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.patch.PatchException +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.ClassDef +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.StringReference +import com.android.tools.smali.dexlib2.util.MethodUtil + +/** + * A fingerprint for a method. A fingerprint is a partial description of a method. + * It is used to uniquely match a method by its characteristics. + * + * An example fingerprint for a public method that takes a single string parameter and returns void: + * ``` + * fingerprint { + * accessFlags(AccessFlags.PUBLIC) + * returns("V") + * parameters("Ljava/lang/String;") + * } + * ``` + * + * @param accessFlags The exact access flags using values of [AccessFlags]. + * @param returnType The return type. Compared using [String.startsWith]. + * @param parameters The parameters. Partial matches allowed and follow the same rules as [returnType]. + * @param opcodes A pattern of instruction opcodes. `null` can be used as a wildcard. + * @param strings A list of the strings. Compared using [String.contains]. + * @param custom A custom condition for this fingerprint. + * @param fuzzyPatternScanThreshold The threshold for fuzzy scanning the [opcodes] pattern. + */ +class Fingerprint internal constructor( + internal val accessFlags: Int?, + internal val returnType: String?, + internal val parameters: List?, + internal val opcodes: List?, + internal val strings: List?, + internal val custom: ((method: Method, classDef: ClassDef) -> Boolean)?, + private val fuzzyPatternScanThreshold: Int, +) { + @Suppress("ktlint:standard:backing-property-naming") + // Backing field needed for lazy initialization. + private var _matchOrNull: Match? = null + + /** + * The match for this [Fingerprint]. Null if unmatched. + */ + context(_: BytecodePatchContext) + private val matchOrNull: Match? + get() = matchOrNull() + + /** + * Match using [BytecodePatchContext.lookupMaps]. + * + * Generally faster than the other [matchOrNull] overloads when there are many methods to check for a match. + * + * Fingerprints can be optimized for performance: + * - Slowest: Specify [custom] or [opcodes] and nothing else. + * - Fast: Specify [accessFlags], [returnType]. + * - Faster: Specify [accessFlags], [returnType] and [parameters]. + * - Fastest: Specify [strings], with at least one string being an exact (non-partial) match. + * + * @return The [Match] if a match was found or if the fingerprint is already matched to a method, null otherwise. + */ + context(context: BytecodePatchContext) + internal fun matchOrNull(): Match? { + if (_matchOrNull != null) return _matchOrNull + + var match = strings?.mapNotNull { + context.classDefs.methodsByString[it] + }?.minByOrNull { it.size }?.let { methodClasses -> + methodClasses.forEach { method -> + val match = matchOrNull(method, context.classDefs[method.definingClass]!!) + if (match != null) return@let match + } + + null + } + if (match != null) return match + context.classDefs.forEach { classDef -> + match = matchOrNull(classDef) + if (match != null) return match + } + + return null + } + + /** + * Match using a [ClassDef]. + * + * @param classDef The class to match against. + * @return The [Match] if a match was found or if the fingerprint is already matched to a method, null otherwise. + */ + context(_: BytecodePatchContext) + fun matchOrNull( + classDef: ClassDef, + ): Match? { + if (_matchOrNull != null) return _matchOrNull + + for (method in classDef.methods) { + val match = matchOrNull(method, classDef) + if (match != null) return match + } + + return null + } + + /** + * Match using a [Method]. + * The class is retrieved from the method. + * + * @param method The method to match against. + * @return The [Match] if a match was found or if the fingerprint is already matched to a method, null otherwise. + */ + context(context: BytecodePatchContext) + fun matchOrNull( + method: Method, + ) = matchOrNull(method, context.classDefs[method.definingClass]!!) + + /** + * Match using a [Method]. + * + * @param method The method to match against. + * @param classDef The class the method is a member of. + * @return The [Match] if a match was found or if the fingerprint is already matched to a method, null otherwise. + */ + context(context: BytecodePatchContext) + fun matchOrNull( + method: Method, + classDef: ClassDef, + ): Match? { + if (_matchOrNull != null) return _matchOrNull + + if (returnType != null && !method.returnType.startsWith(returnType)) { + return null + } + + if (accessFlags != null && accessFlags != method.accessFlags) { + return null + } + + fun parametersEqual( + parameters1: Iterable, + parameters2: Iterable, + ): Boolean { + if (parameters1.count() != parameters2.count()) return false + val iterator1 = parameters1.iterator() + parameters2.forEach { + if (!it.startsWith(iterator1.next())) return false + } + return true + } + + // TODO: parseParameters() + if (parameters != null && !parametersEqual(parameters, method.parameterTypes)) { + return null + } + + if (custom != null && !custom.invoke(method, classDef)) { + return null + } + + val stringMatches: List? = + if (strings != null) { + buildList { + val instructions = method.instructionsOrNull ?: return null + + val stringsList = strings.toMutableList() + + instructions.forEachIndexed { instructionIndex, instruction -> + if ( + instruction.opcode != Opcode.CONST_STRING && + instruction.opcode != Opcode.CONST_STRING_JUMBO + ) { + return@forEachIndexed + } + + val string = ((instruction as ReferenceInstruction).reference as StringReference).string + val index = stringsList.indexOfFirst(string::contains) + if (index == -1) return@forEachIndexed + + add(Match.StringMatch(string, instructionIndex)) + stringsList.removeAt(index) + } + + if (stringsList.isNotEmpty()) return null + } + } else { + null + } + + val patternMatch = if (opcodes != null) { + val instructions = method.instructionsOrNull ?: return null + + fun patternScan(): Match.PatternMatch? { + val fingerprintFuzzyPatternScanThreshold = fuzzyPatternScanThreshold + + val instructionLength = instructions.count() + val patternLength = opcodes.size + + for (index in 0 until instructionLength) { + var patternIndex = 0 + var threshold = fingerprintFuzzyPatternScanThreshold + + while (index + patternIndex < instructionLength) { + val originalOpcode = instructions.elementAt(index + patternIndex).opcode + val patternOpcode = opcodes.elementAt(patternIndex) + + if (patternOpcode != null && patternOpcode.ordinal != originalOpcode.ordinal) { + // Reaching maximum threshold (0) means, + // the pattern does not match to the current instructions. + if (threshold-- == 0) break + } + + if (patternIndex < patternLength - 1) { + // If the entire pattern has not been scanned yet, continue the scan. + patternIndex++ + continue + } + + // The entire pattern has been scanned. + return Match.PatternMatch( + index, + index + patternIndex, + ) + } + } + + return null + } + + patternScan() ?: return null + } else { + null + } + + _matchOrNull = Match( + context, + classDef, + method, + patternMatch, + stringMatches, + ) + + return _matchOrNull + } + + private val exception get() = PatchException("Failed to match the fingerprint: $this") + + /** + * The match for this [Fingerprint]. + * + * @throws PatchException If the [Fingerprint] has not been matched. + */ + context(_: BytecodePatchContext) + private val match + get() = matchOrNull ?: throw exception + + /** + * Match using a [ClassDef]. + * + * @param classDef The class to match against. + * @return The [Match] if a match was found or if the fingerprint is already matched to a method, null otherwise. + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + fun match( + classDef: ClassDef, + ) = matchOrNull(classDef) ?: throw exception + + /** + * Match using a [Method]. + * The class is retrieved from the method. + * + * @param method The method to match against. + * @return The [Match] if a match was found or if the fingerprint is already matched to a method, null otherwise. + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + fun match( + method: Method, + ) = matchOrNull(method) ?: throw exception + + /** + * Match using a [Method]. + * + * @param method The method to match against. + * @param classDef The class the method is a member of. + * @return The [Match] if a match was found or if the fingerprint is already matched to a method, null otherwise. + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + fun match( + method: Method, + classDef: ClassDef, + ) = matchOrNull(method, classDef) ?: throw exception + + /** + * The class the matching method is a member of. + */ + context(_: BytecodePatchContext) + val originalClassDefOrNull + get() = matchOrNull?.originalClassDef + + /** + * The matching method. + */ + context(_: BytecodePatchContext) + val originalMethodOrNull + get() = matchOrNull?.originalMethod + + /** + * The mutable version of [originalClassDefOrNull]. + * + * Accessing this property allocates a [ClassProxy]. + * Use [originalClassDefOrNull] if mutable access is not required. + */ + context(_: BytecodePatchContext) + val classDefOrNull + get() = matchOrNull?.classDef + + /** + * The mutable version of [originalMethodOrNull]. + * + * Accessing this property allocates a [ClassProxy]. + * Use [originalMethodOrNull] if mutable access is not required. + */ + context(_: BytecodePatchContext) + val methodOrNull + get() = matchOrNull?.method + + /** + * The match for the opcode pattern. + */ + context(_: BytecodePatchContext) + val patternMatchOrNull + get() = matchOrNull?.patternMatch + + /** + * The matches for the strings. + */ + context(_: BytecodePatchContext) + val stringMatchesOrNull + get() = matchOrNull?.stringMatches + + /** + * The class the matching method is a member of. + * + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + val originalClassDef + get() = match.originalClassDef + + /** + * The matching method. + * + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + val originalMethod + get() = match.originalMethod + + /** + * The mutable version of [originalClassDef]. + * + * Accessing this property allocates a [ClassProxy]. + * Use [originalClassDef] if mutable access is not required. + * + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + val classDef + get() = match.classDef + + /** + * The mutable version of [originalMethod]. + * + * Accessing this property allocates a [ClassProxy]. + * Use [originalMethod] if mutable access is not required. + * + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + val method + get() = match.method + + /** + * The match for the opcode pattern. + * + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + val patternMatch + get() = match.patternMatch + + /** + * The matches for the strings. + * + * @throws PatchException If the fingerprint has not been matched. + */ + context(_: BytecodePatchContext) + val stringMatches + get() = match.stringMatches +} + +/** + * A match of a [Fingerprint]. + * + * @param originalClassDef The class the matching method is a member of. + * @param originalMethod The matching method. + * @param patternMatch The match for the opcode pattern. + * @param stringMatches The matches for the strings. + */ +class Match internal constructor( + val context: BytecodePatchContext, + val originalClassDef: ClassDef, + val originalMethod: Method, + val patternMatch: PatternMatch?, + val stringMatches: List?, +) { + /** + * The mutable version of [originalClassDef]. + * + * Accessing this property allocates a new mutable instance. + * Use [originalClassDef] if mutable access is not required. + */ + val classDef by lazy { context.firstClassDefMutable(originalClassDef.type) } + + /** + * The mutable version of [originalMethod]. + * + * Accessing this property allocates a new mutable instance. + * Use [originalMethod] if mutable access is not required. + */ + val method by lazy { classDef.methods.first { MethodUtil.methodSignaturesMatch(it, originalMethod) } } + + /** + * A match for an opcode pattern. + * @param startIndex The index of the first opcode of the pattern in the method. + * @param endIndex The index of the last opcode of the pattern in the method. + */ + class PatternMatch internal constructor( + val startIndex: Int, + val endIndex: Int, + ) + + /** + * A match for a string. + * + * @param string The string that matched. + * @param index The index of the instruction in the method. + */ + class StringMatch internal constructor(val string: String, val index: Int) +} + +/** + * A builder for [Fingerprint]. + * + * @property accessFlags The exact access flags using values of [AccessFlags]. + * @property returnType The return type compared using [String.startsWith]. + * @property parameters The parameters of the method. Partial matches allowed and follow the same rules as [returnType]. + * @property opcodes An opcode pattern of the instructions. Wildcard or unknown opcodes can be specified by `null`. + * @property strings A list of the strings compared each using [String.contains]. + * @property customBlock A custom condition for this fingerprint. + * @property fuzzyPatternScanThreshold The threshold for fuzzy pattern scanning. + * + * @constructor Create a new [FingerprintBuilder]. + */ +class FingerprintBuilder internal constructor( + private val fuzzyPatternScanThreshold: Int = 0, +) { + private var accessFlags: Int? = null + private var returnType: String? = null + private var parameters: List? = null + private var opcodes: List? = null + private var strings: List? = null + private var customBlock: ((method: Method, classDef: ClassDef) -> Boolean)? = null + + /** + * Set the access flags. + * + * @param accessFlags The exact access flags using values of [AccessFlags]. + */ + fun accessFlags(accessFlags: Int) { + this.accessFlags = accessFlags + } + + /** + * Set the access flags. + * + * @param accessFlags The exact access flags using values of [AccessFlags]. + */ + fun accessFlags(vararg accessFlags: AccessFlags) { + this.accessFlags = accessFlags.fold(0) { acc, it -> acc or it.value } + } + + /** + * Set the return type. + * + * @param returnType The return type compared using [String.startsWith]. + */ + fun returns(returnType: String) { + this.returnType = returnType + } + + /** + * Set the parameters. + * + * @param parameters The parameters of the method. Partial matches allowed and follow the same rules as [returnType]. + */ + fun parameters(vararg parameters: String) { + this.parameters = parameters.toList() + } + + /** + * Set the opcodes. + * + * @param opcodes An opcode pattern of instructions. + * Wildcard or unknown opcodes can be specified by `null`. + */ + fun opcodes(vararg opcodes: Opcode?) { + this.opcodes = opcodes.toList() + } + + /** + * Set the opcodes. + * + * @param instructions A list of instructions or opcode names in SMALI format. + * - Wildcard or unknown opcodes can be specified by `null`. + * - Empty lines are ignored. + * - Each instruction must be on a new line. + * - The opcode name is enough, no need to specify the operands. + * + * @throws Exception If an unknown opcode is used. + */ + fun opcodes(instructions: String) { + this.opcodes = instructions.trimIndent().split("\n").filter { + it.isNotBlank() + }.map { + // Remove any operands. + val name = it.split(" ", limit = 1).first().trim() + if (name == "null") return@map null + + opcodesByName[name] ?: throw Exception("Unknown opcode: $name") + } + } + + /** + * Set the strings. + * + * @param strings A list of strings compared each using [String.contains]. + */ + fun strings(vararg strings: String) { + this.strings = strings.toList() + } + + /** + * Set a custom condition for this fingerprint. + * + * @param customBlock A custom condition for this fingerprint. + */ + fun custom(customBlock: (method: Method, classDef: ClassDef) -> Boolean) { + this.customBlock = customBlock + } + + internal fun build() = Fingerprint( + accessFlags, + returnType, + parameters, + opcodes, + strings, + customBlock, + fuzzyPatternScanThreshold, + ) + + private companion object { + val opcodesByName = Opcode.entries.associateBy { it.name } + } +} + +/** + * Create a [Fingerprint]. + * + * @param fuzzyPatternScanThreshold The threshold for fuzzy pattern scanning. Default is 0. + * @param block The block to build the [Fingerprint]. + * + * @return The created [Fingerprint]. + */ +fun fingerprint( + fuzzyPatternScanThreshold: Int = 0, + block: FingerprintBuilder.() -> Unit, +) = FingerprintBuilder(fuzzyPatternScanThreshold).apply(block).build() diff --git a/src/main/kotlin/app/revanced/patcher/InternalApi.kt b/core/src/commonMain/kotlin/app/revanced/patcher/InternalApi.kt similarity index 100% rename from src/main/kotlin/app/revanced/patcher/InternalApi.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/InternalApi.kt diff --git a/core/src/commonMain/kotlin/app/revanced/patcher/Matching.kt b/core/src/commonMain/kotlin/app/revanced/patcher/Matching.kt new file mode 100644 index 0000000..69decf5 --- /dev/null +++ b/core/src/commonMain/kotlin/app/revanced/patcher/Matching.kt @@ -0,0 +1,814 @@ +@file:Suppress("unused", "MemberVisibilityCanBePrivate", "CONTEXT_RECEIVERS_DEPRECATED") + +package app.revanced.patcher + +import app.revanced.patcher.extensions.* +import app.revanced.patcher.patch.BytecodePatchContext +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.HiddenApiRestriction +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.* +import com.android.tools.smali.dexlib2.iface.Annotation +import com.android.tools.smali.dexlib2.iface.instruction.* +import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22t +import com.android.tools.smali.dexlib2.util.MethodUtil +import com.sun.jdi.StringReference +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty + +fun Iterable.anyClassDef(predicate: ClassDef.() -> Boolean) = any(predicate) + +fun ClassDef.anyMethod(predicate: Method.() -> Boolean) = methods.any(predicate) + +fun ClassDef.anyDirectMethod(predicate: Method.() -> Boolean) = directMethods.any(predicate) + +fun ClassDef.anyVirtualMethod(predicate: Method.() -> Boolean) = virtualMethods.any(predicate) + +fun ClassDef.anyField(predicate: Field.() -> Boolean) = fields.any(predicate) + +fun ClassDef.anyInstanceField(predicate: Field.() -> Boolean) = instanceFields.any(predicate) + +fun ClassDef.anyStaticField(predicate: Field.() -> Boolean) = staticFields.any(predicate) + +fun ClassDef.anyInterface(predicate: String.() -> Boolean) = interfaces.any(predicate) + +fun ClassDef.anyAnnotation(predicate: Annotation.() -> Boolean) = annotations.any(predicate) + +fun Method.implementation(predicate: MethodImplementation.() -> Boolean) = implementation?.predicate() ?: false + +fun Method.anyParameter(predicate: MethodParameter.() -> Boolean) = parameters.any(predicate) + +fun Method.anyParameterType(predicate: CharSequence.() -> Boolean) = parameterTypes.any(predicate) + +fun Method.anyAnnotation(predicate: Annotation.() -> Boolean) = annotations.any(predicate) + +fun Method.anyHiddenApiRestriction(predicate: HiddenApiRestriction.() -> Boolean) = hiddenApiRestrictions.any(predicate) + +fun MethodImplementation.anyInstruction(predicate: Instruction.() -> Boolean) = instructions.any(predicate) + +fun MethodImplementation.anyTryBlock(predicate: TryBlock.() -> Boolean) = tryBlocks.any(predicate) + +fun MethodImplementation.anyDebugItem(predicate: Any.() -> Boolean) = debugItems.any(predicate) + +fun Iterable.anyInstruction(predicate: Instruction.() -> Boolean) = any(predicate) + +fun BytecodePatchContext.firstClassDefOrNull(predicate: context(PredicateContext) ClassDef.() -> Boolean) = + with(PredicateContext()) { classDefs.firstOrNull { it.predicate() } } + +fun BytecodePatchContext.firstClassDef(predicate: context(PredicateContext) ClassDef.() -> Boolean) = + requireNotNull(firstClassDefOrNull(predicate)) + +fun BytecodePatchContext.firstClassDefMutableOrNull(predicate: context(PredicateContext) ClassDef.() -> Boolean) = + firstClassDefOrNull(predicate)?.let { classDefs.getOrReplaceMutable(it) } + +fun BytecodePatchContext.firstClassDefMutable(predicate: context(PredicateContext) ClassDef.() -> Boolean) = + requireNotNull(firstClassDefMutableOrNull(predicate)) + +fun BytecodePatchContext.firstClassDefOrNull( + type: String, predicate: (context(PredicateContext) ClassDef.() -> Boolean)? = null +) = classDefs[type]?.takeIf { + predicate == null || with(PredicateContext()) { it.predicate() } +} + +fun BytecodePatchContext.firstClassDef( + type: String, + predicate: (context(PredicateContext) ClassDef.() -> Boolean)? = null +) = requireNotNull(firstClassDefOrNull(type, predicate)) + +fun BytecodePatchContext.firstClassDefMutableOrNull( + type: String, + predicate: (context(PredicateContext) ClassDef.() -> Boolean)? = null +) = firstClassDefOrNull(type, predicate)?.let { classDefs.getOrReplaceMutable(it) } + +fun BytecodePatchContext.firstClassDefMutable( + type: String, + predicate: (context(PredicateContext) ClassDef.() -> Boolean)? = null +) = requireNotNull(firstClassDefMutableOrNull(type, predicate)) + +fun BytecodePatchContext.firstMethodOrNull(predicate: context(PredicateContext) Method.() -> Boolean): Method? { + val methods = classDefs.asSequence().flatMap { it.methods.asSequence() } + with(PredicateContext()) { + return methods.firstOrNull { it.predicate() } + } +} + +fun BytecodePatchContext.firstMethod(predicate: context(PredicateContext) Method.() -> Boolean) = + requireNotNull(firstMethodOrNull(predicate)) + +fun BytecodePatchContext.firstMethodMutableOrNull(predicate: context(PredicateContext) Method.() -> Boolean) = + firstMethodOrNull(predicate)?.let { method -> + firstClassDefMutable(method.definingClass).methods.first { + MethodUtil.methodSignaturesMatch(method, it) + } + } + +fun BytecodePatchContext.firstMethodMutable(predicate: context(PredicateContext) Method.() -> Boolean) = + requireNotNull(firstMethodMutableOrNull(predicate)) + +fun BytecodePatchContext.firstMethodOrNull( + vararg strings: String, + predicate: context(PredicateContext) Method.() -> Boolean = { true }, +) = with(PredicateContext()) { + val methodsWithStrings = strings.mapNotNull { classDefs.methodsByString[it] } + if (methodsWithStrings.size != strings.size) return null + + methodsWithStrings.minBy { it.size }.firstOrNull { method -> + val containsAllOtherStrings = methodsWithStrings.all { method in it } + containsAllOtherStrings && method.predicate() + } +} + +fun BytecodePatchContext.firstMethod( + vararg strings: String, + predicate: context(PredicateContext) Method.() -> Boolean = { true }, +) = requireNotNull(firstMethodOrNull(*strings, predicate = predicate)) + +fun BytecodePatchContext.firstMethodMutableOrNull( + vararg strings: String, + predicate: context(PredicateContext) Method.() -> Boolean = { true }, +) = firstMethodOrNull(*strings, predicate = predicate)?.let { method -> + firstClassDefMutable(method.definingClass).methods.first { + MethodUtil.methodSignaturesMatch( + method, it + ) + } +} + +fun BytecodePatchContext.firstMethodMutable( + vararg strings: String, predicate: context(PredicateContext) Method.() -> Boolean = { true } +) = requireNotNull(firstMethodMutableOrNull(*strings, predicate = predicate)) + +class CachedReadOnlyProperty internal constructor( + private val block: BytecodePatchContext.(KProperty<*>) -> T +) : ReadOnlyProperty { + private var value: T? = null + private var cached = false + + override fun getValue(thisRef: BytecodePatchContext, property: KProperty<*>): T { + if (!cached) { + value = thisRef.block(property) + cached = true + } + + return value!! + } +} + +fun gettingFirstClassDefOrNull(predicate: context(PredicateContext) ClassDef.() -> Boolean) = + CachedReadOnlyProperty { firstClassDefOrNull(predicate) } + +fun gettingFirstClassDef(predicate: context(PredicateContext) ClassDef.() -> Boolean) = + CachedReadOnlyProperty { firstClassDef(predicate) } + +fun gettingFirstClassDefMutableOrNull(predicate: context(PredicateContext) ClassDef.() -> Boolean) = + CachedReadOnlyProperty { firstClassDefMutableOrNull(predicate) } + +fun gettingFirstClassDefMutable(predicate: context(PredicateContext) ClassDef.() -> Boolean) = + CachedReadOnlyProperty { firstClassDefMutable(predicate) } + +fun gettingFirstClassDefOrNull( + type: String, predicate: (context(PredicateContext) ClassDef.() -> Boolean)? = null +) = CachedReadOnlyProperty { firstClassDefOrNull(type, predicate) } + +fun gettingFirstClassDef( + type: String, predicate: (context(PredicateContext) ClassDef.() -> Boolean)? = null +) = CachedReadOnlyProperty { firstClassDef(type, predicate) } + +fun gettingFirstClassDefMutableOrNull( + type: String, predicate: (context(PredicateContext) ClassDef.() -> Boolean)? = null +) = CachedReadOnlyProperty { firstClassDefMutableOrNull(type, predicate) } + +fun gettingFirstClassDefMutable( + type: String, predicate: (context(PredicateContext) ClassDef.() -> Boolean)? = null +) = CachedReadOnlyProperty { firstClassDefMutable(type, predicate) } + +fun gettingFirstMethodOrNull(predicate: context(PredicateContext) Method.() -> Boolean) = + CachedReadOnlyProperty { firstMethodOrNull(predicate) } + +fun gettingFirstMethod(predicate: context(PredicateContext) Method.() -> Boolean) = + CachedReadOnlyProperty { firstMethod(predicate) } + +fun gettingFirstMethodMutableOrNull(predicate: context(PredicateContext) Method.() -> Boolean) = + CachedReadOnlyProperty { firstMethodMutableOrNull(predicate) } + +fun gettingFirstMethodMutable(predicate: context(PredicateContext) Method.() -> Boolean) = + CachedReadOnlyProperty { firstMethodMutable(predicate) } + +fun gettingFirstMethodOrNull( + vararg strings: String, + predicate: context(PredicateContext) Method.() -> Boolean = { true }, +) = CachedReadOnlyProperty { firstMethodOrNull(*strings, predicate = predicate) } + +fun gettingFirstMethod( + vararg strings: String, + predicate: context(PredicateContext) Method.() -> Boolean = { true }, +) = CachedReadOnlyProperty { firstMethod(*strings, predicate = predicate) } + +fun gettingFirstMethodMutableOrNull( + vararg strings: String, + predicate: context(PredicateContext) Method.() -> Boolean = { true }, +) = CachedReadOnlyProperty { firstMethodMutableOrNull(*strings, predicate = predicate) } + +fun gettingFirstMethodMutable( + vararg strings: String, + predicate: context(PredicateContext) Method.() -> Boolean = { true }, +) = CachedReadOnlyProperty { firstMethodMutable(*strings, predicate = predicate) } + +// region Matcher + +// region IndexedMatcher + +fun indexedMatcher() = IndexedMatcher() + +fun indexedMatcher(build: IndexedMatcher.() -> Unit) = + IndexedMatcher().apply(build) + +fun Iterable.matchIndexed(build: IndexedMatcher.() -> Unit) = + indexedMatcher(build)(this) + +context(_: PredicateContext) +fun Iterable.rememberedMatchIndexed(key: Any, build: IndexedMatcher.() -> Unit) = + indexedMatcher()(key, this, build) + +context(matcher: IndexedMatcher) +fun head( + predicate: T.(lastMatchedIndex: Int, currentIndex: Int) -> Boolean +): T.(Int, Int) -> Boolean = { lastMatchedIndex, currentIndex -> + currentIndex == 0 && predicate(lastMatchedIndex, currentIndex) +} + +context(matcher: IndexedMatcher) +fun head(predicate: T.() -> Boolean): T.(Int, Int) -> Boolean = + head { _, _ -> predicate() } + +context(matcher: IndexedMatcher) +fun after( + range: IntRange = 1..1, + predicate: T.(lastMatchedIndex: Int, currentIndex: Int) -> Boolean +): T.(Int, Int) -> Boolean = predicate@{ lastMatchedIndex, currentIndex -> + val distance = currentIndex - lastMatchedIndex + + matcher.nextIndex = when { + distance < range.first -> lastMatchedIndex + range.first + distance > range.last -> -1 + else -> return@predicate predicate(lastMatchedIndex, currentIndex) + } + + false +} + +context(matcher: IndexedMatcher) +fun after(range: IntRange = 1..1, predicate: T.() -> Boolean) = + after(range) { _, _ -> predicate() } + +context(matcher: IndexedMatcher) +operator fun (T.(Int, Int) -> Boolean).unaryPlus() = matcher.add(this) + +class IndexedMatcher : Matcher Boolean>() { + private val _indices: MutableList = mutableListOf() + val indices: List = _indices + + private var lastMatchedIndex = -1 + private var currentIndex = -1 + var nextIndex: Int? = null + + override fun invoke(haystack: Iterable): Boolean { + // Normalize to list + val hay = haystack as? List ?: haystack.toList() + + _indices.clear() + this@IndexedMatcher.lastMatchedIndex = -1 + currentIndex = -1 + + data class Frame( + val patternIndex: Int, + val lastMatchedIndex: Int, + val previousFrame: Frame?, + var nextHayIndex: Int, + val matchedIndex: Int + ) + + val stack = ArrayDeque() + stack.add( + Frame( + patternIndex = 0, + lastMatchedIndex = -1, + previousFrame = null, + nextHayIndex = 0, + matchedIndex = -1 + ) + ) + + while (stack.isNotEmpty()) { + val frame = stack.last() + + if (frame.nextHayIndex >= hay.size || nextIndex == -1) { + stack.removeLast() + nextIndex = null + continue + } + + val i = frame.nextHayIndex + currentIndex = i + lastMatchedIndex = frame.lastMatchedIndex + nextIndex = null + + if (this[frame.patternIndex](hay[i], lastMatchedIndex, currentIndex)) { + Frame( + patternIndex = frame.patternIndex + 1, + lastMatchedIndex = i, + previousFrame = frame, + nextHayIndex = i + 1, + matchedIndex = i + ).also { + if (it.patternIndex == size) { + _indices += buildList(size) { + var f: Frame? = it + while (f != null && f.matchedIndex != -1) { + add(f.matchedIndex) + f = f.previousFrame + } + }.asReversed() + + return true + } + }.let(stack::add) + } + + frame.nextHayIndex = when (val nextIndex = nextIndex) { + null -> frame.nextHayIndex + 1 + -1 -> 0 // Frame will be removed next loop. + else -> nextIndex + } + } + + return false + } +} + +// endregion + +context(_: PredicateContext) +inline operator fun > M.invoke(key: Any, iterable: Iterable, builder: M.() -> Unit) = + remembered(key) { apply(builder) }(iterable) + +context(_: PredicateContext) +inline operator fun > M.invoke( + iterable: Iterable, + builder: M.() -> Unit +) = invoke(this@invoke.hashCode(), iterable, builder) + +abstract class Matcher : MutableList by mutableListOf() { + var matchIndex = -1 + protected set + + abstract operator fun invoke(haystack: Iterable): Boolean +} + +// endregion Matcher + +class PredicateContext internal constructor() : MutableMap by mutableMapOf() + +context(context: PredicateContext) +inline fun remembered(key: Any, defaultValue: () -> V) = + context[key] as? V ?: defaultValue().also { context[key] = it } + + +fun T.declarativePredicate(build: DeclarativePredicateBuilder.() -> Unit) = + DeclarativePredicateBuilder().apply(build).all(this) + +context(_: PredicateContext) +fun T.rememberedDeclarativePredicate(key: Any, block: DeclarativePredicateBuilder.() -> Unit): Boolean = + remembered(key) { DeclarativePredicateBuilder().apply(block) }.all(this) + +context(_: PredicateContext) +private fun T.rememberedDeclarativePredicate(predicate: context(PredicateContext, T) DeclarativePredicateBuilder.() -> Unit) = + rememberedDeclarativePredicate("declarative predicate build") { predicate() } + +fun BytecodePatchContext.firstClassDefByDeclarativePredicateOrNull( + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = firstClassDefOrNull { rememberedDeclarativePredicate(predicate) } + +fun BytecodePatchContext.firstClassDefByDeclarativePredicate( + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = requireNotNull(firstClassDefByDeclarativePredicateOrNull(predicate)) + +fun BytecodePatchContext.firstClassDefMutableByDeclarativePredicateOrNull( + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = firstClassDefMutableOrNull { rememberedDeclarativePredicate(predicate) } + +fun BytecodePatchContext.firstClassDefMutableByDeclarativePredicate( + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = requireNotNull(firstClassDefMutableByDeclarativePredicateOrNull(predicate)) + +fun BytecodePatchContext.firstClassDefByDeclarativePredicateOrNull( + type: String, + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = firstClassDefOrNull(type) { rememberedDeclarativePredicate(predicate) } + +fun BytecodePatchContext.firstClassDefByDeclarativePredicate( + type: String, + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = requireNotNull(firstClassDefByDeclarativePredicateOrNull(type, predicate)) + +fun BytecodePatchContext.firstClassDefMutableByDeclarativePredicateOrNull( + type: String, + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = firstClassDefMutableOrNull(type) { rememberedDeclarativePredicate(predicate) } + +fun BytecodePatchContext.firstClassDefMutableByDeclarativePredicate( + type: String, + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = requireNotNull(firstClassDefMutableByDeclarativePredicateOrNull(type, predicate)) + +fun BytecodePatchContext.firstMethodByDeclarativePredicateOrNull( + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = firstMethodOrNull { rememberedDeclarativePredicate(predicate) } + +fun BytecodePatchContext.firstMethodByDeclarativePredicate( + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = requireNotNull(firstMethodByDeclarativePredicateOrNull(predicate)) + +fun BytecodePatchContext.firstMethodMutableByDeclarativePredicateOrNull( + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = firstMethodMutableOrNull { rememberedDeclarativePredicate(predicate) } + +fun BytecodePatchContext.firstMethodMutableByDeclarativePredicate( + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = requireNotNull(firstMethodMutableByDeclarativePredicateOrNull(predicate)) + +fun BytecodePatchContext.firstMethodByDeclarativePredicateOrNull( + vararg strings: String, + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = firstMethodOrNull(*strings) { rememberedDeclarativePredicate(predicate) } + +fun BytecodePatchContext.firstMethodByDeclarativePredicate( + vararg strings: String, + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = requireNotNull(firstMethodByDeclarativePredicateOrNull(*strings, predicate = predicate)) + +fun BytecodePatchContext.firstMethodMutableByDeclarativePredicateOrNull( + vararg strings: String, + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = firstMethodMutableOrNull(*strings) { rememberedDeclarativePredicate(predicate) } + +fun BytecodePatchContext.firstMethodMutableByDeclarativePredicate( + vararg strings: String, + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = requireNotNull(firstMethodMutableByDeclarativePredicateOrNull(*strings, predicate = predicate)) + +fun gettingFirstClassDefByDeclarativePredicateOrNull( + type: String, + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = gettingFirstClassDefOrNull(type) { rememberedDeclarativePredicate(predicate) } + +fun gettingFirstClassDefByDeclarativePredicate( + type: String, + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = CachedReadOnlyProperty { firstClassDefByDeclarativePredicate(type, predicate) } + +fun gettingFirstClassDefMutableByDeclarativePredicateOrNull( + type: String, + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = gettingFirstClassDefMutableOrNull(type) { rememberedDeclarativePredicate(predicate) } + +fun gettingFirstClassDefMutableByDeclarativePredicate( + type: String, + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = CachedReadOnlyProperty { firstClassDefMutableByDeclarativePredicate(type, predicate) } + +fun gettingFirstClassDefByDeclarativePredicateOrNull( + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = gettingFirstClassDefOrNull { rememberedDeclarativePredicate(predicate) } + +fun gettingFirstClassDefByDeclarativePredicate( + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = CachedReadOnlyProperty { firstClassDefByDeclarativePredicate(predicate) } + +fun gettingFirstClassDefMutableByDeclarativePredicateOrNull( + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = gettingFirstClassDefMutableOrNull { rememberedDeclarativePredicate(predicate) } + +fun gettingFirstClassDefMutableByDeclarativePredicate( + predicate: context(PredicateContext, ClassDef) DeclarativePredicateBuilder.() -> Unit +) = CachedReadOnlyProperty { firstClassDefMutableByDeclarativePredicate(predicate) } + +fun gettingFirstMethodByDeclarativePredicateOrNull( + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = gettingFirstMethodOrNull { rememberedDeclarativePredicate(predicate) } + +fun gettingFirstMethodByDeclarativePredicate( + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = CachedReadOnlyProperty { firstMethodByDeclarativePredicate(predicate = predicate) } + +fun gettingFirstMethodMutableByDeclarativePredicateOrNull( + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = gettingFirstMethodMutableOrNull { rememberedDeclarativePredicate(predicate) } + +fun gettingFirstMethodMutableByDeclarativePredicate( + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = CachedReadOnlyProperty { firstMethodMutableByDeclarativePredicate(predicate = predicate) } + +fun gettingFirstMethodByDeclarativePredicateOrNull( + vararg strings: String, + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = gettingFirstMethodOrNull(*strings) { rememberedDeclarativePredicate(predicate) } + +fun gettingFirstMethodByDeclarativePredicate( + vararg strings: String, + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = CachedReadOnlyProperty { firstMethodByDeclarativePredicate(*strings, predicate = predicate) } + +fun gettingFirstMethodMutableByDeclarativePredicateOrNull( + vararg strings: String, + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = gettingFirstMethodMutableOrNull(*strings) { rememberedDeclarativePredicate(predicate) } + +fun gettingFirstMethodMutableByDeclarativePredicate( + vararg strings: String, + predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) = CachedReadOnlyProperty { firstMethodMutableByDeclarativePredicate(*strings, predicate = predicate) } + + +class DeclarativePredicateBuilder internal constructor() { + private val children = mutableListOf Boolean>() + + fun anyOf(block: DeclarativePredicateBuilder.() -> Unit) { + val child = DeclarativePredicateBuilder().apply(block) + children += { child.children.any { it() } } + } + + fun predicate(block: T.() -> Boolean) { + children += block + } + + fun all(target: T): Boolean = children.all { target.it() } + fun any(target: T): Boolean = children.all { target.it() } +} + +fun firstMethodComposite( + vararg strings: String, + builder: + context(PredicateContext, Method, IndexedMatcher, MutableList) DeclarativePredicateBuilder.() -> Unit +) = with(indexedMatcher()) matcher@{ + with(mutableListOf()) strings@{ + addAll(strings) + + Composition( + indices = this@matcher.indices, + strings = this@strings + ) { builder() } + } +} + +val m = firstMethodComposite("lookup") { + instructions( + head { string == "str" }, + anyOf(), + anyOf(after(1..2, string("also lookup"))), + string("s", String::startsWith), + string(), + literal(), + after(1..4, anyOf()), + noneOf(`is`()), + instruction { opcode == Opcode.CONST_STRING }, + { _, _ -> opcode == Opcode.CONST_STRING }, + ) + instructions { + +head(literal()) + + if (true) + +after(1..2, string("lookup")) + else + +instruction { opcode == Opcode.CONST_STRING } + + add { currentIndex, lastMatchedIndex -> + currentIndex == 2 && opcode == Opcode.CONST_STRING + } + } + + instructions { + +anyOf(after(1..2, string("also lookup")), Opcode.IF_EQ()) + +head(anyOf(string("s"), "s"(), Opcode.IF_EQ())) + +head(allOf(Opcode.CONST_STRING_JUMBO(), "str"())) + add(instruction { this.opcode == Opcode.CONST_STRING || this.string == "lookup" }) + add(instruction { string == "lookup" }) + +after(1..2, anyOf(string("s"), Opcode.IF_EQ())) + +string("also lookup") + +"equals"() + +"prefix" { startsWith(it) } + +string { startsWith("prefix") } + +"suffix"(String::endsWith) + +literal(12) { it >= this } + +literal(1232) + +literal { this >= 1123 } + +literal() + +string() + +string { startsWith("s") } + +method() + +reference() + +field() + +`is`() + +`is`() + +allOf(`is`(), string("test")) + +`is` { reference !is StringReference } + +`is` { registerCount > 2 } + +registers(0, 1, 1, 2) + +noneOf(registers({ size > 3 }), reference { contains("SomeClass") }) + +type() + +Opcode.CONST_STRING() + +after(1..2, Opcode.RETURN_VOID()) + +reference { startsWith("some") } + +field("s") + +allOf() // Wildcard + +anyOf(noneOf(string(), literal(123)), allOf(Opcode.CONST_STRING(), string("tet"))) + +method("abc") { startsWith(it) } + +after(1..2, string("also lookup") { startsWith(it) }) + +after(1..2, anyOf(string("a", String::endsWith), Opcode.CONST_4())) + +reference { contains("some") } + +method("name") + +field("name") + +after(1..2, reference("com/example", String::contains)) + +after(1..2, reference("lookup()V", String::endsWith)) + +after(1..2, reference("Lcom/example;->method()V", String::startsWith)) + +after(1..2, reference("Lcom/example;->method()V")) + +after(1..2, reference("Lcom/example;->field:Ljava/lang/String;") { endsWith(it) }) + } +} + +inline fun `is`( + crossinline predicate: T.() -> Boolean = { true } +): Instruction.(Int, Int) -> Boolean = { _, _ -> (this as? T)?.predicate() == true } + +fun instruction(predicate: Instruction.() -> Boolean): Instruction.(Int, Int) -> Boolean = { _, _ -> predicate() } + +fun registers(predicate: IntArray.() -> Boolean = { true }): Instruction.(Int, Int) -> Boolean = { _, _ -> + when (this) { + is RegisterRangeInstruction -> + IntArray(registerCount) { startRegister + it }.predicate() + + is FiveRegisterInstruction -> + intArrayOf(registerC, registerD, registerE, registerF, registerG).predicate() + + is ThreeRegisterInstruction -> + intArrayOf(registerA, registerB, registerC).predicate() + + is TwoRegisterInstruction -> + intArrayOf(registerA, registerB).predicate() + + is OneRegisterInstruction -> + intArrayOf(registerA).predicate() + + else -> false + } +} + +fun registers( + vararg registers: Int, + compare: IntArray.(registers: IntArray) -> Boolean = { registers -> + this.size >= registers.size && registers.indices.all { this[it] == registers[it] } + } +) = registers({ compare(registers) }) + +fun literal(predicate: Long.() -> Boolean = { true }): Instruction.(Int, Int) -> Boolean = + { _, _ -> wideLiteral?.predicate() == true } + +fun literal(literal: Long, compare: Long.(Long) -> Boolean = Long::equals) = + literal { compare(literal) } + +fun reference(predicate: String.() -> Boolean = { true }): Instruction.(Int, Int) -> Boolean = + predicate@{ _, _ -> this.reference?.toString()?.predicate() == true } + +fun reference(reference: String, compare: String.(String) -> Boolean = String::equals) = + reference { compare(reference) } + +fun field(predicate: String.() -> Boolean = { true }): Instruction.(Int, Int) -> Boolean = { _, _ -> + fieldReference?.name?.predicate() == true +} + +fun field(name: String, compare: String.(String) -> Boolean = String::equals) = + field { compare(name) } + + +fun type(predicate: String.() -> Boolean = { true }): Instruction.(Int, Int) -> Boolean = + { _, _ -> type?.predicate() == true } + +fun type(type: String, compare: String.(String) -> Boolean = String::equals) = + type { compare(type) } + +fun method(predicate: String.() -> Boolean = { true }): Instruction.(Int, Int) -> Boolean = { _, _ -> + methodReference?.name?.predicate() == true +} + +fun method(name: String, compare: String.(String) -> Boolean = String::equals) = + method { compare(name) } + +fun string(compare: String.() -> Boolean = { true }): Instruction.(Int, Int) -> Boolean = predicate@{ _, _ -> + this@predicate.string?.compare() == true +} + +context(stringsList: MutableList, builder: DeclarativePredicateBuilder) +fun string( + string: String, + compare: String.(String) -> Boolean = String::equals +): Instruction.(Int, Int) -> Boolean { + if (compare == String::equals) stringsList += string + + return string { compare(string) } +} + +context(stringsList: MutableList) +operator fun String.invoke(compare: String.(String) -> Boolean = String::equals): Instruction.(Int, Int) -> Boolean { + if (compare == String::equals) stringsList += this + + return { _, _ -> string?.compare(this@invoke) == true } +} + +operator fun Opcode.invoke(): Instruction.(currentIndex: Int, lastMatchedIndex: Int) -> Boolean = + { _, _ -> opcode == this@invoke } + +fun anyOf( + vararg predicates: Instruction.(currentIndex: Int, lastMatchedIndex: Int) -> Boolean +): Instruction.(Int, Int) -> Boolean = { currentIndex, lastMatchedIndex -> + predicates.any { predicate -> predicate(currentIndex, lastMatchedIndex) } +} + +fun allOf( + vararg predicates: Instruction.(currentIndex: Int, lastMatchedIndex: Int) -> Boolean +): Instruction.(Int, Int) -> Boolean = { currentIndex, lastMatchedIndex -> + predicates.all { predicate -> predicate(currentIndex, lastMatchedIndex) } +} + +fun noneOf( + vararg predicates: Instruction.(currentIndex: Int, lastMatchedIndex: Int) -> Boolean +): Instruction.(Int, Int) -> Boolean = { currentIndex, lastMatchedIndex -> + predicates.none { predicate -> predicate(currentIndex, lastMatchedIndex) } +} + +fun DeclarativePredicateBuilder.accessFlags(vararg flags: AccessFlags) = + predicate { accessFlags(*flags) } + +fun DeclarativePredicateBuilder.returnType( + returnType: String, + compare: String.(String) -> Boolean = String::startsWith +) = predicate { this.returnType.compare(returnType) } + +fun DeclarativePredicateBuilder.name( + name: String, + compare: String.(String) -> Boolean = String::equals +) = + predicate { this.name.compare(name) } + +fun DeclarativePredicateBuilder.definingClass( + definingClass: String, + compare: String.(String) -> Boolean = String::equals +) = predicate { this.definingClass.compare(definingClass) } + +fun DeclarativePredicateBuilder.parameterTypes(vararg parameterTypePrefixes: String) = predicate { + parameterTypes.size == parameterTypePrefixes.size && parameterTypes.zip(parameterTypePrefixes) + .all { (a, b) -> a.startsWith(b) } +} + +context(matcher: IndexedMatcher) +fun DeclarativePredicateBuilder.instructions( + build: IndexedMatcher.() -> Unit +) { + matcher.apply(build) + predicate { implementation { matcher(instructions) } } +} + +context(matcher: IndexedMatcher) +fun DeclarativePredicateBuilder.instructions( + vararg predicates: Instruction.(currentIndex: Int, lastMatchedIndex: Int) -> Boolean +) = instructions { addAll(predicates) } + +fun DeclarativePredicateBuilder.custom(block: Method.() -> Boolean) { + predicate { block() } +} + +class Composition internal constructor( + val indices: List, + val strings: List, + private val predicate: context(PredicateContext, Method) DeclarativePredicateBuilder.() -> Unit +) { + private var _methodOrNull: com.android.tools.smali.dexlib2.mutable.MutableMethod? = null + + context(context: BytecodePatchContext) + val methodOrNull: com.android.tools.smali.dexlib2.mutable.MutableMethod? + get() { + if (_methodOrNull == null) { + _methodOrNull = if (strings.isEmpty()) + context.firstMethodMutableByDeclarativePredicateOrNull(predicate) + else + context.firstMethodMutableByDeclarativePredicateOrNull( + strings = strings.toTypedArray(), + predicate + ) + } + + return _methodOrNull + } + + context(_: BytecodePatchContext) + val method get() = requireNotNull(methodOrNull) +} diff --git a/src/main/kotlin/app/revanced/patcher/PackageMetadata.kt b/core/src/commonMain/kotlin/app/revanced/patcher/PackageMetadata.kt similarity index 100% rename from src/main/kotlin/app/revanced/patcher/PackageMetadata.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/PackageMetadata.kt diff --git a/src/main/kotlin/app/revanced/patcher/Patcher.kt b/core/src/commonMain/kotlin/app/revanced/patcher/Patcher.kt similarity index 95% rename from src/main/kotlin/app/revanced/patcher/Patcher.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/Patcher.kt index 1247cb9..d8cdec8 100644 --- a/src/main/kotlin/app/revanced/patcher/Patcher.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/Patcher.kt @@ -1,9 +1,11 @@ package app.revanced.patcher import app.revanced.patcher.patch.* +import com.google.common.annotations.VisibleForTesting import kotlinx.coroutines.flow.flow import java.io.Closeable import java.util.logging.Logger +import kotlin.reflect.jvm.jvmName /** * A Patcher. @@ -11,7 +13,7 @@ import java.util.logging.Logger * @param config The configuration to use for the patcher. */ class Patcher(private val config: PatcherConfig) : Closeable { - private val logger = Logger.getLogger(this::class.java.name) + private val logger = Logger.getLogger(this::class.jvmName) /** * The context containing the current state of the patcher. @@ -69,7 +71,7 @@ class Patcher(private val config: PatcherConfig) : Closeable { // Recursively execute all dependency patches. dependencies.forEach { dependency -> - dependency.execute(executedPatches).exception?.let{ + dependency.execute(executedPatches).exception?.let { return PatchResult( this, PatchException( @@ -96,10 +98,9 @@ class Patcher(private val config: PatcherConfig) : Closeable { context.resourceContext.decodeResources(config.resourceMode) } - logger.info("Initializing lookup maps") + logger.info("Initializing cache") - // Accessing the lazy lookup maps to initialize them. - context.bytecodeContext.lookupMaps + context.bytecodeContext.classDefs.initializeCache() logger.info("Executing patches") diff --git a/src/main/kotlin/app/revanced/patcher/PatcherConfig.kt b/core/src/commonMain/kotlin/app/revanced/patcher/PatcherConfig.kt similarity index 96% rename from src/main/kotlin/app/revanced/patcher/PatcherConfig.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/PatcherConfig.kt index 037f7d3..5ee117d 100644 --- a/src/main/kotlin/app/revanced/patcher/PatcherConfig.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/PatcherConfig.kt @@ -3,7 +3,10 @@ package app.revanced.patcher import app.revanced.patcher.patch.ResourcePatchContext import brut.androlib.Config import java.io.File +import java.io.deleteRecursively +import java.io.resolve import java.util.logging.Logger +import kotlin.reflect.jvm.jvmName /** * The configuration for the patcher. @@ -38,7 +41,7 @@ class PatcherConfig( frameworkFileDirectory: String? = null, ) : this(apkFile, temporaryFilesPath, aaptBinaryPath?.let { File(it) }, frameworkFileDirectory) - private val logger = Logger.getLogger(PatcherConfig::class.java.name) + private val logger = Logger.getLogger(PatcherConfig::class.jvmName) /** * The mode to use for resource decoding and compiling. diff --git a/src/main/kotlin/app/revanced/patcher/PatcherContext.kt b/core/src/commonMain/kotlin/app/revanced/patcher/PatcherContext.kt similarity index 100% rename from src/main/kotlin/app/revanced/patcher/PatcherContext.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/PatcherContext.kt diff --git a/src/main/kotlin/app/revanced/patcher/PatcherResult.kt b/core/src/commonMain/kotlin/app/revanced/patcher/PatcherResult.kt similarity index 100% rename from src/main/kotlin/app/revanced/patcher/PatcherResult.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/PatcherResult.kt diff --git a/src/main/kotlin/app/revanced/patcher/extensions/Instruction.kt b/core/src/commonMain/kotlin/app/revanced/patcher/extensions/Instruction.kt similarity index 60% rename from src/main/kotlin/app/revanced/patcher/extensions/Instruction.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/extensions/Instruction.kt index f16e030..01160d1 100644 --- a/src/main/kotlin/app/revanced/patcher/extensions/Instruction.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/extensions/Instruction.kt @@ -1,16 +1,12 @@ package app.revanced.patcher.extensions -import app.revanced.patcher.dex.mutable.MutableMethod import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.Opcodes import com.android.tools.smali.dexlib2.builder.BuilderInstruction -import com.android.tools.smali.dexlib2.iface.instruction.DualReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction +import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction import com.android.tools.smali.dexlib2.iface.reference.* -import com.android.tools.smali.dexlib2.util.MethodUtil import com.android.tools.smali.dexlib2.writer.builder.DexBuilder import com.android.tools.smali.smali.smaliFlexLexer import com.android.tools.smali.smali.smaliParser @@ -20,39 +16,6 @@ import org.antlr.runtime.TokenSource import org.antlr.runtime.tree.CommonTreeNodeStream import java.io.StringReader -inline fun Instruction.reference(predicate: T.() -> Boolean) = - ((this as? ReferenceInstruction)?.reference as? T)?.predicate() ?: false - -inline fun Instruction.reference2(predicate: T.() -> Boolean) = - ((this as? DualReferenceInstruction)?.reference2 as? T)?.predicate() ?: false - -fun Instruction.methodReference(predicate: MethodReference.() -> Boolean) = - reference(predicate) - -fun Instruction.methodReference(methodReference: MethodReference) = - methodReference { MethodUtil.methodSignaturesMatch(methodReference, this) } - -fun Instruction.fieldReference(predicate: FieldReference.() -> Boolean) = - reference(predicate) - -fun Instruction.fieldReference(fieldName: String) = - fieldReference { name == fieldName } - -fun Instruction.type(predicate: String.() -> Boolean) = - reference { type.predicate() } - -fun Instruction.type(type: String) = - type { this == type } - -fun Instruction.string(predicate: String.() -> Boolean) = - reference { string.predicate() } - -fun Instruction.string(string: String) = - string { this == string } - -fun Instruction.opcode(opcode: Opcode) = this.opcode == opcode - -fun Instruction.wideLiteral(wideLiteral: Long) = (this as? WideLiteralInstruction)?.wideLiteral == wideLiteral private inline fun Instruction.reference(): T? = (this as? ReferenceInstruction)?.reference as? T @@ -61,24 +24,45 @@ val Instruction.reference: Reference? get() = reference() val Instruction.methodReference - get() = - reference() + get() = reference() val Instruction.fieldReference - get() = - reference() + get() = reference() val Instruction.typeReference - get() = - reference() + get() = reference() val Instruction.stringReference - get() = - reference() + get() = reference() +/** TODO: This is technically missing for consistency: + +private inline fun Instruction.reference2(): T? = +(this as? DualReferenceInstruction)?.reference2 as? T + +val Instruction.reference2: Reference? +get() = reference2() + +val Instruction.methodReference2 +get() = reference2() + +val Instruction.fieldReference2 +get() = reference2() + +val Instruction.typeReference2 +get() = reference2() + +val Instruction.stringReference2 +get() = reference2() + **/ + +val Instruction.type + get() = typeReference?.type + +val Instruction.string + get() = stringReference?.string val Instruction.wideLiteral - get() = - (this as? WideLiteralInstruction)?.wideLiteral + get() = (this as? NarrowLiteralInstruction)?.wideLiteral private const val CLASS_HEADER = ".class LInlineCompiler;\n.super Ljava/lang/Object;\n" @@ -94,7 +78,7 @@ private val sb by lazy { StringBuilder(512) } * @param templateMethod The method to compile the instructions against. * @returns A list of instructions. */ -fun String.toInstructions(templateMethod: MutableMethod? = null): List { +fun String.toInstructions(templateMethod: com.android.tools.smali.dexlib2.mutable.MutableMethod? = null): List { val parameters = templateMethod?.parameterTypes?.joinToString("") { it } ?: "" val registers = templateMethod?.implementation?.registerCount ?: 1 // TODO: Should this be 0? val isStatic = templateMethod?.let { AccessFlags.STATIC.isSet(it.accessFlags) } ?: true diff --git a/src/main/kotlin/app/revanced/patcher/extensions/Method.kt b/core/src/commonMain/kotlin/app/revanced/patcher/extensions/Method.kt similarity index 96% rename from src/main/kotlin/app/revanced/patcher/extensions/Method.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/extensions/Method.kt index 3275d6b..55ff3a3 100644 --- a/src/main/kotlin/app/revanced/patcher/extensions/Method.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/extensions/Method.kt @@ -1,6 +1,6 @@ package app.revanced.patcher.extensions -import app.revanced.patcher.dex.mutable.MutableMethod +import com.android.tools.smali.dexlib2.mutable.MutableMethod import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.builder.BuilderInstruction import com.android.tools.smali.dexlib2.builder.BuilderOffsetInstruction @@ -64,7 +64,7 @@ fun MutableMethodImplementation.removeInstructions(count: Int) = removeInstructi fun MutableMethodImplementation.replaceInstructions( index: Int, instructions: List, -) = instructions.forEach { replaceInstruction(index, it) } +) = instructions.forEachIndexed { i, instruction -> replaceInstruction(index + i, instruction) } /** * Add an instruction to a method at the given index. @@ -100,7 +100,8 @@ fun MutableMethod.addInstruction( * * @param smaliInstructions The instruction to add. */ -fun MutableMethod.addInstruction(smaliInstructions: String) = implementation!!.addInstruction(smaliInstructions.toInstructions(this).first()) +fun MutableMethod.addInstruction(smaliInstructions: String) = + implementation!!.addInstruction(smaliInstructions.toInstructions(this).first()) /** * Add instructions to a method at the given index. @@ -118,7 +119,8 @@ fun MutableMethod.addInstructions( * * @param instructions The instructions to add. */ -fun MutableMethod.addInstructions(instructions: List) = implementation!!.addInstructions(instructions) +fun MutableMethod.addInstructions(instructions: List) = + implementation!!.addInstructions(instructions) /** * Add instructions to a method. @@ -135,7 +137,8 @@ fun MutableMethod.addInstructions( * * @param smaliInstructions The instructions to add. */ -fun MutableMethod.addInstructions(smaliInstructions: String) = implementation!!.addInstructions(smaliInstructions.toInstructions(this)) +fun MutableMethod.addInstructions(smaliInstructions: String) = + implementation!!.addInstructions(smaliInstructions.toInstructions(this)) /** * Add instructions to a method at the given index. @@ -193,6 +196,7 @@ fun MutableMethod.addInstructionsWithLabels( i.registerB, label, ) + is BuilderInstruction30t -> BuilderInstruction30t(i.opcode, label) is BuilderInstruction31t -> BuilderInstruction31t(i.opcode, i.registerA, label) else -> throw IllegalStateException( diff --git a/core/src/commonMain/kotlin/app/revanced/patcher/patch/BytecodePatchContext.kt b/core/src/commonMain/kotlin/app/revanced/patcher/patch/BytecodePatchContext.kt new file mode 100644 index 0000000..137179e --- /dev/null +++ b/core/src/commonMain/kotlin/app/revanced/patcher/patch/BytecodePatchContext.kt @@ -0,0 +1,287 @@ +package app.revanced.patcher.patch + +import app.revanced.patcher.InternalApi +import app.revanced.patcher.PatcherConfig +import app.revanced.patcher.PatcherResult +import com.android.tools.smali.dexlib2.mutable.MutableClassDef +import com.android.tools.smali.dexlib2.mutable.MutableClassDef.Companion.toMutable +import app.revanced.patcher.extensions.instructionsOrNull +import app.revanced.patcher.util.ClassMerger.merge +import app.revanced.patcher.util.MethodNavigator +import com.android.tools.smali.dexlib2.iface.ClassDef +import com.android.tools.smali.dexlib2.iface.DexFile +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.reference.StringReference +import lanchon.multidexlib2.BasicDexFileNamer +import lanchon.multidexlib2.DexIO +import lanchon.multidexlib2.MultiDexIO +import lanchon.multidexlib2.RawDexIO +import java.io.Closeable +import java.io.IOException +import java.io.deleteRecursively +import java.io.inputStream +import java.io.resolve +import java.util.logging.Logger +import kotlin.reflect.jvm.jvmName + +/** + * A context for patches containing the current state of the bytecode. + * + * @param config The [PatcherConfig] used to create this context. + */ +@Suppress("MemberVisibilityCanBePrivate") +class BytecodePatchContext internal constructor(internal val config: PatcherConfig) : + PatchContext>, + Closeable { + private val logger = Logger.getLogger(this::class.jvmName) + + inner class ClassDefs private constructor( + dexFile: DexFile, + private val classDefs: MutableSet = dexFile.classes.toMutableSet() + ) : + MutableSet by classDefs { + private val byType = mutableMapOf() + + operator fun get(name: String): ClassDef? = byType[name] + + // Better performance according to + // https://github.com/LisoUseInAIKyrios/revanced-patcher/commit/9b6d95d4f414a35ed68da37b0ecd8549df1ef63a + private val _methodsByStrings = + LinkedHashMap>(2 * size, 0.5f) + + val methodsByString: Map> = _methodsByStrings + + // Can have a use-case in the future: + // private val _methodsWithString = methodsByString.values.flatten().toMutableSet() + // val methodsWithString: Set = _methodsWithString + + constructor() : this( + MultiDexIO.readDexFile( + true, + config.apkFile, + BasicDexFileNamer(), + null, + null + ) + ) + + internal val opcodes = dexFile.opcodes + + override fun add(element: ClassDef): Boolean { + val added = classDefs.add(element) + if (added) addCache(element) + + return added + } + + override fun addAll(elements: Collection): Boolean { + var anyAdded = false + elements.forEach { element -> + val added = classDefs.add(element) + if (added) { + addCache(element) + anyAdded = true + } + } + + return anyAdded + } + + // TODO: There is one default method "removeIf" in MutableSet, which we cannot override in the common module. + // The method must be overloaded with a NotImplementedException to avoid cache desynchronization. + + override fun clear() { + classDefs.clear() + byType.clear() + _methodsByStrings.clear() + } + + override fun remove(element: ClassDef): Boolean { + val removed = classDefs.remove(element) + if (removed) removeCache(element) + + return removed + } + + override fun removeAll(elements: Collection): Boolean { + var anyRemoved = false + elements.forEach { element -> + val removed = classDefs.remove(element) + if (removed) { + removeCache(element) + anyRemoved = true + } + } + + return anyRemoved + } + + override fun retainAll(elements: Collection) = + removeAll(classDefs.asSequence().filter { it !in elements }) + + private fun addCache(classDef: ClassDef) { + byType[classDef.type] = classDef + + classDef.forEachString { method, string -> + _methodsByStrings.getOrPut(string) { + // Maybe adjusting load factor/ initial size can improve performance. + mutableSetOf() + } += method + } + } + + private fun removeCache(classDef: ClassDef) { + byType -= classDef.type + + classDef.forEachString { method, string -> + if (_methodsByStrings[string]?.also { it -= method }?.isEmpty() == true) + _methodsByStrings -= string + } + } + + + private fun ClassDef.forEachString(action: (Method, String) -> Unit) { + methods.asSequence().forEach { method -> + method.instructionsOrNull?.asSequence() + ?.filterIsInstance() + ?.map { it.reference } + ?.filterIsInstance() + ?.map { it.string } + ?.forEach { string -> + action(method, string) + } + } + } + + /** + * Get a mutable version of the given [classDef], replacing it in the set if necessary. + * + * @param classDef The [ClassDef] to get or replace. + * @return The mutable version of the [classDef]. + * @see MutableClassDef + * @see toMutable + */ + fun getOrReplaceMutable(classDef: ClassDef): MutableClassDef { + if (classDef !is MutableClassDef) { + val mutableClassDef = classDef.toMutable() + this -= classDef + this += mutableClassDef + + return mutableClassDef + } + + return classDef + } + + internal fun initializeCache() = classDefs.forEach(::addCache) + + internal fun clearCache() { + byType.clear() + _methodsByStrings.clear() + } + } + + /** + * The list of classes. + */ + val classDefs = ClassDefs() + + /** + * Merge the extension of [bytecodePatch] into the [BytecodePatchContext]. + * If no extension is present, the function will return early. + * + * @param bytecodePatch The [BytecodePatch] to merge the extension of. + */ + internal fun mergeExtension(bytecodePatch: BytecodePatch) { + val extensionStream = bytecodePatch.extensionInputStream?.get() + ?: return logger.fine("Extension not found") + + RawDexIO.readRawDexFile( + extensionStream, 0, null + ).classes.forEach { classDef -> + val existingClass = classDefs[classDef.type] ?: run { + logger.fine { "Adding class \"$classDef\"" } + + classDefs += classDef + + return@forEach + } + + logger.fine { "Class \"$classDef\" exists already. Adding missing methods and fields." } + + existingClass.merge(classDef, this@BytecodePatchContext).let { mergedClass -> + // If the class was merged, replace the original class with the merged class. + if (mergedClass === existingClass) { + return@let + } + + classDefs -= existingClass + classDefs += mergedClass + } + } + + extensionStream.close() + } + + /** + * Navigate a method. + * + * @param method The method to navigate. + * + * @return A [MethodNavigator] for the method. + */ + fun navigate(method: MethodReference) = MethodNavigator(method) + + /** + * Compile bytecode from the [BytecodePatchContext]. + * + * @return The compiled bytecode. + */ + @InternalApi + override fun get(): Set { + logger.info("Compiling patched dex files") + + classDefs.clearCache() + System.gc() + + val patchedDexFileResults = + config.patchedFiles.resolve("dex").also { + it.deleteRecursively() // Make sure the directory is empty. + it.mkdirs() + }.apply { + MultiDexIO.writeDexFile( + true, + -1, + this, + BasicDexFileNamer(), + object : DexFile { + override fun getClasses() = classDefs.let { + // More performant according to + // https://github.com/LisoUseInAIKyrios/revanced-patcher/ + // commit/8c26ad08457fb1565ea5794b7930da42a1c81cf1 + // #diff-be698366d9868784ecf7da3fd4ac9d2b335b0bb637f9f618fbe067dbd6830b8fR197 + // TODO: Benchmark, if actually faster. + HashSet(it.size * 3 / 2).apply { addAll(it) } + } + + override fun getOpcodes() = classDefs.opcodes + }, + DexIO.DEFAULT_MAX_DEX_POOL_SIZE, + ) { _, entryName, _ -> logger.info { "Compiled $entryName" } } + }.listFiles { it.isFile }!!.map { + PatcherResult.PatchedDexFile(it.name, it.inputStream()) + }.toSet() + + return patchedDexFileResults + } + + override fun close() { + try { + classDefs.clear() + } catch (e: IOException) { + logger.warning("Failed to clear BytecodePatchContext: ${e.message}") + } + } +} diff --git a/src/main/kotlin/app/revanced/patcher/patch/Option.kt b/core/src/commonMain/kotlin/app/revanced/patcher/patch/Option.kt similarity index 99% rename from src/main/kotlin/app/revanced/patcher/patch/Option.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/patch/Option.kt index c37a1e6..2999d2b 100644 --- a/src/main/kotlin/app/revanced/patcher/patch/Option.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/patch/Option.kt @@ -1,7 +1,10 @@ +@file:Suppress("unused") + package app.revanced.patcher.patch import kotlin.reflect.KProperty import kotlin.reflect.KType +import kotlin.reflect.jvm.jvmName import kotlin.reflect.typeOf /** @@ -162,8 +165,8 @@ class Options internal constructor( (option as Option).value = value } catch (e: ClassCastException) { throw OptionException.InvalidValueTypeException( - value?.let { it::class.java.name } ?: "null", - option.value?.let { it::class.java.name } ?: "null", + value?.let { it::class.jvmName } ?: "null", + option.value?.let { it::class.jvmName } ?: "null", ) } } diff --git a/src/main/kotlin/app/revanced/patcher/patch/Patch.kt b/core/src/commonMain/kotlin/app/revanced/patcher/patch/Patch.kt similarity index 75% rename from src/main/kotlin/app/revanced/patcher/patch/Patch.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/patch/Patch.kt index 1639ba8..a918721 100644 --- a/src/main/kotlin/app/revanced/patcher/patch/Patch.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/patch/Patch.kt @@ -4,17 +4,12 @@ package app.revanced.patcher.patch import app.revanced.patcher.Patcher import app.revanced.patcher.PatcherContext -import dalvik.system.DexClassLoader -import lanchon.multidexlib2.BasicDexFileNamer -import lanchon.multidexlib2.MultiDexIO import java.io.File import java.io.InputStream import java.lang.reflect.Member import java.lang.reflect.Method import java.lang.reflect.Modifier -import java.net.URLClassLoader import java.util.function.Supplier -import java.util.jar.JarFile import kotlin.properties.ReadOnlyProperty typealias PackageName = String @@ -33,7 +28,7 @@ sealed interface PatchContext : Supplier * * @param C The [PatchContext] to execute and finalize the patch with. * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @param dependencies Other patches this patch depends on. @@ -127,7 +122,7 @@ internal fun Iterable>.forEachRecursively( * A bytecode patch. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @param compatiblePackages The packages the patch is compatible with. @@ -149,7 +144,7 @@ class BytecodePatch internal constructor( compatiblePackages: Set?, dependencies: Set>, options: Set>, - val extensionInputStream: Supplier?, + internal val extensionInputStream: Supplier?, executeBlock: (BytecodePatchContext) -> Unit, finalizeBlock: ((BytecodePatchContext) -> Unit)?, ) : Patch( @@ -176,7 +171,7 @@ class BytecodePatch internal constructor( * A raw resource patch. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @param compatiblePackages The packages the patch is compatible with. @@ -219,7 +214,7 @@ class RawResourcePatch internal constructor( * A resource patch. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @param compatiblePackages The packages the patch is compatible with. @@ -263,7 +258,7 @@ class ResourcePatch internal constructor( * * @param C The [PatchContext] to execute and finalize the patch with. * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @property compatiblePackages The packages the patch is compatible with. @@ -380,7 +375,7 @@ private fun > B.buildPatch(block: B.() -> Unit = {}) = apply * A [BytecodePatchBuilder] builder. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @property extensionInputStream Getter for the extension input stream of the patch. @@ -393,23 +388,20 @@ class BytecodePatchBuilder internal constructor( description: String?, use: Boolean, ) : PatchBuilder(name, description, use) { - // Must be internal for the inlined function "extendWith". - @PublishedApi internal var extensionInputStream: Supplier? = null - // Inlining is necessary to get the class loader that loaded the patch - // to load the extension from the resources. /** * Set the extension of the patch. * * @param extension The name of the extension resource. */ - @Suppress("NOTHING_TO_INLINE") - inline fun extendWith(extension: String) = apply { - val classLoader = object {}.javaClass.classLoader + fun extendWith(extension: String) = apply { + // Should be the classloader which loaded the patch class. + val classLoader = Class.forName(Thread.currentThread().stackTrace[2].className).classLoader!! extensionInputStream = Supplier { - classLoader.getResourceAsStream(extension) ?: throw PatchException("Extension \"$extension\" not found") + classLoader.getResourceAsStream(extension) + ?: throw PatchException("Extension \"$extension\" not found") } } @@ -430,7 +422,7 @@ class BytecodePatchBuilder internal constructor( * Create a new [BytecodePatch]. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @param block The block to build the patch. @@ -463,7 +455,7 @@ fun gettingBytecodePatch( * A [RawResourcePatch] builder. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @@ -490,7 +482,7 @@ class RawResourcePatchBuilder internal constructor( * Create a new [RawResourcePatch]. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @param block The block to build the patch. @@ -522,7 +514,7 @@ fun gettingRawResourcePatch( * A [ResourcePatch] builder. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @@ -549,7 +541,7 @@ class ResourcePatchBuilder internal constructor( * Create a new [ResourcePatch]. * * @param name The name of the patch. - * If null, the patch is named "Patch" and will not be loaded by [PatchLoader]. + * If null, the patch is named "Patch" and will not be loaded by [loadPatches]. * @param description The description of the patch. * @param use Weather or not the patch should be used. * @param block The block to build the patch. @@ -598,142 +590,45 @@ class PatchException(errorMessage: String?, cause: Throwable?) : Exception(error class PatchResult internal constructor(val patch: Patch<*>, val exception: PatchException? = null) /** - * A loader for patches. + * A collection of patches loaded from patches files. * - * Loads unnamed patches from JAR or DEX files declared as public static fields - * or returned by public static and non-parametrized methods. - * - * @param byPatchesFile The patches associated by the patches file they were loaded from. + * @property patchesByFile The patches mapped by their patches file. */ -sealed class PatchLoader private constructor( - val byPatchesFile: Map>>, -) : Set> by byPatchesFile.values.flatten().toSet() { - /** - * @param patchesFiles A set of JAR or DEX files to load the patches from. - * @param getBinaryClassNames A function that returns the binary names of all classes accessible by the class loader. - * @param classLoader The [ClassLoader] to use for loading the classes. - */ - private constructor( - patchesFiles: Set, - getBinaryClassNames: (patchesFile: File) -> List, - classLoader: ClassLoader, - ) : this(classLoader.loadPatches(patchesFiles.associateWith { getBinaryClassNames(it).toSet() })) +class Patches internal constructor(val patchesByFile: Map>>) : Set> +by patchesByFile.values.flatten().toSet() - /** - * A [PatchLoader] for JAR files. - * - * @param patchesFiles The JAR files to load the patches from. - * - * @constructor Create a new [PatchLoader] for JAR files. - */ - class Jar(patchesFiles: Set) : - PatchLoader( - patchesFiles, - { file -> - JarFile(file).entries().toList().filter { it.name.endsWith(".class") } - .map { it.name.substringBeforeLast('.').replace('/', '.') } - }, - URLClassLoader(patchesFiles.map { it.toURI().toURL() }.toTypedArray()), - ) +internal fun loadPatches( + patchesFiles: Set, + getBinaryClassNames: (patchesFile: File) -> List, + classLoader: ClassLoader, +): Patches { + fun Member.isUsable(): Boolean { + if (this is Method && parameterCount != 0) return false - /** - * A [PatchLoader] for [Dex] files. - * - * @param patchesFiles The DEX files to load the patches from. - * @param optimizedDexDirectory The directory to store optimized DEX files in. - * This parameter is deprecated and has no effect since API level 26. - * - * @constructor Create a new [PatchLoader] for [Dex] files. - */ - class Dex(patchesFiles: Set, optimizedDexDirectory: File? = null) : - PatchLoader( - patchesFiles, - { patchBundle -> - MultiDexIO.readDexFile(true, patchBundle, BasicDexFileNamer(), null, null).classes - .map { classDef -> - classDef.type.substring(1, classDef.length - 1) - } - }, - DexClassLoader( - patchesFiles.joinToString(File.pathSeparator) { it.absolutePath }, - optimizedDexDirectory?.absolutePath, - null, - this::class.java.classLoader, - ), - ) - - // Companion object required for unit tests. - private companion object { - val Class<*>.isPatch get() = Patch::class.java.isAssignableFrom(this) - - /** - * Public static fields that are patches. - */ - private val Class<*>.patchFields - get() = fields.filter { field -> - field.type.isPatch && field.canAccess() - }.map { field -> - field.get(null) as Patch<*> - } - - /** - * Public static and non-parametrized methods that return patches. - */ - private val Class<*>.patchMethods - get() = methods.filter { method -> - method.returnType.isPatch && method.parameterCount == 0 && method.canAccess() - }.map { method -> - method.invoke(null) as Patch<*> - } - - /** - * Loads unnamed patches declared as public static fields - * or returned by public static and non-parametrized methods. - * - * @param binaryClassNamesByPatchesFile The binary class name of the classes to load the patches from - * associated by the patches file. - * - * @return The loaded patches associated by the patches file. - */ - private fun ClassLoader.loadPatches(binaryClassNamesByPatchesFile: Map>) = - binaryClassNamesByPatchesFile.mapValues { (_, binaryClassNames) -> - binaryClassNames.asSequence().map { - loadClass(it) - }.flatMap { - it.patchFields + it.patchMethods - }.filter { - it.name != null - }.toSet() - } - - private fun Member.canAccess(): Boolean { - if (this is Method && parameterCount != 0) return false - - return Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) - } + return Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers) } + + fun Class<*>.getPatchFields() = fields.filter { field -> + field.type.isPatch && field.isUsable() + }.map { field -> + field.get(null) as Patch<*> + } + + fun Class<*>.getPatchMethods() = methods.filter { method -> + method.returnType.isPatch && method.parameterCount == 0 && method.isUsable() + }.map { method -> + method.invoke(null) as Patch<*> + } + + return Patches(patchesFiles.associateWith { file -> + getBinaryClassNames(file).map { + classLoader.loadClass(it) + }.flatMap { clazz -> + clazz.getPatchMethods() + clazz.getPatchFields() + }.filter { it.name != null }.toSet() + }) } -/** - * Loads patches from JAR files declared as public static fields - * or returned by public static and non-parametrized methods. - * Patches with no name are not loaded. - * - * @param patchesFiles The JAR files to load the patches from. - * - * @return The loaded patches. - */ -fun loadPatchesFromJar(patchesFiles: Set) = - PatchLoader.Jar(patchesFiles) +expect fun loadPatches(patchesFiles: Set): Patches -/** - * Loads patches from DEX files declared as public static fields - * or returned by public static and non-parametrized methods. - * Patches with no name are not loaded. - * - * @param patchesFiles The DEX files to load the patches from. - * - * @return The loaded patches. - */ -fun loadPatchesFromDex(patchesFiles: Set, optimizedDexDirectory: File? = null) = - PatchLoader.Dex(patchesFiles, optimizedDexDirectory) +internal expect val Class<*>.isPatch: Boolean diff --git a/src/main/kotlin/app/revanced/patcher/patch/ResourcePatchContext.kt b/core/src/commonMain/kotlin/app/revanced/patcher/patch/ResourcePatchContext.kt similarity index 99% rename from src/main/kotlin/app/revanced/patcher/patch/ResourcePatchContext.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/patch/ResourcePatchContext.kt index a65481d..69fbc6e 100644 --- a/src/main/kotlin/app/revanced/patcher/patch/ResourcePatchContext.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/patch/ResourcePatchContext.kt @@ -16,8 +16,10 @@ import brut.androlib.res.xml.ResXmlUtils import brut.directory.ExtFile import java.io.InputStream import java.io.OutputStream +import java.io.resolve import java.nio.file.Files import java.util.logging.Logger +import kotlin.reflect.jvm.jvmName /** * A context for patches containing the current state of resources. @@ -29,7 +31,7 @@ class ResourcePatchContext internal constructor( private val packageMetadata: PackageMetadata, private val config: PatcherConfig, ) : PatchContext { - private val logger = Logger.getLogger(ResourcePatchContext::class.java.name) + private val logger = Logger.getLogger(ResourcePatchContext::class.jvmName) /** * Read a document from an [InputStream]. diff --git a/src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt b/core/src/commonMain/kotlin/app/revanced/patcher/util/ClassMerger.kt similarity index 90% rename from src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/util/ClassMerger.kt index 728bce9..b2fcb49 100644 --- a/src/main/kotlin/app/revanced/patcher/util/ClassMerger.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/util/ClassMerger.kt @@ -1,6 +1,12 @@ package app.revanced.patcher.util -import app.revanced.patcher.dex.mutable.MutableClassDef +import com.android.tools.smali.dexlib2.mutable.MutableClassDef +import com.android.tools.smali.dexlib2.mutable.MutableClassDef.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableField +import com.android.tools.smali.dexlib2.mutable.MutableField.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableMethod +import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable +import app.revanced.patcher.firstClassDefOrNull import app.revanced.patcher.patch.BytecodePatchContext import app.revanced.patcher.util.ClassMerger.Utils.asMutableClass import app.revanced.patcher.util.ClassMerger.Utils.filterAny @@ -8,23 +14,19 @@ import app.revanced.patcher.util.ClassMerger.Utils.filterNotAny import app.revanced.patcher.util.ClassMerger.Utils.isPublic import app.revanced.patcher.util.ClassMerger.Utils.toPublic import app.revanced.patcher.util.ClassMerger.Utils.traverseClassHierarchy -import app.revanced.patcher.dex.mutable.MutableClassDef.Companion.toMutable -import app.revanced.patcher.dex.mutable.MutableField -import app.revanced.patcher.dex.mutable.MutableField.Companion.toMutable -import app.revanced.patcher.dex.mutable.MutableMethod -import app.revanced.patcher.dex.mutable.MutableMethod.Companion.toMutable import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.iface.ClassDef import com.android.tools.smali.dexlib2.util.MethodUtil import java.util.logging.Logger import kotlin.reflect.KFunction2 +import kotlin.reflect.jvm.jvmName /** * Experimental class to merge a [ClassDef] with another. * Note: This will not consider method implementations or if the class is missing a superclass or interfaces. */ internal object ClassMerger { - private val logger = Logger.getLogger(ClassMerger::class.java.name) + private val logger = Logger.getLogger(ClassMerger::class.jvmName) /** * Merge a class with [otherClass]. @@ -181,12 +183,13 @@ internal object ClassMerger { callback(targetClass) targetClass.superclass ?: return - classDefs.find { targetClass.superclass == it.type }?.mutable()?.let { - traverseClassHierarchy(it, callback) + + firstClassDefOrNull { type == targetClass.superclass }?.let { classDef -> + traverseClassHierarchy(classDefs.getOrReplaceMutable(classDef), callback) } } - fun ClassDef.asMutableClass() = if (this is MutableClassDef) this else this.toMutable() + fun ClassDef.asMutableClass() = this as? MutableClassDef ?: this.toMutable() /** * Check if the [AccessFlags.PUBLIC] flag is set. diff --git a/src/main/kotlin/app/revanced/patcher/util/Document.kt b/core/src/commonMain/kotlin/app/revanced/patcher/util/Document.kt similarity index 80% rename from src/main/kotlin/app/revanced/patcher/util/Document.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/util/Document.kt index c768552..1d5ea7c 100644 --- a/src/main/kotlin/app/revanced/patcher/util/Document.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/util/Document.kt @@ -1,14 +1,19 @@ package app.revanced.patcher.util +import collections.merge +import com.google.common.base.Charsets import org.w3c.dom.Document import java.io.Closeable import java.io.File import java.io.InputStream +import java.io.bufferedWriter +import java.io.inputStream import javax.xml.parsers.DocumentBuilderFactory import javax.xml.transform.OutputKeys import javax.xml.transform.TransformerFactory import javax.xml.transform.dom.DOMSource import javax.xml.transform.stream.StreamResult +import kotlin.use class Document internal constructor( inputStream: InputStream, @@ -29,7 +34,7 @@ class Document internal constructor( if (readerCount[it]!! > 1) { throw IllegalStateException( "Two or more instances are currently reading $it." + - "To be able to close this instance, no other instances may be reading $it at the same time.", + "To be able to close this instance, no other instances may be reading $it at the same time.", ) } else { readerCount.remove(it) @@ -40,9 +45,9 @@ class Document internal constructor( if (isAndroid) { transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-16") transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes") - it.bufferedWriter(charset = Charsets.UTF_8).use { writer -> - transformer.transform(DOMSource(this), StreamResult(writer)) - } + val writer = it.bufferedWriter(charset = Charsets.UTF_8) + transformer.transform(DOMSource(this), StreamResult(writer)) + writer.close() } else { transformer.transform(DOMSource(this), StreamResult(it)) } diff --git a/src/main/kotlin/app/revanced/patcher/util/MethodNavigator.kt b/core/src/commonMain/kotlin/app/revanced/patcher/util/MethodNavigator.kt similarity index 86% rename from src/main/kotlin/app/revanced/patcher/util/MethodNavigator.kt rename to core/src/commonMain/kotlin/app/revanced/patcher/util/MethodNavigator.kt index ab4117d..d58f872 100644 --- a/src/main/kotlin/app/revanced/patcher/util/MethodNavigator.kt +++ b/core/src/commonMain/kotlin/app/revanced/patcher/util/MethodNavigator.kt @@ -2,8 +2,10 @@ package app.revanced.patcher.util -import app.revanced.patcher.dex.mutable.MutableMethod +import com.android.tools.smali.dexlib2.mutable.MutableMethod import app.revanced.patcher.extensions.instructionsOrNull +import app.revanced.patcher.firstClassDef +import app.revanced.patcher.firstClassDefMutable import app.revanced.patcher.patch.BytecodePatchContext import com.android.tools.smali.dexlib2.iface.ClassDef import com.android.tools.smali.dexlib2.iface.Method @@ -82,10 +84,9 @@ class MethodNavigator internal constructor( * @return The last navigated method mutably. */ context(context: BytecodePatchContext) - fun stop() = with(context) { - classDefs.find(matchesCurrentMethodReferenceDefiningClass)!!.mutable().firstMethodBySignature - as MutableMethod - } + fun stop() = context.firstClassDefMutable(lastNavigatedMethodReference.definingClass) + .firstMethodBySignature as MutableMethod + /** * Get the last navigated method mutably. @@ -101,14 +102,7 @@ class MethodNavigator internal constructor( * @return The last navigated method immutably. */ context(context: BytecodePatchContext) - fun original(): Method = context.classDefs.first(matchesCurrentMethodReferenceDefiningClass).firstMethodBySignature - - /** - * Predicate to match the class defining the current method reference. - */ - private val matchesCurrentMethodReferenceDefiningClass = { classDef: ClassDef -> - classDef.type == lastNavigatedMethodReference.definingClass - } + fun original(): Method = context.firstClassDef(lastNavigatedMethodReference.definingClass).firstMethodBySignature /** * Find the first [lastNavigatedMethodReference] in the class. diff --git a/core/src/commonMain/kotlin/collections/MutableMap.kt b/core/src/commonMain/kotlin/collections/MutableMap.kt new file mode 100644 index 0000000..1a66170 --- /dev/null +++ b/core/src/commonMain/kotlin/collections/MutableMap.kt @@ -0,0 +1,13 @@ +package collections + +internal expect fun MutableMap.kmpMerge( + key: K, + value: V, + remappingFunction: (oldValue: V, newValue: V) -> V, +) + +internal fun MutableMap.merge( + key: K, + value: V, + remappingFunction: (oldValue: V, newValue: V) -> V, +) = kmpMerge(key, value, remappingFunction) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableAnnotationEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue.kt similarity index 50% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableAnnotationEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue.kt index 9eb4e79..99d1a64 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableAnnotationEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableAnnotationEncodedValue.kt @@ -1,9 +1,7 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value -import app.revanced.patcher.dex.mutable.MutableAnnotationElement.Companion.toMutable import com.android.tools.smali.dexlib2.base.value.BaseAnnotationEncodedValue -import com.android.tools.smali.dexlib2.iface.AnnotationElement -import com.android.tools.smali.dexlib2.iface.value.AnnotationEncodedValue +import com.android.tools.smali.dexlib2.mutable.MutableAnnotationElement.Companion.toMutable class MutableAnnotationEncodedValue(annotationEncodedValue: AnnotationEncodedValue) : BaseAnnotationEncodedValue(), @@ -14,15 +12,15 @@ class MutableAnnotationEncodedValue(annotationEncodedValue: AnnotationEncodedVal annotationEncodedValue.elements.map { annotationElement -> annotationElement.toMutable() }.toMutableSet() } - override fun getType(): String = this.type - fun setType(type: String) { this.type = type } - override fun getElements(): MutableSet = _elements + override fun getType() = this.type + + override fun getElements() = _elements companion object { - fun AnnotationEncodedValue.toMutable(): MutableAnnotationEncodedValue = MutableAnnotationEncodedValue(this) + fun AnnotationEncodedValue.toMutable() = MutableAnnotationEncodedValue(this) } } diff --git a/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue.kt new file mode 100644 index 0000000..97363b1 --- /dev/null +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableArrayEncodedValue.kt @@ -0,0 +1,16 @@ +package com.android.tools.smali.dexlib2.iface.value + +import com.android.tools.smali.dexlib2.base.value.BaseArrayEncodedValue +import com.android.tools.smali.dexlib2.iface.value.MutableEncodedValue.Companion.toMutable + +class MutableArrayEncodedValue(arrayEncodedValue: ArrayEncodedValue) : BaseArrayEncodedValue(), MutableEncodedValue { + private val _value by lazy { + arrayEncodedValue.value.map { encodedValue -> encodedValue.toMutable() }.toMutableList() + } + + override fun getValue() = _value + + companion object { + fun ArrayEncodedValue.toMutable(): MutableArrayEncodedValue = MutableArrayEncodedValue(this) + } +} diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableBooleanEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue.kt similarity index 80% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableBooleanEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue.kt index 9293cc4..ca24cb7 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableBooleanEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableBooleanEncodedValue.kt @@ -1,19 +1,18 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseBooleanEncodedValue -import com.android.tools.smali.dexlib2.iface.value.BooleanEncodedValue class MutableBooleanEncodedValue(booleanEncodedValue: BooleanEncodedValue) : BaseBooleanEncodedValue(), MutableEncodedValue { private var value = booleanEncodedValue.value - override fun getValue(): Boolean = this.value - fun setValue(value: Boolean) { this.value = value } + override fun getValue(): Boolean = this.value + companion object { fun BooleanEncodedValue.toMutable(): MutableBooleanEncodedValue = MutableBooleanEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue.kt similarity index 70% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue.kt index d9bdae4..82b04c0 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableByteEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableByteEncodedValue.kt @@ -1,19 +1,16 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseByteEncodedValue -import com.android.tools.smali.dexlib2.iface.value.ByteEncodedValue -class MutableByteEncodedValue(byteEncodedValue: ByteEncodedValue) : - BaseByteEncodedValue(), - MutableEncodedValue { +class MutableByteEncodedValue(byteEncodedValue: ByteEncodedValue) : BaseByteEncodedValue(), MutableEncodedValue { private var value = byteEncodedValue.value - override fun getValue(): Byte = this.value - fun setValue(value: Byte) { this.value = value } + override fun getValue(): Byte = this.value + companion object { fun ByteEncodedValue.toMutable(): MutableByteEncodedValue = MutableByteEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableCharEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue.kt similarity index 70% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableCharEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue.kt index 4f6a6d1..eef4676 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableCharEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableCharEncodedValue.kt @@ -1,19 +1,16 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseCharEncodedValue -import com.android.tools.smali.dexlib2.iface.value.CharEncodedValue -class MutableCharEncodedValue(charEncodedValue: CharEncodedValue) : - BaseCharEncodedValue(), - MutableEncodedValue { +class MutableCharEncodedValue(charEncodedValue: CharEncodedValue) : BaseCharEncodedValue(), MutableEncodedValue { private var value = charEncodedValue.value - override fun getValue(): Char = this.value - fun setValue(value: Char) { this.value = value } + override fun getValue(): Char = this.value + companion object { fun CharEncodedValue.toMutable(): MutableCharEncodedValue = MutableCharEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableDoubleEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue.kt similarity index 80% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableDoubleEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue.kt index 1af6dba..6259ec2 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableDoubleEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableDoubleEncodedValue.kt @@ -1,19 +1,18 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseDoubleEncodedValue -import com.android.tools.smali.dexlib2.iface.value.DoubleEncodedValue class MutableDoubleEncodedValue(doubleEncodedValue: DoubleEncodedValue) : BaseDoubleEncodedValue(), MutableEncodedValue { private var value = doubleEncodedValue.value - override fun getValue(): Double = this.value - fun setValue(value: Double) { this.value = value } + override fun getValue(): Double = this.value + companion object { fun DoubleEncodedValue.toMutable(): MutableDoubleEncodedValue = MutableDoubleEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue.kt similarity index 94% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue.kt index 9cc2a13..bf3112b 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableEncodedValue.kt @@ -1,7 +1,6 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.ValueType -import com.android.tools.smali.dexlib2.iface.value.* interface MutableEncodedValue : EncodedValue { companion object { diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableEnumEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue.kt similarity index 74% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableEnumEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue.kt index 07b2a17..5c41b7d 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableEnumEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableEnumEncodedValue.kt @@ -1,20 +1,17 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseEnumEncodedValue import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.value.EnumEncodedValue -class MutableEnumEncodedValue(enumEncodedValue: EnumEncodedValue) : - BaseEnumEncodedValue(), - MutableEncodedValue { +class MutableEnumEncodedValue(enumEncodedValue: EnumEncodedValue) : BaseEnumEncodedValue(), MutableEncodedValue { private var value = enumEncodedValue.value - override fun getValue(): FieldReference = this.value - fun setValue(value: FieldReference) { this.value = value } + override fun getValue(): FieldReference = this.value + companion object { fun EnumEncodedValue.toMutable(): MutableEnumEncodedValue = MutableEnumEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableFieldEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue.kt similarity index 77% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableFieldEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue.kt index e56451d..14d1144 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableFieldEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableFieldEncodedValue.kt @@ -1,23 +1,20 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.ValueType import com.android.tools.smali.dexlib2.base.value.BaseFieldEncodedValue import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.value.FieldEncodedValue -class MutableFieldEncodedValue(fieldEncodedValue: FieldEncodedValue) : - BaseFieldEncodedValue(), - MutableEncodedValue { +class MutableFieldEncodedValue(fieldEncodedValue: FieldEncodedValue) : BaseFieldEncodedValue(), MutableEncodedValue { private var value = fieldEncodedValue.value - override fun getValueType(): Int = ValueType.FIELD - - override fun getValue(): FieldReference = this.value - fun setValue(value: FieldReference) { this.value = value } + override fun getValueType(): Int = ValueType.FIELD + + override fun getValue(): FieldReference = this.value + companion object { fun FieldEncodedValue.toMutable(): MutableFieldEncodedValue = MutableFieldEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableFloatEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue.kt similarity index 70% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableFloatEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue.kt index 5028ff1..9d23b6b 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableFloatEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableFloatEncodedValue.kt @@ -1,19 +1,16 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseFloatEncodedValue -import com.android.tools.smali.dexlib2.iface.value.FloatEncodedValue -class MutableFloatEncodedValue(floatEncodedValue: FloatEncodedValue) : - BaseFloatEncodedValue(), - MutableEncodedValue { +class MutableFloatEncodedValue(floatEncodedValue: FloatEncodedValue) : BaseFloatEncodedValue(), MutableEncodedValue { private var value = floatEncodedValue.value - override fun getValue(): Float = this.value - fun setValue(value: Float) { this.value = value } + override fun getValue(): Float = this.value + companion object { fun FloatEncodedValue.toMutable(): MutableFloatEncodedValue = MutableFloatEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableIntEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue.kt similarity index 70% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableIntEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue.kt index 67fad3f..e035b1f 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableIntEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableIntEncodedValue.kt @@ -1,19 +1,16 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseIntEncodedValue -import com.android.tools.smali.dexlib2.iface.value.IntEncodedValue -class MutableIntEncodedValue(intEncodedValue: IntEncodedValue) : - BaseIntEncodedValue(), - MutableEncodedValue { +class MutableIntEncodedValue(intEncodedValue: IntEncodedValue) : BaseIntEncodedValue(), MutableEncodedValue { private var value = intEncodedValue.value - override fun getValue(): Int = this.value - fun setValue(value: Int) { this.value = value } + override fun getValue(): Int = this.value + companion object { fun IntEncodedValue.toMutable(): MutableIntEncodedValue = MutableIntEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableLongEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue.kt similarity index 70% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableLongEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue.kt index 2db7a00..04953ff 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableLongEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableLongEncodedValue.kt @@ -1,19 +1,16 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseLongEncodedValue -import com.android.tools.smali.dexlib2.iface.value.LongEncodedValue -class MutableLongEncodedValue(longEncodedValue: LongEncodedValue) : - BaseLongEncodedValue(), - MutableEncodedValue { +class MutableLongEncodedValue(longEncodedValue: LongEncodedValue) : BaseLongEncodedValue(), MutableEncodedValue { private var value = longEncodedValue.value - override fun getValue(): Long = this.value - fun setValue(value: Long) { this.value = value } + override fun getValue(): Long = this.value + companion object { fun LongEncodedValue.toMutable(): MutableLongEncodedValue = MutableLongEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue.kt similarity index 82% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue.kt index 4addacf..b0aa267 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodEncodedValue.kt @@ -1,20 +1,19 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseMethodEncodedValue import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.iface.value.MethodEncodedValue class MutableMethodEncodedValue(methodEncodedValue: MethodEncodedValue) : BaseMethodEncodedValue(), MutableEncodedValue { private var value = methodEncodedValue.value - override fun getValue(): MethodReference = this.value - fun setValue(value: MethodReference) { this.value = value } + override fun getValue(): MethodReference = this.value + companion object { fun MethodEncodedValue.toMutable(): MutableMethodEncodedValue = MutableMethodEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodHandleEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue.kt similarity index 83% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodHandleEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue.kt index 7c06402..1899b3c 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodHandleEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodHandleEncodedValue.kt @@ -1,20 +1,19 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseMethodHandleEncodedValue import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference -import com.android.tools.smali.dexlib2.iface.value.MethodHandleEncodedValue class MutableMethodHandleEncodedValue(methodHandleEncodedValue: MethodHandleEncodedValue) : BaseMethodHandleEncodedValue(), MutableEncodedValue { private var value = methodHandleEncodedValue.value - override fun getValue(): MethodHandleReference = this.value - fun setValue(value: MethodHandleReference) { this.value = value } + override fun getValue(): MethodHandleReference = this.value + companion object { fun MethodHandleEncodedValue.toMutable(): MutableMethodHandleEncodedValue = MutableMethodHandleEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodTypeEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue.kt similarity index 72% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodTypeEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue.kt index 4ecec51..57e1124 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableMethodTypeEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableMethodTypeEncodedValue.kt @@ -1,20 +1,17 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseMethodTypeEncodedValue import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference -import com.android.tools.smali.dexlib2.iface.value.MethodTypeEncodedValue -class MutableMethodTypeEncodedValue(methodTypeEncodedValue: MethodTypeEncodedValue) : - BaseMethodTypeEncodedValue(), - MutableEncodedValue { +class MutableMethodTypeEncodedValue(methodTypeEncodedValue: MethodTypeEncodedValue) : BaseMethodTypeEncodedValue(), MutableEncodedValue { private var value = methodTypeEncodedValue.value - override fun getValue(): MethodProtoReference = this.value - fun setValue(value: MethodProtoReference) { this.value = value } + override fun getValue(): MethodProtoReference = this.value + companion object { fun MethodTypeEncodedValue.toMutable(): MutableMethodTypeEncodedValue = MutableMethodTypeEncodedValue(this) } diff --git a/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue.kt new file mode 100644 index 0000000..e600c2a --- /dev/null +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableNullEncodedValue.kt @@ -0,0 +1,9 @@ +package com.android.tools.smali.dexlib2.iface.value + +import com.android.tools.smali.dexlib2.base.value.BaseNullEncodedValue + +class MutableNullEncodedValue : BaseNullEncodedValue(), MutableEncodedValue { + companion object { + fun ByteEncodedValue.toMutable(): MutableByteEncodedValue = MutableByteEncodedValue(this) + } +} diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableShortEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue.kt similarity index 80% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableShortEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue.kt index 3090778..740bcf7 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableShortEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableShortEncodedValue.kt @@ -1,19 +1,18 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseShortEncodedValue -import com.android.tools.smali.dexlib2.iface.value.ShortEncodedValue class MutableShortEncodedValue(shortEncodedValue: ShortEncodedValue) : BaseShortEncodedValue(), MutableEncodedValue { private var value = shortEncodedValue.value - override fun getValue(): Short = this.value - fun setValue(value: Short) { this.value = value } + override fun getValue(): Short = this.value + companion object { fun ShortEncodedValue.toMutable(): MutableShortEncodedValue = MutableShortEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableStringEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue.kt similarity index 72% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableStringEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue.kt index 001c60e..052e934 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableStringEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableStringEncodedValue.kt @@ -1,20 +1,18 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseStringEncodedValue -import com.android.tools.smali.dexlib2.iface.value.ByteEncodedValue -import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue class MutableStringEncodedValue(stringEncodedValue: StringEncodedValue) : BaseStringEncodedValue(), MutableEncodedValue { private var value = stringEncodedValue.value - override fun getValue(): String = this.value - fun setValue(value: String) { this.value = value } + override fun getValue(): String = this.value + companion object { fun ByteEncodedValue.toMutable(): MutableByteEncodedValue = MutableByteEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableTypeEncodedValue.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue.kt similarity index 62% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableTypeEncodedValue.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue.kt index c058926..ddf1436 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableTypeEncodedValue.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/iface/value/MutableTypeEncodedValue.kt @@ -1,19 +1,16 @@ -package app.revanced.patcher.dex.mutable.encodedValue +package com.android.tools.smali.dexlib2.iface.value import com.android.tools.smali.dexlib2.base.value.BaseTypeEncodedValue -import com.android.tools.smali.dexlib2.iface.value.TypeEncodedValue -class MutableTypeEncodedValue(typeEncodedValue: TypeEncodedValue) : - BaseTypeEncodedValue(), - MutableEncodedValue { +class MutableTypeEncodedValue(typeEncodedValue: TypeEncodedValue) : BaseTypeEncodedValue(), MutableEncodedValue { private var value = typeEncodedValue.value - override fun getValue(): String = this.value - fun setValue(value: String) { this.value = value } + override fun getValue() = this.value + companion object { fun TypeEncodedValue.toMutable(): MutableTypeEncodedValue = MutableTypeEncodedValue(this) } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableAnnotation.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableAnnotation.kt similarity index 52% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/MutableAnnotation.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableAnnotation.kt index fc4228e..703d3cc 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableAnnotation.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableAnnotation.kt @@ -1,21 +1,21 @@ -package app.revanced.patcher.dex.mutable +package com.android.tools.smali.dexlib2.mutable -import app.revanced.patcher.dex.mutable.MutableAnnotationElement.Companion.toMutable import com.android.tools.smali.dexlib2.base.BaseAnnotation import com.android.tools.smali.dexlib2.iface.Annotation +import com.android.tools.smali.dexlib2.mutable.MutableAnnotationElement.Companion.toMutable class MutableAnnotation(annotation: Annotation) : BaseAnnotation() { private val visibility = annotation.visibility private val type = annotation.type private val _elements by lazy { annotation.elements.map { element -> element.toMutable() }.toMutableSet() } - override fun getType(): String = type + override fun getType() = type - override fun getElements(): MutableSet = _elements + override fun getElements() = _elements - override fun getVisibility(): Int = visibility + override fun getVisibility() = visibility companion object { - fun Annotation.toMutable(): MutableAnnotation = MutableAnnotation(this) + fun Annotation.toMutable() = MutableAnnotation(this) } } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableAnnotationElement.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableAnnotationElement.kt similarity index 52% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/MutableAnnotationElement.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableAnnotationElement.kt index 08cbb4b..59076a7 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableAnnotationElement.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableAnnotationElement.kt @@ -1,10 +1,9 @@ -package app.revanced.patcher.dex.mutable +package com.android.tools.smali.dexlib2.mutable -import app.revanced.patcher.dex.mutable.encodedValue.MutableEncodedValue -import app.revanced.patcher.dex.mutable.encodedValue.MutableEncodedValue.Companion.toMutable import com.android.tools.smali.dexlib2.base.BaseAnnotationElement import com.android.tools.smali.dexlib2.iface.AnnotationElement -import com.android.tools.smali.dexlib2.iface.value.EncodedValue +import com.android.tools.smali.dexlib2.iface.value.MutableEncodedValue +import com.android.tools.smali.dexlib2.iface.value.MutableEncodedValue.Companion.toMutable class MutableAnnotationElement(annotationElement: AnnotationElement) : BaseAnnotationElement() { private var name = annotationElement.name @@ -18,11 +17,11 @@ class MutableAnnotationElement(annotationElement: AnnotationElement) : BaseAnnot this.value = value } - override fun getName(): String = name + override fun getName() = name - override fun getValue(): EncodedValue = value + override fun getValue() = value companion object { - fun AnnotationElement.toMutable(): MutableAnnotationElement = MutableAnnotationElement(this) + fun AnnotationElement.toMutable() = MutableAnnotationElement(this) } } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableClassDef.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableClassDef.kt similarity index 52% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/MutableClassDef.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableClassDef.kt index 8587e3c..77d5354 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableClassDef.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableClassDef.kt @@ -1,16 +1,14 @@ -package app.revanced.patcher.dex.mutable +package com.android.tools.smali.dexlib2.mutable -import app.revanced.patcher.dex.mutable.MutableAnnotation.Companion.toMutable -import app.revanced.patcher.dex.mutable.MutableField.Companion.toMutable -import app.revanced.patcher.dex.mutable.MutableMethod.Companion.toMutable import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference import com.android.tools.smali.dexlib2.iface.ClassDef +import com.android.tools.smali.dexlib2.mutable.MutableAnnotation.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableField.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable import com.android.tools.smali.dexlib2.util.FieldUtil import com.android.tools.smali.dexlib2.util.MethodUtil -class MutableClassDef(classDef: ClassDef) : - BaseTypeReference(), - ClassDef { +class MutableClassDef(classDef: ClassDef) : BaseTypeReference(), ClassDef { // Class private var type = classDef.type private var sourceFile = classDef.sourceFile @@ -24,8 +22,8 @@ class MutableClassDef(classDef: ClassDef) : // Methods private val _methods by lazy { classDef.methods.map { method -> method.toMutable() }.toMutableSet() } - private val _directMethods by lazy { _methods.filter { method -> MethodUtil.isDirect(method) }.toMutableSet() } - private val _virtualMethods by lazy { _methods.filter { method -> !MethodUtil.isDirect(method) }.toMutableSet() } + private val _directMethods by lazy { methods.filter { method -> MethodUtil.isDirect(method) }.toMutableSet() } + private val _virtualMethods by lazy { methods.filter { method -> !MethodUtil.isDirect(method) }.toMutableSet() } // Fields private val _fields by lazy { classDef.fields.map { field -> field.toMutable() }.toMutableSet() } @@ -48,29 +46,29 @@ class MutableClassDef(classDef: ClassDef) : this.superclass = superclass } - override fun getType(): String = type + override fun getType() = type - override fun getAccessFlags(): Int = accessFlags + override fun getAccessFlags() = accessFlags - override fun getSourceFile(): String? = sourceFile + override fun getSourceFile() = sourceFile - override fun getSuperclass(): String? = superclass + override fun getSuperclass() = superclass - override fun getInterfaces(): MutableList = _interfaces + override fun getInterfaces() = _interfaces - override fun getAnnotations(): MutableSet = _annotations + override fun getAnnotations() = _annotations - override fun getStaticFields(): MutableSet = _staticFields + override fun getStaticFields() = _staticFields - override fun getInstanceFields(): MutableSet = _instanceFields + override fun getInstanceFields() = _instanceFields - override fun getFields(): MutableSet = _fields + override fun getFields() = _fields - override fun getDirectMethods(): MutableSet = _directMethods + override fun getDirectMethods() = _directMethods - override fun getVirtualMethods(): MutableSet = _virtualMethods + override fun getVirtualMethods() = _virtualMethods - override fun getMethods(): MutableSet = _methods + override fun getMethods() = _methods companion object { fun ClassDef.toMutable(): MutableClassDef = MutableClassDef(this) diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableField.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableField.kt similarity index 51% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/MutableField.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableField.kt index 22d9014..6354912 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableField.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableField.kt @@ -1,15 +1,12 @@ -package app.revanced.patcher.dex.mutable +package com.android.tools.smali.dexlib2.mutable -import app.revanced.patcher.dex.mutable.MutableAnnotation.Companion.toMutable -import app.revanced.patcher.dex.mutable.encodedValue.MutableEncodedValue -import app.revanced.patcher.dex.mutable.encodedValue.MutableEncodedValue.Companion.toMutable -import com.android.tools.smali.dexlib2.HiddenApiRestriction import com.android.tools.smali.dexlib2.base.reference.BaseFieldReference import com.android.tools.smali.dexlib2.iface.Field +import com.android.tools.smali.dexlib2.iface.value.MutableEncodedValue +import com.android.tools.smali.dexlib2.iface.value.MutableEncodedValue.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableAnnotation.Companion.toMutable -class MutableField(field: Field) : - BaseFieldReference(), - Field { +class MutableField(field: Field) : BaseFieldReference(), Field { private var definingClass = field.definingClass private var name = field.name private var type = field.type @@ -39,21 +36,21 @@ class MutableField(field: Field) : this.initialValue = initialValue } - override fun getDefiningClass(): String = this.definingClass + override fun getDefiningClass() = this.definingClass - override fun getName(): String = this.name + override fun getName() = this.name - override fun getType(): String = this.type + override fun getType() = this.type - override fun getAnnotations(): MutableSet = this._annotations + override fun getAnnotations() = this._annotations - override fun getAccessFlags(): Int = this.accessFlags + override fun getAccessFlags() = this.accessFlags - override fun getHiddenApiRestrictions(): MutableSet = this._hiddenApiRestrictions + override fun getHiddenApiRestrictions() = this._hiddenApiRestrictions - override fun getInitialValue(): MutableEncodedValue? = this.initialValue + override fun getInitialValue() = this.initialValue companion object { - fun Field.toMutable(): MutableField = MutableField(this) + fun Field.toMutable() = MutableField(this) } } diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableMethod.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableMethod.kt similarity index 52% rename from src/main/kotlin/app/revanced/patcher/dex/mutable/MutableMethod.kt rename to core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableMethod.kt index 00fdeb5..f6dd23b 100644 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableMethod.kt +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableMethod.kt @@ -1,21 +1,18 @@ -package app.revanced.patcher.dex.mutable +package com.android.tools.smali.dexlib2.mutable -import app.revanced.patcher.dex.mutable.MutableAnnotation.Companion.toMutable -import app.revanced.patcher.dex.mutable.MutableMethodParameter.Companion.toMutable -import com.android.tools.smali.dexlib2.HiddenApiRestriction import com.android.tools.smali.dexlib2.base.reference.BaseMethodReference import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.mutable.MutableAnnotation.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableMethodParameter.Companion.toMutable -class MutableMethod(method: Method) : - BaseMethodReference(), - Method { +class MutableMethod(method: Method) : BaseMethodReference(), Method { private var definingClass = method.definingClass private var name = method.name private var accessFlags = method.accessFlags private var returnType = method.returnType - // Create own mutable MethodImplementation (due to not being able to change members like register count) + // TODO: Create own mutable MethodImplementation (due to not being able to change members like register count) private val _implementation by lazy { method.implementation?.let { MutableMethodImplementation(it) } } private val _annotations by lazy { method.annotations.map { annotation -> annotation.toMutable() }.toMutableSet() } private val _parameters by lazy { method.parameters.map { parameter -> parameter.toMutable() }.toMutableList() } @@ -38,25 +35,25 @@ class MutableMethod(method: Method) : this.returnType = returnType } - override fun getDefiningClass(): String = definingClass + override fun getDefiningClass() = definingClass - override fun getName(): String = name + override fun getName() = name - override fun getParameterTypes(): MutableList = _parameterTypes + override fun getParameterTypes() = _parameterTypes - override fun getReturnType(): String = returnType + override fun getReturnType() = returnType - override fun getAnnotations(): MutableSet = _annotations + override fun getAnnotations() = _annotations - override fun getAccessFlags(): Int = accessFlags + override fun getAccessFlags() = accessFlags - override fun getHiddenApiRestrictions(): MutableSet = _hiddenApiRestrictions + override fun getHiddenApiRestrictions() = _hiddenApiRestrictions - override fun getParameters(): MutableList = _parameters + override fun getParameters() = _parameters - override fun getImplementation(): MutableMethodImplementation? = _implementation + override fun getImplementation() = _implementation companion object { - fun Method.toMutable(): MutableMethod = MutableMethod(this) + fun Method.toMutable() = MutableMethod(this) } } diff --git a/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableMethodParameter.kt b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableMethodParameter.kt new file mode 100644 index 0000000..4540b1c --- /dev/null +++ b/core/src/commonMain/kotlin/com/android/tools/smali/dexlib2/mutable/MutableMethodParameter.kt @@ -0,0 +1,26 @@ +package com.android.tools.smali.dexlib2.mutable + +import com.android.tools.smali.dexlib2.base.BaseMethodParameter +import com.android.tools.smali.dexlib2.iface.MethodParameter +import com.android.tools.smali.dexlib2.mutable.MutableAnnotation.Companion.toMutable + +class MutableMethodParameter(parameter: MethodParameter) : BaseMethodParameter(), MethodParameter { + private var type = parameter.type + private var name = parameter.name + private var signature = parameter.signature + private val _annotations by lazy { + parameter.annotations.map { annotation -> annotation.toMutable() }.toMutableSet() + } + + override fun getType() = type + + override fun getName() = name + + override fun getSignature() = signature + + override fun getAnnotations() = _annotations + + companion object { + fun MethodParameter.toMutable() = MutableMethodParameter(this) + } +} diff --git a/core/src/commonMain/kotlin/java/io/File.kt b/core/src/commonMain/kotlin/java/io/File.kt new file mode 100644 index 0000000..8669495 --- /dev/null +++ b/core/src/commonMain/kotlin/java/io/File.kt @@ -0,0 +1,17 @@ +package java.io + +internal expect fun File.kmpResolve(child: String): File + +internal fun File.resolve(child: String) = kmpResolve(child) + +internal expect fun File.kmpDeleteRecursively(): Boolean + +internal fun File.deleteRecursively() = kmpDeleteRecursively() + +internal expect fun File.kmpInputStream(): InputStream + +internal fun File.inputStream() = kmpInputStream() + +internal expect fun File.kmpBufferedWriter(charset: java.nio.charset.Charset): BufferedWriter + +internal fun File.bufferedWriter(charset: java.nio.charset.Charset) = kmpBufferedWriter(charset) \ No newline at end of file diff --git a/core/src/jvmMain/kotlin/app/revanced/patcher/patch/Patch.jvm.kt b/core/src/jvmMain/kotlin/app/revanced/patcher/patch/Patch.jvm.kt new file mode 100644 index 0000000..0c7ffe8 --- /dev/null +++ b/core/src/jvmMain/kotlin/app/revanced/patcher/patch/Patch.jvm.kt @@ -0,0 +1,26 @@ +package app.revanced.patcher.patch + +import java.io.File +import java.net.URLClassLoader +import java.util.function.Predicate +import java.util.jar.JarFile + +actual val Class<*>.isPatch get() = Patch::class.java.isAssignableFrom(this) + +/** + * Loads patches from JAR files declared as public static fields + * or returned by public static and non-parametrized methods. + * Patches with no name are not loaded. + * + * @param patchesFiles The JAR files to load the patches from. + * + * @return The loaded patches. + */ +actual fun loadPatches(patchesFiles: Set) = loadPatches( + patchesFiles, + { file -> + JarFile(file).entries().toList().filter { it.name.endsWith(".class") } + .map { it.name.substringBeforeLast('.').replace('/', '.') } + }, + URLClassLoader(patchesFiles.map { it.toURI().toURL() }.toTypedArray()), +) diff --git a/core/src/jvmMain/kotlin/collections/MutableMap.jvm.kt b/core/src/jvmMain/kotlin/collections/MutableMap.jvm.kt new file mode 100644 index 0000000..4068c22 --- /dev/null +++ b/core/src/jvmMain/kotlin/collections/MutableMap.jvm.kt @@ -0,0 +1,7 @@ +package collections + +internal actual fun MutableMap.kmpMerge( + key: K, + value: V, + remappingFunction: (oldValue: V, newValue: V) -> V +) = merge(key, value, remappingFunction) \ No newline at end of file diff --git a/core/src/jvmMain/kotlin/java/io/File.jvm.kt b/core/src/jvmMain/kotlin/java/io/File.jvm.kt new file mode 100644 index 0000000..2772efc --- /dev/null +++ b/core/src/jvmMain/kotlin/java/io/File.jvm.kt @@ -0,0 +1,9 @@ +package java.io + +import java.nio.charset.Charset + + +internal actual fun File.kmpResolve(child: String) = resolve(child) +internal actual fun File.kmpDeleteRecursively() = deleteRecursively() +internal actual fun File.kmpInputStream() = inputStream() +internal actual fun File.kmpBufferedWriter(charset: Charset) = bufferedWriter(charset) \ No newline at end of file diff --git a/src/test/kotlin/app/revanced/patcher/ExtensionsTest.kt b/core/src/jvmTest/kotlin/app/revanced/patcher/ExtensionsTest.kt similarity index 98% rename from src/test/kotlin/app/revanced/patcher/ExtensionsTest.kt rename to core/src/jvmTest/kotlin/app/revanced/patcher/ExtensionsTest.kt index d665f1c..57e0ba9 100644 --- a/src/test/kotlin/app/revanced/patcher/ExtensionsTest.kt +++ b/core/src/jvmTest/kotlin/app/revanced/patcher/ExtensionsTest.kt @@ -1,7 +1,7 @@ package app.revanced.patcher -import app.revanced.patcher.dex.mutable.MutableMethod -import app.revanced.patcher.dex.mutable.MutableMethod.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableMethod +import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable import app.revanced.patcher.extensions.* import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode diff --git a/src/test/kotlin/app/revanced/patcher/PatcherTest.kt b/core/src/jvmTest/kotlin/app/revanced/patcher/PatcherTest.kt similarity index 67% rename from src/test/kotlin/app/revanced/patcher/PatcherTest.kt rename to core/src/jvmTest/kotlin/app/revanced/patcher/PatcherTest.kt index e2db339..c64d761 100644 --- a/src/test/kotlin/app/revanced/patcher/PatcherTest.kt +++ b/core/src/jvmTest/kotlin/app/revanced/patcher/PatcherTest.kt @@ -3,17 +3,23 @@ package app.revanced.patcher import app.revanced.patcher.extensions.toInstructions import app.revanced.patcher.patch.* import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.ClassDef +import com.android.tools.smali.dexlib2.Opcodes +import com.android.tools.smali.dexlib2.iface.DexFile +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.immutable.ImmutableClassDef import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodImplementation import io.mockk.every import io.mockk.just import io.mockk.mockk +import io.mockk.mockkStatic import io.mockk.runs +import io.mockk.spyk import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.BeforeEach +import lanchon.multidexlib2.MultiDexIO +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.assertAll import org.junit.jupiter.api.assertThrows import java.util.logging.Logger @@ -21,11 +27,14 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertNotNull +import kotlin.test.assertNull internal object PatcherTest { private lateinit var patcher: Patcher + private lateinit var patcherContext: PatcherContext - @BeforeEach + @JvmStatic + @BeforeAll fun setUp() { patcher = mockk { // Can't mock private fields, until https://github.com/mockk/mockk/issues/1244 is resolved. @@ -40,9 +49,73 @@ internal object PatcherTest { Logger.getAnonymousLogger(), ) - every { context.bytecodeContext.classDefs } returns mockk(relaxed = true) every { this@mockk() } answers { callOriginal() } } + + val classDefs = mutableSetOf( + ImmutableClassDef( + "class", + 0, + null, + null, + null, + null, + null, + listOf( + ImmutableMethod( + "class", + "method", + emptyList(), + "V", + 0, + null, + null, + ImmutableMethodImplementation( + 2, + """ + const-string v0, "Hello, World!" + iput-object v0, p0, Ljava/lang/System;->out:Ljava/io/PrintStream; + iget-object v0, p0, Ljava/lang/System;->out:Ljava/io/PrintStream; + return-void + const-string v0, "This is a test." + return-object v0 + invoke-virtual { p0, v0 }, Ljava/io/PrintStream;->println(Ljava/lang/String;)V + invoke-static { p0 }, Ljava/lang/System;->currentTimeMillis()J + check-cast p0, Ljava/io/PrintStream; + """.toInstructions(), + null, + null + ), + ), + ), + ) + ) + + patcherContext = mockk { + every { bytecodeContext } returns mockk context@{ + every { config } returns mockk { + every { apkFile } returns mockk() + } + + mockkStatic(MultiDexIO::readDexFile) + every { + MultiDexIO.readDexFile( + any(), + any(), + any(), + any(), + any() + ) + } returns mockk { + every { classes } returns classDefs + every { opcodes } returns Opcodes.getDefault() + } + every { this@context.classDefs } returns ClassDefs().apply { initializeCache() } + every { mergeExtension(any()) } just runs + } + } + + every { patcher.context } returns patcherContext } @Test @@ -156,11 +229,13 @@ internal object PatcherTest { } @Test - fun `throws if unmatched fingerprint match is delegated`() { + fun `throws if unmatched fingerprint match is used`() { val patch = bytecodePatch { execute { // Fingerprint can never match. - val fingerprint = fingerprint { } + val fingerprint = fingerprint { + strings("doesnt exist") + } // Throws, because the fingerprint can't be matched. fingerprint.patternMatch @@ -175,14 +250,16 @@ internal object PatcherTest { val iterable = (1..10).toList() val matcher = indexedMatcher() - matcher.apply { head { this > 5 } } + matcher.apply { + +head { this > 5 } + } assertFalse( matcher(iterable), "Should not match at any other index than first" ) matcher.clear() - matcher.apply { head { this == 1 } }(iterable) + matcher.apply { +head { this == 1 } }(iterable) assertEquals( listOf(0), matcher.indices, @@ -190,11 +267,11 @@ internal object PatcherTest { ) matcher.clear() - matcher.apply { add { this > 0 } }(iterable) + matcher.apply { add { _, _ -> this > 0 } }(iterable) assertEquals(1, matcher.indices.size, "Should only match once.") matcher.clear() - matcher.apply { add { this == 2 } }(iterable) + matcher.apply { add { _, _ -> this == 2 } }(iterable) assertEquals( listOf(1), matcher.indices, @@ -203,9 +280,9 @@ internal object PatcherTest { matcher.clear() matcher.apply { - head { this == 1 } - add { this == 2 } - add { this == 4 } + +head { this == 1 } + add { _, _ -> this == 2 } + add { _, _ -> this == 4 } }(iterable) assertEquals( listOf(0, 1, 3), @@ -215,7 +292,7 @@ internal object PatcherTest { matcher.clear() matcher.apply { - after { this == 1 } + +after { this == 1 } }(iterable) assertEquals( listOf(0), @@ -225,7 +302,7 @@ internal object PatcherTest { matcher.clear() matcher.apply { - after(2..Int.MAX_VALUE) { this == 1 } + +after(2..Int.MAX_VALUE) { this == 1 } } assertFalse( matcher(iterable), @@ -234,7 +311,7 @@ internal object PatcherTest { matcher.clear() matcher.apply { - after(1..1) { this == 2 } + +after(1..1) { this == 2 } } assertFalse( matcher(iterable), @@ -243,10 +320,10 @@ internal object PatcherTest { matcher.clear() matcher.apply { - head { this == 1 } - after(2..5) { this == 4 } - add { this == 8 } - add { this == 9 } + +head { this == 1 } + +after(2..5) { this == 4 } + add { _, _ -> this == 8 } + add { _, _ -> this == 9 } }(iterable) assertEquals( listOf(0, 3, 7, 8), @@ -256,93 +333,55 @@ internal object PatcherTest { } @Test - fun `matches fingerprint`() { - every { patcher.context.bytecodeContext.classDefs } returns mutableSetOf( - ImmutableClassDef( - "class", - 0, - null, - null, - null, - null, - null, - listOf( - ImmutableMethod( - "class", - "method", - emptyList(), - "V", - 0, - null, - null, - ImmutableMethodImplementation( - 2, - """ - const-string v0, "Hello, World!" - iput-object v0, p0, Ljava/lang/System;->out:Ljava/io/PrintStream; - iget-object v0, p0, Ljava/lang/System;->out:Ljava/io/PrintStream; - return-void - const-string v0, "This is a test." - return-object v0 - invoke-virtual { p0, v0 }, Ljava/io/PrintStream;->println(Ljava/lang/String;)V - invoke-static { p0 }, Ljava/lang/System;->currentTimeMillis()J - check-cast p0, Ljava/io/PrintStream; - """.toInstructions(), - null, - null - ), - ), - ), - ), - ) - every { - with(patcher.context.bytecodeContext) { - any(ClassDef::class).mutable() + fun `matches via composite`() { + fun composite(fail: Boolean = false) = firstMethodComposite { + name("method") + definingClass("class") + + if (fail) returnType("doesnt exist") + + instructions( + head(Opcode.CONST_STRING()), + `is`(), + noneOf(registers()), + string("test", String::contains), + after(1..3, allOf(Opcode.INVOKE_VIRTUAL(), registers(1, 0))), + allOf(), + type("PrintStream;", String::endsWith) + ) + } + + with(patcher.context.bytecodeContext) { + assertNotNull(composite().methodOrNull) { + "Expected to find a method matching the composite fingerprint." } - } answers { callOriginal() } - - val a = gettingFirstMethodOrNull { true } + assertNull(composite(fail = true).methodOrNull) { + "Expected to not find a method matching the composite fingerprint." + } + } + } + @Test + fun `matches fingerprint`() { val fingerprint = fingerprint { returns("V") } val fingerprint2 = fingerprint { returns("V") } val fingerprint3 = fingerprint { returns("V") } - val composite = firstMethodComposite { - instructions { - head { opcode == Opcode.CONST_STRING } - add { opcode == Opcode.IPUT_OBJECT } - } - } - - val patches = setOf( - bytecodePatch { - execute { - fingerprint.match(classDefs.first().methods.first()) - fingerprint2.match(classDefs.first()) - fingerprint3.originalClassDef - composite.method - } - }, - ) - - patches() - - with(patcher.context.bytecodeContext) - { + with(patcher.context.bytecodeContext) { assertAll( "Expected fingerprints to match.", - { assertNotNull(fingerprint.originalClassDefOrNull) }, - { assertNotNull(fingerprint2.originalClassDefOrNull) }, + { assertNotNull(fingerprint.matchOrNull(this.classDefs.first().methods.first())) }, + { assertNotNull(fingerprint2.matchOrNull(this.classDefs.first())) }, { assertNotNull(fingerprint3.originalClassDefOrNull) }, - { assertEquals("method", composite.method.name) }, ) } } private operator fun Set>.invoke(): List { - every { patcher.context.executablePatches } returns toMutableSet() - every { patcher.context.bytecodeContext.lookupMaps } returns with(patcher.context.bytecodeContext) { LookupMaps() } - every { with(patcher.context.bytecodeContext) { mergeExtension(any()) } } just runs + // TODO: Ideally most of this mocking could be moved to setUp, + // but by doing so the mocking breaks and it is not clear why. + + every { patcherContext.executablePatches } returns toMutableSet() return runBlocking { patcher().toList().also { results -> diff --git a/src/test/kotlin/app/revanced/patcher/patch/PatchLoaderTest.kt b/core/src/jvmTest/kotlin/app/revanced/patcher/patch/PatchLoaderTest.kt similarity index 52% rename from src/test/kotlin/app/revanced/patcher/patch/PatchLoaderTest.kt rename to core/src/jvmTest/kotlin/app/revanced/patcher/patch/PatchLoaderTest.kt index 8f90fef..fd79b00 100644 --- a/src/test/kotlin/app/revanced/patcher/patch/PatchLoaderTest.kt +++ b/core/src/jvmTest/kotlin/app/revanced/patcher/patch/PatchLoaderTest.kt @@ -2,6 +2,7 @@ package app.revanced.patcher.patch +import io.mockk.mockk import org.junit.jupiter.api.Test import java.io.File import kotlin.reflect.KFunction @@ -47,44 +48,23 @@ private fun privateNamedPatchFunction() = privatePatch // endregion internal object PatchLoaderTest { - private const val LOAD_PATCHES_FUNCTION_NAME = "loadPatches" private val TEST_PATCHES_CLASS = ::publicPatch.javaField!!.declaringClass.name private val TEST_PATCHES_CLASS_LOADER = ::publicPatch.javaClass.classLoader @Test fun `loads patches correctly`() { - // Get instance of private PatchLoader.Companion class. - val patchLoaderCompanionObject = getPrivateFieldByType( - PatchLoader::class.java, - PatchLoader::class.companionObject!!.javaObjectType, + val patches = loadPatches( + setOf(mockk()), + { listOf(TEST_PATCHES_CLASS) }, + TEST_PATCHES_CLASS_LOADER ) - // Get private PatchLoader.Companion.loadPatches function from PatchLoader.Companion. - @Suppress("UNCHECKED_CAST") - val loadPatchesFunction = getPrivateFunctionByName( - patchLoaderCompanionObject, - LOAD_PATCHES_FUNCTION_NAME, - ) as KFunction>>> - - // Call private PatchLoader.Companion.loadPatches function. - val patches = loadPatchesFunction.call( - patchLoaderCompanionObject, - TEST_PATCHES_CLASS_LOADER, - mapOf(File("patchesFile") to setOf(TEST_PATCHES_CLASS)), - ).values.first() - assertEquals( 2, patches.size, "Expected 2 patches to be loaded, " + - "because there's only two named patches declared as public static fields " + - "or returned by public static and non-parametrized methods.", + "because there's only two named patches declared as public static fields " + + "or returned by public static and non-parametrized methods.", ) } - - private fun getPrivateFieldByType(cls: Class<*>, fieldType: Class<*>) = - cls.declaredFields.first { it.type == fieldType }.apply { isAccessible = true }.get(null) - - private fun getPrivateFunctionByName(obj: Any, @Suppress("SameParameterValue") methodName: String) = - obj::class.declaredFunctions.first { it.name == methodName }.apply { isAccessible = true } } diff --git a/src/test/kotlin/app/revanced/patcher/patch/PatchTest.kt b/core/src/jvmTest/kotlin/app/revanced/patcher/patch/PatchTest.kt similarity index 100% rename from src/test/kotlin/app/revanced/patcher/patch/PatchTest.kt rename to core/src/jvmTest/kotlin/app/revanced/patcher/patch/PatchTest.kt diff --git a/src/test/kotlin/app/revanced/patcher/patch/options/OptionsTest.kt b/core/src/jvmTest/kotlin/app/revanced/patcher/patch/options/OptionsTest.kt similarity index 100% rename from src/test/kotlin/app/revanced/patcher/patch/options/OptionsTest.kt rename to core/src/jvmTest/kotlin/app/revanced/patcher/patch/options/OptionsTest.kt diff --git a/src/test/kotlin/app/revanced/patcher/util/SmaliTest.kt b/core/src/jvmTest/kotlin/app/revanced/patcher/util/SmaliTest.kt similarity index 97% rename from src/test/kotlin/app/revanced/patcher/util/SmaliTest.kt rename to core/src/jvmTest/kotlin/app/revanced/patcher/util/SmaliTest.kt index acd88f0..41dfd5d 100644 --- a/src/test/kotlin/app/revanced/patcher/util/SmaliTest.kt +++ b/core/src/jvmTest/kotlin/app/revanced/patcher/util/SmaliTest.kt @@ -1,6 +1,6 @@ package app.revanced.patcher.util -import app.revanced.patcher.dex.mutable.MutableMethod.Companion.toMutable +import com.android.tools.smali.dexlib2.mutable.MutableMethod.Companion.toMutable import app.revanced.patcher.extensions.* import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode diff --git a/gradle.properties b/gradle.properties index 4ef4a41..3732b5a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,11 @@ -org.gradle.parallel = true -org.gradle.caching = true -version = 22.0.0 +version = 22.0.0-local +#Kotlin +kotlin.code.style=official +kotlin.daemon.jvmargs=-Xmx3072M +#Gradle +org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M" +org.gradle.caching=true +org.gradle.configuration-cache=true +#Android +android.nonTransitiveRClass=true +android.useAndroidX=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 93e58e4..4f6dfaf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,10 @@ + [versions] -android = "4.1.1.4" -apktool-lib = "2.10.1.1" -binary-compatibility-validator = "0.18.1" +agp = "8.12.3" +android-compileSdk = "36" +android-minSdk = "26" kotlin = "2.2.21" +apktool-lib = "2.10.1.1" kotlinx-coroutines-core = "1.10.2" mockk = "1.14.6" multidexlib2 = "3.0.3.r3" @@ -10,9 +12,9 @@ multidexlib2 = "3.0.3.r3" #noinspection GradleDependency smali = "3.0.9" xpp3 = "1.1.4c" +vanniktechMavenPublish = "0.35.0" [libraries] -android = { module = "com.google.android:android", version.ref = "android" } apktool-lib = { module = "app.revanced:apktool-lib", version.ref = "apktool-lib" } kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" } @@ -23,5 +25,6 @@ smali = { module = "com.android.tools.smali:smali", version.ref = "smali" } xpp3 = { module = "xpp3:xpp3", version.ref = "xpp3" } [plugins] -binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" } -kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +android-kotlin-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } +kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } +vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktechMavenPublish" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c35211..f8e1ee3 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradlew b/gradlew index f5feea6..adff685 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -173,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -206,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9d21a21..c4bdd3a 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/settings.gradle.kts b/settings.gradle.kts index b4d1a12..9fe0d61 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1,24 @@ rootProject.name = "revanced-patcher" +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + +pluginManagement { + repositories { + mavenCentral() + google() + } +} + +dependencyResolutionManagement { + repositories { + mavenCentral() + google() + maven { + name = "githubPackages" + // A repository must be specified for some reason. "registry" is a dummy. + url = uri("https://maven.pkg.github.com/revanced/registry") + credentials(PasswordCredentials::class) + } + } +} + +include(":core") diff --git a/src/main/kotlin/app/revanced/patcher/Fingerprint.kt b/src/main/kotlin/app/revanced/patcher/Fingerprint.kt deleted file mode 100644 index dae502c..0000000 --- a/src/main/kotlin/app/revanced/patcher/Fingerprint.kt +++ /dev/null @@ -1,784 +0,0 @@ -@file:Suppress("unused", "MemberVisibilityCanBePrivate") - -package app.revanced.patcher - -import app.revanced.patcher.InstructionLocation.* -import app.revanced.patcher.Match.PatternMatch -import app.revanced.patcher.Matcher.MatchContext -import app.revanced.patcher.extensions.getInstruction -import app.revanced.patcher.extensions.instructionsOrNull -import app.revanced.patcher.extensions.opcode -import app.revanced.patcher.extensions.string -import app.revanced.patcher.extensions.stringReference -import app.revanced.patcher.patch.BytecodePatchContext -import app.revanced.patcher.patch.PatchException -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.ClassDef -import com.android.tools.smali.dexlib2.iface.Method -import com.android.tools.smali.dexlib2.iface.instruction.Instruction -import com.android.tools.smali.dexlib2.util.MethodUtil - -/** - * A fingerprint for a method. A fingerprint is a partial description of a method. - * It is used to uniquely match a method by its characteristics. - * - * An example fingerprint for a public method that takes a single string parameter and returns void: - * ``` - * fingerprint { - * accessFlags(AccessFlags.PUBLIC) - * returns("V") - * parameters("Ljava/lang/String;") - * } - * ``` - * - * @param accessFlags The exact access flags using values of [AccessFlags]. - * @param returnType The return type. Compared using [String.startsWith]. - * @param parameters The parameters. Partial matches allowed and follow the same rules as [returnType]. - * @param filters A list of filters to match, declared in the same order the instructions appear in the method. - * @param strings A list of the strings that appear anywhere in the method. Compared using [String.contains]. - * @param custom A custom condition for this fingerprint. - */ -class Fingerprint internal constructor( - internal val accessFlags: Int?, - internal val returnType: String?, - internal val parameters: List?, - internal val filters: List?, - @Deprecated("Instead use instruction filters") - internal val strings: List?, - internal val custom: ((method: Method, classDef: ClassDef) -> Boolean)?, -) { - // Backing field needed for lazy initialization. - private var _matchOrNull: Match? = null - - /** - * Clears the current match, forcing this fingerprint to resolve again. - * This method should only be used if this fingerprint is re-used after it's modified, - * and the prior match indexes are no longer correct. - */ - fun clearMatch() { - _matchOrNull = null - } - - /** - * The match for this [Fingerprint], or `null` if no matches exist. - */ - context(context: BytecodePatchContext) - fun matchOrNull(): Match? { - if (_matchOrNull != null) return _matchOrNull - - var stringMatches: List? = null - - val matchIndices = indexedMatcher() - - // This line is needed, because the method must be passed by reference to "matchIndices". - // Referencing the method directly would "hardcode" it in the cached pattern by value. - // By using this variable, the reference can be updated for each method. - lateinit var currentMethod: Method - - context(_: MatchContext) - fun Method.match(): Boolean { - if (this@Fingerprint.accessFlags != null && this@Fingerprint.accessFlags != accessFlags) - return false - - if (this@Fingerprint.returnType != null && !returnType.startsWith(this@Fingerprint.returnType)) - return false - - if (this@Fingerprint.parameters != null && !parametersStartsWith( - parameterTypes, - this@Fingerprint.parameters - ) - ) - return false - - if (custom != null && !custom(this, context.lookupMaps.classDefsByType[definingClass]!!)) - return false - - stringMatches = if (strings != null) { - val instructions = instructionsOrNull ?: return false - var stringsList: MutableList? = null - - buildList { - instructions.forEachIndexed { instructionIndex, instruction -> - if (stringsList == null) stringsList = strings.toMutableList() - - val string = instruction.stringReference?.string ?: return@forEachIndexed - val index = stringsList.indexOfFirst(string::contains) - if (index < 0) return@forEachIndexed - - add(Match.StringMatch(string, instructionIndex)) - stringsList.removeAt(index) - } - - if (stringsList == null || stringsList.isNotEmpty()) return false - } - - } else null - - currentMethod = this - return filters == null || matchIndices(instructionsOrNull ?: return false) { - filters.forEach { filter -> - val filterMatches: Instruction.() -> Boolean = { filter.matches(currentMethod, this) } - - when (val location = filter.location) { - is MatchAfterImmediately -> after { filterMatches() } - is MatchAfterWithin -> after(1..location.matchDistance) { filterMatches() } - is MatchAfterAnywhere -> add { filterMatches() } - is MatchAfterAtLeast -> after(location.minimumDistanceFromLastInstruction..Int.MAX_VALUE) { filterMatches() } - is MatchAfterRange -> after(location.minimumDistanceFromLastInstruction..location.maximumDistanceFromLastInstruction) { filterMatches() } - is MatchFirst -> head { filterMatches() } - } - } - } - } - - val allStrings = buildList { - if (filters != null) addAll( - (filters.filterIsInstance() + filters.filterIsInstance().flatMap { - it.filters.filterIsInstance() - }) - ) - }.map { it.stringValue } + (strings ?: emptyList()) - - val method = if (allStrings.isNotEmpty()) { - context.firstMethodOrNull(strings = allStrings.toTypedArray()) { match() } - ?: context(MatchContext()) { context.lookupMaps.methodsWithString.firstOrNull { it.match() } } - } else { - context.firstMethodOrNull { match() } - } ?: return null - - val instructionMatches = filters?.withIndex()?.map { (i, filter) -> - val matchIndex = matchIndices.indices[i] - - Match.InstructionMatch(filter, matchIndex, method.getInstruction(matchIndex)) - } - - _matchOrNull = Match( - context, - context.lookupMaps.classDefsByType[method.definingClass]!!, - method, - instructionMatches, - stringMatches, - ) - - return _matchOrNull - } - - /** - * Match using a [ClassDef]. - * - * @param classDef The class to match against. - * @return The [Match] if a match was found or if the - * fingerprint is already matched to a method, null otherwise. - */ - context(_: BytecodePatchContext) - fun matchOrNull( - classDef: ClassDef, - ): Match? { - if (_matchOrNull != null) return _matchOrNull - - for (method in classDef.methods) { - val match = matchOrNull(classDef, method) - if (match != null) { - _matchOrNull = match - return match - } - } - - return null - } - - /** - * Match using a [Method]. - * The class is retrieved from the method. - * - * @param method The method to match against. - * @return The [Match] if a match was found or if the fingerprint is previously matched to a method, - * otherwise `null`. - */ - context(context: BytecodePatchContext) - fun matchOrNull( - method: Method, - ): Match? { - if (_matchOrNull != null) return _matchOrNull - - return matchOrNull(context.lookupMaps.classDefsByType[method.definingClass]!!, method) - } - - /** - * Match using a [Method]. - * - * @param method The method to match against. - * @param classDef The class the method is a member of. - * @return The [Match] if a match was found or if the fingerprint is previously matched to a method, - * otherwise `null`. - */ - context(context: BytecodePatchContext) - fun matchOrNull( - classDef: ClassDef, - method: Method, - ): Match? { - if (_matchOrNull != null) return _matchOrNull - - var stringMatches: List? = null - - val matchIndices = indexedMatcher() - - context(_: MatchContext) - fun Method.match(): Boolean { - if (this@Fingerprint.accessFlags != null && this@Fingerprint.accessFlags != accessFlags) - return false - - if (this@Fingerprint.returnType != null && !returnType.startsWith(this@Fingerprint.returnType)) - return false - - if (this@Fingerprint.parameters != null && !parametersStartsWith( - parameterTypes, - this@Fingerprint.parameters - ) - ) - return false - - if (custom != null && !custom(this, classDef)) - return false - - stringMatches = if (strings != null) { - val instructions = instructionsOrNull ?: return false - var stringsList: MutableList? = null - - buildList { - instructions.forEachIndexed { instructionIndex, instruction -> - if (stringsList == null) stringsList = strings.toMutableList() - - val string = instruction.stringReference?.string ?: return@forEachIndexed - val index = stringsList.indexOfFirst(string::contains) - if (index < 0) return@forEachIndexed - - add(Match.StringMatch(string, instructionIndex)) - stringsList.removeAt(index) - } - - if (stringsList == null || stringsList.isNotEmpty()) return false - } - - } else null - - return filters == null || matchIndices(instructionsOrNull ?: return false) { - filters.forEach { filter -> - val filterMatches: Instruction.() -> Boolean = { filter.matches(method, this) } - - when (val location = filter.location) { - is MatchAfterImmediately -> after { filterMatches() } - is MatchAfterWithin -> after(1..location.matchDistance) { filterMatches() } - is MatchAfterAnywhere -> add { filterMatches() } - is MatchAfterAtLeast -> after(location.minimumDistanceFromLastInstruction..Int.MAX_VALUE) { filterMatches() } - is MatchAfterRange -> after(location.minimumDistanceFromLastInstruction..location.maximumDistanceFromLastInstruction) { filterMatches() } - is MatchFirst -> head { filterMatches() } - } - } - } - } - - if (!context(MatchContext()) { method.match() }) return null - val instructionMatches = filters?.withIndex()?.map { (i, filter) -> - val matchIndex = matchIndices.indices[i] - Match.InstructionMatch(filter, matchIndex, method.getInstruction(matchIndex)) - } - - _matchOrNull = Match( - context, - context.lookupMaps.classDefsByType[method.definingClass]!!, - method, - instructionMatches, - stringMatches, - ) - - return _matchOrNull - } - - fun patchException() = PatchException("Failed to match the fingerprint: $this") - - /** - * The match for this [Fingerprint]. - * - * @return The [Match] of this fingerprint. - * @throws PatchException If the [Fingerprint] failed to match. - */ - context(_: BytecodePatchContext) - fun match() = matchOrNull() ?: throw patchException() - - /** - * Match using a [ClassDef]. - * - * @param classDef The class to match against. - * @return The [Match] of this fingerprint. - * @throws PatchException If the fingerprint failed to match. - */ - context(_: BytecodePatchContext) - fun match( - classDef: ClassDef, - ) = matchOrNull(classDef) ?: throw patchException() - - /** - * Match using a [Method]. - * The class is retrieved from the method. - * - * @param method The method to match against. - * @return The [Match] of this fingerprint. - * @throws PatchException If the fingerprint failed to match. - */ - context(_: BytecodePatchContext) - fun match( - method: Method, - ) = matchOrNull(method) ?: throw patchException() - - /** - * Match using a [Method]. - * - * @param method The method to match against. - * @param classDef The class the method is a member of. - * @return The [Match] of this fingerprint. - * @throws PatchException If the fingerprint failed to match. - */ - context(_: BytecodePatchContext) - fun match( - method: Method, - classDef: ClassDef, - ) = matchOrNull(classDef, method) ?: throw patchException() - - /** - * The class the matching method is a member of, or null if this fingerprint did not match. - */ - context(_: BytecodePatchContext) - val originalClassDefOrNull - get() = matchOrNull()?.originalClassDef - - /** - * The matching method, or null of this fingerprint did not match. - */ - context(_: BytecodePatchContext) - val originalMethodOrNull - get() = matchOrNull()?.originalMethod - - /** - * The mutable version of [originalClassDefOrNull]. - * - * Accessing this property allocates a new mutable instance. - * Use [originalClassDefOrNull] if mutable access is not required. - */ - context(_: BytecodePatchContext) - val classDefOrNull - get() = matchOrNull()?.classDef - - /** - * The mutable version of [originalMethodOrNull]. - * - * Accessing this property allocates a new mutable instance. - * Use [originalMethodOrNull] if mutable access is not required. - */ - context(_: BytecodePatchContext) - val methodOrNull - get() = matchOrNull()?.method - - /** - * The match for the opcode pattern, or null if this fingerprint did not match. - */ - context(_: BytecodePatchContext) - @Deprecated("instead use instructionMatchesOrNull") - val patternMatchOrNull: PatternMatch? - get() { - val match = this.matchOrNull() - if (match == null || match.instructionMatchesOrNull == null) { - return null - } - return match.patternMatch - } - - /** - * The match for the instruction filters, or null if this fingerprint did not match. - */ - context(_: BytecodePatchContext) - val instructionMatchesOrNull - get() = matchOrNull()?.instructionMatchesOrNull - - /** - * The matches for the strings, or null if this fingerprint did not match. - * - * This does not give matches for strings declared using [string] instruction filters. - */ - context(_: BytecodePatchContext) - @Deprecated("Instead use string instructions and `instructionMatchesOrNull()`") - val stringMatchesOrNull - get() = matchOrNull()?.stringMatchesOrNull - - /** - * The class the matching method is a member of. - * - * @throws PatchException If the fingerprint has not been matched. - */ - context(_: BytecodePatchContext) - val originalClassDef - get() = match().originalClassDef - - /** - * The matching method. - * - * @throws PatchException If the fingerprint has not been matched. - */ - context(_: BytecodePatchContext) - val originalMethod - get() = match().originalMethod - - /** - * The mutable version of [originalClassDef]. - * - * Accessing this property allocates a new mutable instance. - * Use [originalClassDef] if mutable access is not required. - * - * @throws PatchException If the fingerprint has not been matched. - */ - context(_: BytecodePatchContext) - val classDef - get() = match().classDef - - /** - * The mutable version of [originalMethod]. - * - * Accessing this property allocates a new mutable instance. - * Use [originalMethod] if mutable access is not required. - * - * @throws PatchException If the fingerprint has not been matched. - */ - context(_: BytecodePatchContext) - val method - get() = match().method - - /** - * The match for the opcode pattern. - * - * @throws PatchException If the fingerprint has not been matched. - */ - context(_: BytecodePatchContext) - @Deprecated("Instead use instructionMatch") - val patternMatch - get() = match().patternMatch - - /** - * Instruction filter matches. - * - * @throws PatchException If the fingerprint has not been matched. - */ - context(_: BytecodePatchContext) - val instructionMatches - get() = match().instructionMatches - - /** - * The matches for the strings declared using `strings()`. - * This does not give matches for strings declared using [string] instruction filters. - * - * @throws PatchException If the fingerprint has not been matched. - */ - context(_: BytecodePatchContext) - @Deprecated("Instead use string instructions and `instructionMatches()`") - val stringMatches - get() = match().stringMatches -} - -/** - * A match of a [Fingerprint]. - * - * @param originalClassDef The class the matching method is a member of. - * @param originalMethod The matching method. - * @param _instructionMatches The match for the instruction filters. - * @param _stringMatches The matches for the strings declared using `strings()`. - */ -class Match internal constructor( - val context: BytecodePatchContext, - val originalClassDef: ClassDef, - val originalMethod: Method, - private val _instructionMatches: List?, - private val _stringMatches: List?, -) { - /** - * The mutable version of [originalClassDef]. - * - * Accessing this property allocates a new mutable instance. - * Use [originalClassDef] if mutable access is not required. - */ - val classDef by lazy { with(context) { originalClassDef.mutable() } } - - /** - * The mutable version of [originalMethod]. - * - * Accessing this property allocates a new mutable instance. - * Use [originalMethod] if mutable access is not required. - */ - val method by lazy { classDef.methods.first { MethodUtil.methodSignaturesMatch(it, originalMethod) } } - - @Deprecated("Instead use instructionMatches", ReplaceWith("instructionMatches")) - val patternMatch by lazy { - if (_instructionMatches == null) throw PatchException("Did not match $this") - @SuppressWarnings("deprecation") - PatternMatch(_instructionMatches.first().index, _instructionMatches.last().index) - } - - val instructionMatches - get() = _instructionMatches ?: throw PatchException("Fingerprint declared no instruction filters") - val instructionMatchesOrNull = _instructionMatches - - @Deprecated("Instead use string instructions and `instructionMatches()`") - val stringMatches - get() = _stringMatches ?: throw PatchException("Fingerprint declared no strings") - - @Deprecated("Instead use string instructions and `instructionMatchesOrNull()`") - val stringMatchesOrNull = _stringMatches - - /** - * A match for an opcode pattern. - * @param startIndex The index of the first opcode of the pattern in the method. - * @param endIndex The index of the last opcode of the pattern in the method. - */ - @Deprecated("Instead use InstructionMatch") - class PatternMatch internal constructor( - val startIndex: Int, - val endIndex: Int, - ) - - /** - * A match for a string. - * - * @param string The string that matched. - * @param index The index of the instruction in the method. - */ - @Deprecated("Instead use string instructions and `InstructionMatch`") - class StringMatch internal constructor(val string: String, val index: Int) - - /** - * A match for a [InstructionFilter]. - * @param filter The filter that matched - * @param index The instruction index it matched with. - * @param instruction The instruction that matched. - */ - class InstructionMatch internal constructor( - val filter: InstructionFilter, - val index: Int, - val instruction: Instruction - ) { - @Suppress("UNCHECKED_CAST") - fun getInstruction(): T = instruction as T - } -} - -/** - * A builder for [Fingerprint]. - * - * @property accessFlags The exact access flags using values of [AccessFlags]. - * @property returnType The return type compared using [String.startsWith]. - * @property parameters The parameters of the method. Partial matches allowed and follow the same rules as [returnType]. - * @property instructionFilters Filters to match the method instructions. - * @property strings A list of the strings compared each using [String.contains]. - * @property customBlock A custom condition for this fingerprint. - * - * @constructor Create a new [FingerprintBuilder]. - */ -class FingerprintBuilder() { - private var accessFlags: Int? = null - private var returnType: String? = null - private var parameters: List? = null - private var instructionFilters: List? = null - private var strings: List? = null - private var customBlock: ((method: Method, classDef: ClassDef) -> Boolean)? = null - - /** - * Set the access flags. - * - * @param accessFlags The exact access flags using values of [AccessFlags]. - */ - fun accessFlags(accessFlags: Int) { - this.accessFlags = accessFlags - } - - /** - * Set the access flags. - * - * @param accessFlags The exact access flags using values of [AccessFlags]. - */ - fun accessFlags(vararg accessFlags: AccessFlags) { - this.accessFlags = accessFlags.fold(0) { acc, it -> acc or it.value } - } - - /** - * Set the return type. - * - * If [accessFlags] includes [AccessFlags.CONSTRUCTOR], then there is no need to - * set a return type set since constructors are always void return type. - * - * @param returnType The return type compared using [String.startsWith]. - */ - fun returns(returnType: String) { - this.returnType = returnType - } - - /** - * Set the parameters. - * - * @param parameters The parameters of the method. - * Partial matches allowed and follow the same rules as [returnType]. - */ - fun parameters(vararg parameters: String) { - this.parameters = parameters.toList() - } - - private fun verifyNoFiltersSet() { - if (this.instructionFilters != null) { - throw PatchException("Instruction filters already set") - } - } - - /** - * A pattern of opcodes, where each opcode must appear immediately after the previous. - * - * To use opcodes with other [InstructionFilter] objects, - * instead use [instructions] with individual opcodes declared using [opcode]. - * - * This method is identical to declaring individual opcode filters - * with [InstructionFilter.location] set to [InstructionLocation.MatchAfterImmediately] - * for all but the first opcode. - * - * Unless absolutely necessary, it is recommended to instead use [instructions] - * with more fine grained filters. - * - * ``` - * opcodes( - * Opcode.INVOKE_VIRTUAL, // First opcode matches anywhere in the method. - * Opcode.MOVE_RESULT_OBJECT, // Must match exactly after INVOKE_VIRTUAL. - * Opcode.IPUT_OBJECT // Must match exactly after MOVE_RESULT_OBJECT. - * ) - * ``` - * is identical to: - * ``` - * instructions( - * opcode(Opcode.INVOKE_VIRTUAL), // First opcode matches anywhere in the method. - * opcode(Opcode.MOVE_RESULT_OBJECT, maxAfter = 0), // Must match exactly after INVOKE_VIRTUAL. - * opcode(Opcode.IPUT_OBJECT, maxAfter = 0) // Must match exactly after MOVE_RESULT_OBJECT. - * ) - * ``` - * - * @param opcodes An opcode pattern of instructions. - * Wildcard or unknown opcodes can be specified by `null`. - */ - fun opcodes(vararg opcodes: Opcode?) { - verifyNoFiltersSet() - if (opcodes.isEmpty()) throw IllegalArgumentException("One or more opcodes is required") - - this.instructionFilters = OpcodesFilter.listOfOpcodes(opcodes.toList()) - } - - /** - * A pattern of opcodes from SMALI formatted text, - * where each opcode must appear immediately after the previous opcode. - * - * Unless absolutely necessary, it is recommended to instead use [instructions]. - * - * @param instructions A list of instructions or opcode names in SMALI format. - * - Wildcard or unknown opcodes can be specified by `null`. - * - Empty lines are ignored. - * - Each instruction must be on a new line. - * - The opcode name is enough, no need to specify the operands. - * - * @throws Exception If an unknown opcode is used. - */ - fun opcodes(instructions: String) { - verifyNoFiltersSet() - if (instructions.isBlank()) throw IllegalArgumentException("No instructions declared (empty string)") - - this.instructionFilters = OpcodesFilter.listOfOpcodes( - instructions.trimIndent().split("\n").filter { - it.isNotBlank() - }.map { - // Remove any operands. - val name = it.split(" ", limit = 1).first().trim() - if (name == "null") return@map null - - opcodesByName[name] ?: throw IllegalArgumentException("Unknown opcode: $name") - } - ) - } - - /** - * A list of instruction filters to match. - */ - fun instructions(vararg instructionFilters: InstructionFilter) { - verifyNoFiltersSet() - if (instructionFilters.isEmpty()) throw IllegalArgumentException("One or more instructions is required") - - this.instructionFilters = instructionFilters.toList() - } - - /** - * Set the strings. - * - * @param strings A list of strings compared each using [String.contains]. - */ - @Deprecated("Instead use `instruction()` filters and `string()` instruction declarations") - fun strings(vararg strings: String) { - this.strings = strings.toList() - } - - /** - * Set a custom condition for this fingerprint. - * - * @param customBlock A custom condition for this fingerprint. - */ - fun custom(customBlock: (method: Method, classDef: ClassDef) -> Boolean) { - this.customBlock = customBlock - } - - fun build(): Fingerprint { - // If access flags include constructor then - // skip the return type check since it's always void. - if (returnType?.equals("V") == true && accessFlags != null - && AccessFlags.CONSTRUCTOR.isSet(accessFlags!!) - ) { - returnType = null - } - - return Fingerprint( - accessFlags, - returnType, - parameters, - instructionFilters, - strings, - customBlock, - ) - } - - - private companion object { - val opcodesByName = Opcode.entries.associateBy { it.name } - } -} - -fun fingerprint( - block: FingerprintBuilder.() -> Unit, -) = FingerprintBuilder().apply(block).build() - -/** - * Matches two lists of parameters, where the first parameter list - * starts with the values of the second list. - */ -internal fun parametersStartsWith( - targetMethodParameters: Iterable, - fingerprintParameters: Iterable, -): Boolean { - if (fingerprintParameters.count() != targetMethodParameters.count()) return false - val fingerprintIterator = fingerprintParameters.iterator() - - targetMethodParameters.forEach { - if (!it.startsWith(fingerprintIterator.next())) return false - } - - return true -} - - diff --git a/src/main/kotlin/app/revanced/patcher/InstructionFilter.kt b/src/main/kotlin/app/revanced/patcher/InstructionFilter.kt deleted file mode 100644 index e54bd12..0000000 --- a/src/main/kotlin/app/revanced/patcher/InstructionFilter.kt +++ /dev/null @@ -1,1075 +0,0 @@ -package app.revanced.patcher - -import app.revanced.patcher.FieldAccessFilter.Companion.parseJvmFieldAccess -import app.revanced.patcher.MethodCallFilter.Companion.parseJvmMethodCall -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.Method -import com.android.tools.smali.dexlib2.iface.instruction.Instruction -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction -import com.android.tools.smali.dexlib2.iface.reference.FieldReference -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.iface.reference.StringReference -import com.android.tools.smali.dexlib2.iface.reference.TypeReference -import java.util.* - -/** - * Simple interface to control how much space is allowed between a previous - * [InstructionFilter] match and the current [InstructionFilter]. - */ -fun interface InstructionLocation { - /** - * @param previouslyMatchedIndex The previously matched index, or -1 if this is the first filter. - * @param currentIndex The current method index that is about to be checked. - */ - fun indexIsValidForMatching(previouslyMatchedIndex: Int, currentIndex: Int) : Boolean - - /** - * Matching can occur anywhere after the previous instruction filter match index. - * Is the default behavior for all filters. - */ - class MatchAfterAnywhere : InstructionLocation { - override fun indexIsValidForMatching(previouslyMatchedIndex: Int, currentIndex: Int) = true - } - - /** - * Matches the first instruction of a method. - * - * This can only be used for the first filter, and using with any other filter will throw an exception. - */ - class MatchFirst() : InstructionLocation { - override fun indexIsValidForMatching(previouslyMatchedIndex: Int, currentIndex: Int) : Boolean { - require(previouslyMatchedIndex < 0) { - "MatchFirst can only be used for the first instruction filter" - } - return true - } - } - - /** - * Instruction index immediately after the previous filter. - * - * Useful for opcodes that must always appear immediately after the last filter such as: - * - [Opcode.MOVE_RESULT] - * - [Opcode.MOVE_RESULT_WIDE] - * - [Opcode.MOVE_RESULT_OBJECT] - * - * This cannot be used for the first filter and will throw an exception. - */ - class MatchAfterImmediately() : InstructionLocation { - override fun indexIsValidForMatching(previouslyMatchedIndex: Int, currentIndex: Int) : Boolean { - require(previouslyMatchedIndex >= 0) { - "MatchAfterImmediately cannot be used for the first instruction filter" - } - return currentIndex - 1 == previouslyMatchedIndex - } - } - - /** - * Instruction index can occur within a range of the previous instruction filter match index. - * used to constrain instruction matching to a region after the previous instruction filter. - * - * This cannot be used for the first filter and will throw an exception. - * - * @param matchDistance The number of unmatched instructions that can exist between the - * current instruction filter and the previously matched instruction filter. - * A value of 0 means the current filter can only match immediately after - * the previously matched instruction (making this functionally identical to - * [MatchAfterImmediately]). A value of 10 means between 0 and 10 unmatched - * instructions can exist between the previously matched instruction and - * the current instruction filter. - */ - class MatchAfterWithin(val matchDistance: Int) : InstructionLocation { - init { - require(matchDistance >= 0) { - "matchDistance must be non-negative" - } - } - - override fun indexIsValidForMatching(previouslyMatchedIndex: Int, currentIndex: Int) : Boolean { - require(previouslyMatchedIndex >= 0) { - "MatchAfterImmediately cannot be used for the first instruction filter" - } - return currentIndex - previouslyMatchedIndex - 1 <= matchDistance - } - } - - /** - * Instruction index can occur only after a minimum number of unmatched instructions from the - * previous instruction match. Or if this is used with the first filter of a fingerprint then - * this can only match starting from a given instruction index. - * - * @param minimumDistanceFromLastInstruction The minimum number of unmatched instructions that - * must exist between this instruction and the last matched instruction. A value of 0 is - * functionally identical to [MatchAfterImmediately]. - */ - class MatchAfterAtLeast(var minimumDistanceFromLastInstruction: Int) : InstructionLocation { - init { - require(minimumDistanceFromLastInstruction >= 0) { - "minimumDistanceFromLastInstruction must >= 0" - } - } - - override fun indexIsValidForMatching(previouslyMatchedIndex: Int, currentIndex: Int) : Boolean { - return currentIndex - previouslyMatchedIndex - 1 >= minimumDistanceFromLastInstruction - } - } - - /** - * Functionally combines both [MatchAfterAtLeast] and [MatchAfterWithin] to give a bounded range - * where the next instruction must match relative to the previous matched instruction. - * - * Unlike [MatchAfterImmediately] or [MatchAfterWithin], this can be used for the first filter - * to constrain matching to a specific range starting from index 0. - * - * @param minimumDistanceFromLastInstruction The minimum number of unmatched instructions that - * must exist between this instruction and the last - * matched instruction. - * @param maximumDistanceFromLastInstruction The maximum number of unmatched instructions - * that can exist between this instruction and the - * last matched instruction. - */ - class MatchAfterRange( - val minimumDistanceFromLastInstruction: Int, - val maximumDistanceFromLastInstruction: Int - ) : InstructionLocation { - - private val minMatcher = MatchAfterAtLeast(minimumDistanceFromLastInstruction) - private val maxMatcher = MatchAfterWithin(maximumDistanceFromLastInstruction) - - init { - require(minimumDistanceFromLastInstruction <= maximumDistanceFromLastInstruction) { - "minimumDistanceFromLastInstruction must be <= maximumDistanceFromLastInstruction" - } - } - - override fun indexIsValidForMatching(previouslyMatchedIndex: Int, currentIndex: Int): Boolean { - // For the first filter, previouslyMatchedIndex will be -1, and both delegates - // will correctly enforce their own semantics starting from index 0. - return minMatcher.indexIsValidForMatching(previouslyMatchedIndex, currentIndex) && - maxMatcher.indexIsValidForMatching(previouslyMatchedIndex, currentIndex) - } - } -} - - - -/** - * String comparison type. - */ -enum class StringComparisonType { - EQUALS, - CONTAINS, - STARTS_WITH, - ENDS_WITH; - - /** - * @param targetString The target string to search - * @param searchString To search for in the target string (or to compare entirely for equality). - */ - fun compare(targetString: String, searchString: String): Boolean { - return when (this) { - EQUALS -> targetString == searchString - CONTAINS -> targetString.contains(searchString) - STARTS_WITH -> targetString.startsWith(searchString) - ENDS_WITH -> targetString.endsWith(searchString) - } - } - - /** - * Throws [IllegalArgumentException] if the class type search string is invalid and can never match. - */ - internal fun validateSearchStringForClassType(classTypeSearchString: String) { - when (this) { - EQUALS -> { - STARTS_WITH.validateSearchStringForClassType(classTypeSearchString) - ENDS_WITH.validateSearchStringForClassType(classTypeSearchString) - } - CONTAINS -> Unit // Nothing to validate, anything goes. - STARTS_WITH -> require(classTypeSearchString.startsWith('L')) { - "Class type does not start with L: $classTypeSearchString" - } - ENDS_WITH -> require(classTypeSearchString.endsWith(';')) { - "Class type does not end with a semicolon: $classTypeSearchString" - } - } - } -} - - - -/** - * Matches method [Instruction] objects, similar to how [Fingerprint] matches entire methods. - * - * The most basic filters match only opcodes and nothing more, - * and more precise filters can match: - * - Field references (get/put opcodes) by name/type. - * - Method calls (invoke_* opcodes) by name/parameter/return type. - * - Object instantiation for specific class types. - * - Literal const values. - * - * If creating a custom filter for unusual or app specific purposes, consider extending - * [OpcodeFilter] or [OpcodesFilter] to reduce boilerplate opcode checking logic. - */ -fun interface InstructionFilter { - - /** - * The [InstructionLocation] associated with this filter. - */ - val location: InstructionLocation - get() = InstructionLocation.MatchAfterAnywhere() - - /** - * If this filter matches the method instruction. - * - * @param enclosingMethod The method of that contains [instruction]. - * @param instruction The instruction to check for a match. - */ - fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean -} - - - -class AnyInstruction internal constructor( - internal val filters: List, - override val location: InstructionLocation -) : InstructionFilter { - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ) : Boolean { - return filters.any { filter -> - filter.matches(enclosingMethod, instruction) - } - } -} - -/** - * Logical OR operator where the first filter that matches satisfies this filter. - * - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun anyInstruction( - vararg filters: InstructionFilter, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = AnyInstruction(filters.asList(), location) - - - -/** - * Single opcode match. - * - * Patches can extend this as desired to do unusual or app specific instruction filtering. - * Or Alternatively can implement [InstructionFilter] directly. - * - * @param opcode Opcode to match. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -open class OpcodeFilter( - val opcode: Opcode, - override val location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) : InstructionFilter { - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean { - return instruction.opcode == opcode - } -} - -/** - * Single opcode match. - * - * @param opcode Opcode to match. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun opcode( - opcode: Opcode, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = OpcodeFilter(opcode, location) - - - -/** - * Matches a single instruction from many kinds of opcodes. - * - * Patches can extend this as desired to do unusual or app specific instruction filtering. - * Or Alternatively can implement [InstructionFilter] directly. - * - * @param opcodes Set of opcodes to match to. Value of `null` will match any opcode. - * If matching only a single opcode then instead use [OpcodeFilter]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -open class OpcodesFilter protected constructor( - val opcodes: EnumSet?, - override val location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) : InstructionFilter { - - protected constructor( - opcodes: List?, - location: InstructionLocation - ) : this(if (opcodes == null) null else EnumSet.copyOf(opcodes), location) - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean { - if (opcodes == null) { - return true // Match anything. - } - return opcodes.contains(instruction.opcode) - } - - internal companion object { - /** - * First opcode can match anywhere in a method, but all - * subsequent opcodes must match after the previous opcode. - * - * A value of `null` indicates to match any opcode. - */ - internal fun listOfOpcodes(opcodes: Collection): List { - val list = ArrayList(opcodes.size) - var location: InstructionLocation? = null - - opcodes.forEach { opcode -> - // First opcode can match anywhere. - val opcodeLocation = location ?: InstructionLocation.MatchAfterAnywhere() - - list += if (opcode == null) { - // Null opcode matches anything. - OpcodesFilter( - null as List?, - opcodeLocation - ) - } else { - OpcodeFilter(opcode, opcodeLocation) - } - - if (location == null) { - location = InstructionLocation.MatchAfterImmediately() - } - } - - return list - } - } -} - - - -class LiteralFilter internal constructor( - val literal: () -> Long, - opcodes: List? = null, - location: InstructionLocation -) : OpcodesFilter(opcodes, location) { - - /** - * Store the lambda value instead of calling it more than once. - */ - internal val literalValue: Long by lazy(literal) - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean { - if (!super.matches(enclosingMethod, instruction)) { - return false - } - - if (instruction !is WideLiteralInstruction) return false - - return instruction.wideLiteral == literalValue - } -} - -/** - * Long literal. Automatically converts literal to opcode hex. - * - * @param literal Literal number. - * @param opcodes Opcodes to match. By default this matches any literal number opcode such as: - * [Opcode.CONST_4], [Opcode.CONST_16], [Opcode.CONST], [Opcode.CONST_WIDE]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun literal( - literal: Long, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = LiteralFilter({ literal }, opcodes, location) - -/** - * Integer literal. Automatically converts literal to opcode hex. - * - * @param literal Literal number. - * @param opcodes Opcodes to match. By default this matches any literal number opcode such as: - * [Opcode.CONST_4], [Opcode.CONST_16], [Opcode.CONST], [Opcode.CONST_WIDE]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun literal( - literal: Int, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = LiteralFilter({ literal.toLong() }, opcodes, location) - -/** - * Double point literal. Automatically converts literal to opcode hex. - * - * @param literal Literal number. - * @param opcodes Opcodes to match. By default this matches any literal number opcode such as: - * [Opcode.CONST_4], [Opcode.CONST_16], [Opcode.CONST], [Opcode.CONST_WIDE]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun literal( - literal: Double, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = LiteralFilter({ literal.toRawBits() }, opcodes, location) - -/** - * Floating point literal. Automatically converts literal to opcode hex. - * - * @param literal Floating point literal. - * @param opcodes Opcodes to match. By default this matches any literal number opcode such as: - * [Opcode.CONST_4], [Opcode.CONST_16], [Opcode.CONST], [Opcode.CONST_WIDE]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun literal( - literal: Float, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = LiteralFilter({ literal.toRawBits().toLong() }, opcodes, location) - -/** - * Literal number value. Automatically converts the provided number to opcode hex. - * - * @param literal Literal number. - * @param opcodes Opcodes to match. By default this matches any literal number opcode such as: - * [Opcode.CONST_4], [Opcode.CONST_16], [Opcode.CONST], [Opcode.CONST_WIDE]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun literal( - literal: () -> Long, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = LiteralFilter(literal, opcodes, location) - - - -class MethodCallFilter internal constructor( - val definingClass: String? = null, - val name: String? = null, - val parameters: List? = null, - val returnType: String? = null, - opcodes: List? = null, - location: InstructionLocation -) : OpcodesFilter(opcodes, location) { - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean { - if (!super.matches(enclosingMethod, instruction)) { - return false - } - - val reference = (instruction as? ReferenceInstruction)?.reference as? MethodReference - ?: return false - - if (definingClass != null) { - val referenceClass = reference.definingClass - - if (!StringComparisonType.ENDS_WITH.compare(referenceClass, definingClass)) { - // Check if 'this' defining class is used. - // Would be nice if this also checked all super classes, - // but doing so requires iteratively checking all superclasses - // up to the root class since class defs are mere Strings. - if (!(definingClass == "this" && referenceClass == enclosingMethod.definingClass)) { - return false - } // else, the method call is for 'this' class. - } - } - - if (name != null && reference.name != name) { - return false - } - - if (returnType != null && - !StringComparisonType.STARTS_WITH.compare(reference.returnType, returnType)) { - return false - } - - if (parameters != null && - !parametersStartsWith(reference.parameterTypes, parameters)) { - return false - } - - return true - } - - internal companion object { - private val regex = Regex("""^(L[^;]+;)->([^(\s]+)\(([^)]*)\)(\[?L[^;]+;|\[?[BCSIJFDZV])${'$'}""") - - internal fun parseJvmMethodCall( - methodSignature: String, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() - ): MethodCallFilter { - val matchResult = regex.matchEntire(methodSignature) - ?: throw IllegalArgumentException("Invalid method signature: $methodSignature") - - val classDescriptor = matchResult.groupValues[1] - val methodName = matchResult.groupValues[2] - val paramDescriptorString = matchResult.groupValues[3] - val returnDescriptor = matchResult.groupValues[4] - - val paramDescriptors = parseParameterDescriptors(paramDescriptorString) - - return MethodCallFilter( - classDescriptor, - methodName, - paramDescriptors, - returnDescriptor, - opcodes, - location - ) - } - - /** - * Parses a single JVM type descriptor or an array descriptor at the current position. - * For example: Lcom/example/SomeClass; or I or [I or [Lcom/example/SomeClass; - */ - private fun parseSingleType(params: String, startIndex: Int): Pair { - var i = startIndex - - // Skip past array declaration, including multi-dimensional arrays. - val paramsLength = params.length - while (i < paramsLength && params[i] == '[') { - i++ - } - - return if (i < paramsLength && params[i] == 'L') { - // It's an object type starting with 'L', read until ';' - val semicolonPos = params.indexOf(';', i) - if (semicolonPos < 0) { - throw IllegalArgumentException("Malformed object descriptor (missing semicolon): $params") - } - // Substring from startIndex up to and including the semicolon. - val typeDescriptor = params.substring(startIndex, semicolonPos + 1) - typeDescriptor to (semicolonPos + 1) - } else { - // It's either a primitive or we've already consumed the array part - // So just take one character (e.g. 'I', 'Z', 'B', etc.) - val typeDescriptor = params.substring(startIndex, i + 1) - typeDescriptor to (i + 1) - } - } - - /** - * Parses the parameters into a list of JVM type descriptors. - */ - private fun parseParameterDescriptors(paramString: String): List { - val result = mutableListOf() - var currentIndex = 0 - val stringLength = paramString.length - - while (currentIndex < stringLength) { - val (type, nextIndex) = parseSingleType(paramString, currentIndex) - result.add(type) - currentIndex = nextIndex - } - - return result - } - } -} - -/** - * Matches a method call, such as: - * `invoke-virtual {v3, v4}, La;->b(I)V` - * - * @param definingClass Defining class of the field call. Compares using [StringComparisonType.ENDS_WITH]. - * For calls to a method in the same class, use 'this' as the defining class. - * Note: 'this' does not work for fields found in superclasses. - * @param name Full name of the method. Compares using [StringComparisonType.EQUALS]. - * @param parameters Parameters of the method call. Each parameter matches using[StringComparisonType.STARTS_WITH] - * and semantics are the same as [Fingerprint] parameters. - * @param returnType Return type. Matches using [StringComparisonType.STARTS_WITH]. - * @param opcodes Opcode types to match. By default this matches any method call opcode: `Opcode.INVOKE_*`. - * If this filter must match specific types of method call, then specify the desired opcodes -such as [Opcode.INVOKE_STATIC], [Opcode.INVOKE_STATIC_RANGE] to match only static calls. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun methodCall( - definingClass: String? = null, - name: String? = null, - parameters: List? = null, - returnType: String? = null, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = MethodCallFilter( - definingClass, - name, - parameters, - returnType, - opcodes, - location -) - -/** - * Matches a method call, such as: - * `invoke-virtual {v3, v4}, La;->b(I)V` - * - * @param definingClass Defining class of the field call. Compares using [StringComparisonType.ENDS_WITH]. - * For calls to a method in the same class, use 'this' as the defining class. - * Note: 'this' does not work for fields found in superclasses. - * @param name Full name of the method. Compares using [StringComparisonType.EQUALS]. - * @param parameters Parameters of the method call. Each parameter matches using[StringComparisonType.STARTS_WITH] - * and semantics are the same as [Fingerprint] parameters. - * @param returnType Return type. Matches using [StringComparisonType.STARTS_WITH]. - * @param opcode Single opcode type to match. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun methodCall( - definingClass: String? = null, - name: String? = null, - parameters: List? = null, - returnType: String? = null, - opcode: Opcode, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = MethodCallFilter( - definingClass, - name, - parameters, - returnType, - listOf(opcode), - location -) - -/** - * Method call for a copy pasted SMALI style method signature. e.g.: - * `Landroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;` - * - * Should never be used with obfuscated method names or parameter/return types. - * - * @param smali Smali method call reference, such as - * `Landroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;`. - * @param opcodes List of all possible opcodes to match. Defaults to matching all method calls types: `Opcode.INVOKE_*`. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun methodCall( - smali: String, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = parseJvmMethodCall(smali, opcodes, location) - -/** - * Method call for a copy pasted SMALI style method signature. e.g.: - * `Landroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;` - * - * Should never be used with obfuscated method names or parameter/return types. - * - * @param smali Smali method call reference, such as - * `Landroid/view/View;->inflate(Landroid/content/Context;ILandroid/view/ViewGroup;)Landroid/view/View;`. - * @param opcode Single opcode type to match. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun methodCall( - smali: String, - opcode: Opcode, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = parseJvmMethodCall(smali, listOf(opcode), location) - - - -class FieldAccessFilter internal constructor( - val definingClass: String? = null, - val name: String? = null, - val type: String? = null, - opcodes: List? = null, - location: InstructionLocation -) : OpcodesFilter(opcodes, location) { - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean { - if (!super.matches(enclosingMethod, instruction)) { - return false - } - - val reference = (instruction as? ReferenceInstruction)?.reference as? FieldReference - ?: return false - - if (definingClass != null) { - val referenceClass = reference.definingClass - - if (!referenceClass.endsWith(definingClass)) { - if (!(definingClass == "this" && referenceClass == enclosingMethod.definingClass)) { - return false - } // else, the method call is for 'this' class. - } - } - - if (name != null && reference.name != name) { - return false - } - - if (type != null && !reference.type.startsWith(type)) { - return false - } - - return true - } - - internal companion object { - private val regex = Regex("""^(L[^;]+;)->([^:]+):(\[?L[^;]+;|\[?[BCSIJFDZV])${'$'}""") - - internal fun parseJvmFieldAccess( - fieldSignature: String, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() - ): FieldAccessFilter { - val matchResult = regex.matchEntire(fieldSignature) - ?: throw IllegalArgumentException("Invalid field access smali: $fieldSignature") - - return fieldAccess( - definingClass = matchResult.groupValues[1], - name = matchResult.groupValues[2], - type = matchResult.groupValues[3], - opcodes = opcodes, - location = location - ) - } - } -} - - -/** - * Matches a field call, such as: - * `iget-object v0, p0, Lahhh;->g:Landroid/view/View;` - * - * @param definingClass Defining class of the field call. Compares using [StringComparisonType.ENDS_WITH]. - * For calls to a method in the same class, use 'this' as the defining class. - * Note: 'this' does not work for fields found in superclasses. - * @param name Full name of the field. Compares using [StringComparisonType.EQUALS]. - * @param type Class type of field. Compares using [StringComparisonType.STARTS_WITH]. - * @param opcode Single opcode type to match. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun fieldAccess( - definingClass: String? = null, - name: String? = null, - type: String? = null, - opcode: Opcode, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = fieldAccess( - definingClass, - name, - type, - listOf(opcode), - location -) - -/** - * Matches a field call, such as: - * `iget-object v0, p0, Lahhh;->g:Landroid/view/View;` - * - * @param definingClass Defining class of the field call. Compares using [StringComparisonType.ENDS_WITH]. - * For calls to a method in the same class, use 'this' as the defining class. - * Note: 'this' does not work for fields found in superclasses. - * @param name Full name of the field. Compares using [StringComparisonType.EQUALS]. - * @param type Class type of field. Compares using [StringComparisonType.STARTS_WITH]. - * @param opcodes List of all possible opcodes to match. Defaults to matching all get/put opcodes. - * (`Opcode.IGET`, `Opcode.SGET`, `Opcode.IPUT`, `Opcode.SPUT`, etc). - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun fieldAccess( - definingClass: String? = null, - name: String? = null, - type: String? = null, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = FieldAccessFilter( - definingClass, - name, - type, - opcodes, - location -) - -/** - * Field access for a copy pasted SMALI style field access call. e.g.: - * `Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;` - * - * Should never be used with obfuscated field names or obfuscated field types. - * @param smali Smali field access statement, such as `Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;`. - * @param opcodes List of all possible opcodes to match. Defaults to matching all get/put opcodes. - * (`Opcode.IGET`, `Opcode.SGET`, `Opcode.IPUT`, `Opcode.SPUT`, etc). - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun fieldAccess( - smali: String, - opcodes: List? = null, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = parseJvmFieldAccess(smali, opcodes, location) - -/** - * Field access for a copy pasted SMALI style field access call. e.g.: - * `Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;` - * - * Should never be used with obfuscated field names or obfuscated field types. - * - * @param smali Smali field access statement, such as `Ljava/lang/Boolean;->TRUE:Ljava/lang/Boolean;`. - * @param opcode Single opcode type to match. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun fieldAccess( - smali: String, - opcode: Opcode, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = parseJvmFieldAccess(smali, listOf(opcode), location) - - - -class StringFilter internal constructor( - val string: () -> String, - val comparison: StringComparisonType, - location: InstructionLocation -) : OpcodesFilter(listOf(Opcode.CONST_STRING, Opcode.CONST_STRING_JUMBO), location) { - - /** - * Store the lambda value instead of calling it more than once. - */ - internal val stringValue: String by lazy (string) - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean { - if (!super.matches(enclosingMethod, instruction)) { - return false - } - - val stringReference = (instruction as ReferenceInstruction).reference as StringReference - return comparison.compare(stringReference.string, stringValue) - } -} - -/** - * Literal String instruction. - * - * @param string string literal, using exact matching of [StringComparisonType.EQUALS]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun string( - string: String, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = StringFilter({ string }, StringComparisonType.EQUALS, location) - -/** - * Literal String instruction. - * - * @param string string literal, using exact matching of [StringComparisonType.EQUALS]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun string( - string: () -> String, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = StringFilter(string, StringComparisonType.EQUALS, location) - -/** - * Literal String instruction. - * - * @param string string literal. - * @param comparison How to compare the string literal. For more precise matching of strings, - * consider using [anyInstruction] with multiple exact string declarations. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun string( - string: String, - /** - * How to match a given string opcode literal. Default is exact string equality. For more - * precise matching of multiple strings, consider using [anyInstruction] with multiple - * exact string declarations. - */ - comparison: StringComparisonType = StringComparisonType.EQUALS, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = StringFilter({ string }, comparison, location) - -/** - * Literal String instruction. - * - * @param string string literal. - * @param comparison How to compare the string literal. For more precise matching of strings, - * consider using [anyInstruction] with multiple exact string declarations. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun string( - string: () -> String, - comparison: StringComparisonType, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = StringFilter(string, comparison, location) - - - -class NewInstanceFilter internal constructor ( - val type: () -> String, - val comparison: StringComparisonType, - location: InstructionLocation -) : OpcodesFilter(listOf(Opcode.NEW_INSTANCE, Opcode.NEW_ARRAY), location) { - - /** - * Store the lambda value instead of calling it more than once. - */ - private val typeValue: String by lazy { - val typeValue = type() - comparison.validateSearchStringForClassType(typeValue) - typeValue - } - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean { - if (!super.matches(enclosingMethod, instruction)) { - return false - } - - val reference = (instruction as ReferenceInstruction).reference as TypeReference - return comparison.compare(reference.type, typeValue) - } -} - -/** - * Opcode type [Opcode.NEW_INSTANCE] or [Opcode.NEW_ARRAY] with a non obfuscated class type. - * - * @param type Class type, compared using [StringComparisonType.ENDS_WITH]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun newInstance( - type: String, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = NewInstanceFilter({ type }, StringComparisonType.ENDS_WITH, location) - -/** - * Opcode type [Opcode.NEW_INSTANCE] or [Opcode.NEW_ARRAY] with a non obfuscated class type. - * - * @param type Class type, compared using [StringComparisonType.ENDS_WITH]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun newInstance( - type: () -> String, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere(), -) = NewInstanceFilter(type, StringComparisonType.ENDS_WITH, location) - -/** - * Opcode type [Opcode.NEW_INSTANCE] or [Opcode.NEW_ARRAY] with a non obfuscated class type. - * - * @param type Class type. - * @param comparison How to compare the opcode class type. For more precise matching of types, - * consider using [anyInstruction] with multiple exact type declarations. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun newInstance( - type: String, - comparison: StringComparisonType, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = NewInstanceFilter({ type }, comparison, location) - -/** - * Opcode type [Opcode.NEW_INSTANCE] or [Opcode.NEW_ARRAY] with a non obfuscated class type. - * - * @param type Class type. - * @param comparison How to compare the opcode class type. For more precise matching of types, - * consider using [anyInstruction] with multiple exact type declarations. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun newInstance( - type: () -> String, - comparison: StringComparisonType, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = NewInstanceFilter(type, comparison, location) - - - -class CheckCastFilter internal constructor( - val type: () -> String, - val comparison: StringComparisonType, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) : OpcodeFilter(Opcode.CHECK_CAST, location) { - - /** - * Store the lambda value instead of calling it more than once. - */ - internal val typeValue: String by lazy { - val typeValue = type() - comparison.validateSearchStringForClassType(typeValue) - typeValue - } - - override fun matches( - enclosingMethod: Method, - instruction: Instruction - ): Boolean { - if (!super.matches(enclosingMethod, instruction)) { - return false - } - - val reference = (instruction as ReferenceInstruction).reference as TypeReference - return comparison.compare(reference.type, typeValue) - } -} - -/** - * Opcode type [Opcode.CHECK_CAST] with a non obfuscated class type. - * - * @param type Class type, compared using [StringComparisonType.ENDS_WITH]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun checkCast( - type: String, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = CheckCastFilter({ type }, StringComparisonType.ENDS_WITH, location) - -/** - * Opcode type [Opcode.CHECK_CAST] with a non obfuscated class type. - * - * @param type Class type, compared using [StringComparisonType.ENDS_WITH]. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun checkCast( - type: () -> String, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = CheckCastFilter(type, StringComparisonType.ENDS_WITH, location) - -/** - * Opcode type [Opcode.CHECK_CAST] with a non obfuscated class type using the provided string comparison type. - * - * @param type Class type. - * @param comparison How to compare the opcode class type. For more precise matching of types, - * consider using [anyInstruction] with multiple exact type declarations. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun checkCast( - type: String, - comparison: StringComparisonType, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = CheckCastFilter({ type }, comparison, location) - -/** - * Opcode type [Opcode.CHECK_CAST] with a non obfuscated class type using the provided string comparison type. - * - * @param type Class type. - * @param comparison How to compare the opcode class type. For more precise matching of types, - * consider using [anyInstruction] with multiple exact type declarations. - * @param location Where this filter is allowed to match. Default is anywhere after the previous instruction. - */ -fun checkCast( - type: () -> String, - comparison: StringComparisonType, - location: InstructionLocation = InstructionLocation.MatchAfterAnywhere() -) = CheckCastFilter(type, comparison, location) diff --git a/src/main/kotlin/app/revanced/patcher/Matching.kt b/src/main/kotlin/app/revanced/patcher/Matching.kt deleted file mode 100644 index dc84f74..0000000 --- a/src/main/kotlin/app/revanced/patcher/Matching.kt +++ /dev/null @@ -1,582 +0,0 @@ -@file:Suppress("unused", "MemberVisibilityCanBePrivate", "CONTEXT_RECEIVERS_DEPRECATED") - -package app.revanced.patcher - -import app.revanced.patcher.Matcher.MatchContext -import app.revanced.patcher.dex.mutable.MutableMethod -import app.revanced.patcher.extensions.accessFlags -import app.revanced.patcher.patch.BytecodePatchContext -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.HiddenApiRestriction -import com.android.tools.smali.dexlib2.iface.* -import com.android.tools.smali.dexlib2.iface.Annotation -import com.android.tools.smali.dexlib2.iface.instruction.Instruction -import com.android.tools.smali.dexlib2.util.MethodUtil -import kotlin.properties.ReadOnlyProperty -import kotlin.reflect.KProperty - -fun Iterable.anyClassDef(predicate: ClassDef.() -> Boolean) = any(predicate) - -fun ClassDef.anyMethod(predicate: Method.() -> Boolean) = methods.any(predicate) - -fun ClassDef.anyDirectMethod(predicate: Method.() -> Boolean) = directMethods.any(predicate) - -fun ClassDef.anyVirtualMethod(predicate: Method.() -> Boolean) = virtualMethods.any(predicate) - -fun ClassDef.anyField(predicate: Field.() -> Boolean) = fields.any(predicate) - -fun ClassDef.anyInstanceField(predicate: Field.() -> Boolean) = instanceFields.any(predicate) - -fun ClassDef.anyStaticField(predicate: Field.() -> Boolean) = staticFields.any(predicate) - -fun ClassDef.anyInterface(predicate: String.() -> Boolean) = interfaces.any(predicate) - -fun ClassDef.anyAnnotation(predicate: Annotation.() -> Boolean) = annotations.any(predicate) - -fun Method.implementation(predicate: MethodImplementation.() -> Boolean) = implementation?.predicate() ?: false - -fun Method.anyParameter(predicate: MethodParameter.() -> Boolean) = parameters.any(predicate) - -fun Method.anyParameterType(predicate: CharSequence.() -> Boolean) = parameterTypes.any(predicate) - -fun Method.anyAnnotation(predicate: Annotation.() -> Boolean) = annotations.any(predicate) - -fun Method.anyHiddenApiRestriction(predicate: HiddenApiRestriction.() -> Boolean) = hiddenApiRestrictions.any(predicate) - -fun MethodImplementation.anyInstruction(predicate: Instruction.() -> Boolean) = instructions.any(predicate) - -fun MethodImplementation.anyTryBlock(predicate: TryBlock.() -> Boolean) = tryBlocks.any(predicate) - -fun MethodImplementation.anyDebugItem(predicate: Any.() -> Boolean) = debugItems.any(predicate) - -fun Iterable.anyInstruction(predicate: Instruction.() -> Boolean) = any(predicate) - -fun BytecodePatchContext.firstClassDefOrNull(predicate: context(MatchContext) ClassDef.() -> Boolean) = - with(MatchContext()) { classDefs.firstOrNull { it.predicate() } } - -fun BytecodePatchContext.firstClassDef(predicate: context(MatchContext) ClassDef.() -> Boolean) = - requireNotNull(firstClassDefOrNull(predicate)) - -fun BytecodePatchContext.firstClassDefMutableOrNull(predicate: context(MatchContext) ClassDef.() -> Boolean) = - firstClassDefOrNull(predicate)?.mutable() - -fun BytecodePatchContext.firstClassDefMutable(predicate: context(MatchContext) ClassDef.() -> Boolean) = - requireNotNull(firstClassDefMutableOrNull(predicate)) - -fun BytecodePatchContext.firstClassDefOrNull( - type: String, predicate: (context(MatchContext) ClassDef.() -> Boolean)? = null -) = lookupMaps.classDefsByType[type]?.takeIf { - predicate == null || with(MatchContext()) { it.predicate() } -} - -fun BytecodePatchContext.firstClassDef( - type: String, predicate: (context(MatchContext) ClassDef.() -> Boolean)? = null -) = requireNotNull(firstClassDefOrNull(type, predicate)) - -fun BytecodePatchContext.firstClassDefMutableOrNull( - type: String, predicate: (context(MatchContext) ClassDef.() -> Boolean)? = null -) = firstClassDefOrNull(type, predicate)?.mutable() - -fun BytecodePatchContext.firstClassDefMutable( - type: String, predicate: (context(MatchContext) ClassDef.() -> Boolean)? = null -) = requireNotNull(firstClassDefMutableOrNull(type, predicate)) - -fun Iterable.firstMethodOrNull(predicate: context(MatchContext) Method.() -> Boolean) = - with(MatchContext()) { - this@firstMethodOrNull.asSequence().flatMap { it.methods.asSequence() }.firstOrNull { it.predicate() } - } - -fun Iterable.firstMethod(predicate: context(MatchContext) Method.() -> Boolean) = - requireNotNull(firstMethodOrNull(predicate)) - -/** Can't compile due to JVM platform declaration clash -fun Iterable.firstMethodOrNull(predicate: context(MatchContext) Method.() -> Boolean) = -with(MatchContext()) { firstOrNull { it.predicate() } } - -fun Iterable.firstMethod(predicate: context(MatchContext) Method.() -> Boolean) = -with(MatchContext()) { requireNotNull(firstMethodOrNull(predicate)) } - **/ -fun BytecodePatchContext.firstMethodOrNull(predicate: context(MatchContext) Method.() -> Boolean) = - classDefs.firstMethodOrNull(predicate) - -fun BytecodePatchContext.firstMethod(predicate: context(MatchContext) Method.() -> Boolean) = - requireNotNull(firstMethodOrNull(predicate)) - -fun BytecodePatchContext.firstMethodMutableOrNull(predicate: context(MatchContext) Method.() -> Boolean) = - classDefs.firstMethodOrNull(predicate)?.let { method -> - lookupMaps.classDefsByType[method.definingClass]!!.mutable().methods.first { - MethodUtil.methodSignaturesMatch(method, it) - } - } - -fun BytecodePatchContext.firstMethodMutable(predicate: context(MatchContext) Method.() -> Boolean) = - requireNotNull(firstMethodMutableOrNull(predicate)) - -fun BytecodePatchContext.firstMethodOrNull( - vararg strings: String, - predicate: context(MatchContext) Method.() -> Boolean = { true }, -) = with(MatchContext()) { - strings.mapNotNull { lookupMaps.methodsByStrings[it] }.minByOrNull { it.size }?.firstOrNull { it.predicate() } -} - -fun BytecodePatchContext.firstMethod( - vararg strings: String, - predicate: context(MatchContext) Method.() -> Boolean = { true }, -) = requireNotNull(firstMethodOrNull(*strings, predicate = predicate)) - -fun BytecodePatchContext.firstMethodMutableOrNull( - vararg strings: String, - predicate: context(MatchContext) Method.() -> Boolean = { true }, -) = with(MatchContext()) { - strings.mapNotNull { lookupMaps.methodsByStrings[it] }.minByOrNull { it.size }?.let { methods -> - methods.firstOrNull { it.predicate() }?.let { method -> - firstClassDefMutable(method.definingClass).methods.first { - MethodUtil.methodSignaturesMatch( - method, it - ) - } - } - } -} - -fun BytecodePatchContext.firstMethodMutable( - vararg strings: String, predicate: context(MatchContext) Method.() -> Boolean = { true } -) = requireNotNull(firstMethodMutableOrNull(*strings, predicate = predicate)) - -class CachedReadOnlyProperty internal constructor( - private val block: BytecodePatchContext.(KProperty<*>) -> T -) : ReadOnlyProperty { - private var value: T? = null - private var cached = false - - override fun getValue(thisRef: BytecodePatchContext, property: KProperty<*>): T { - if (!cached) { - value = thisRef.block(property) - cached = true - } - - return value!! - } -} - -fun gettingFirstClassDefOrNull(predicate: context(MatchContext) ClassDef.() -> Boolean) = - CachedReadOnlyProperty { firstClassDefOrNull(predicate) } - -fun gettingFirstClassDef(predicate: context(MatchContext) ClassDef.() -> Boolean) = - CachedReadOnlyProperty { firstClassDef(predicate) } - -fun gettingFirstClassDefMutableOrNull(predicate: context(MatchContext) ClassDef.() -> Boolean) = - CachedReadOnlyProperty { firstClassDefMutableOrNull(predicate) } - -fun gettingFirstClassDefMutable(predicate: context(MatchContext) ClassDef.() -> Boolean) = - CachedReadOnlyProperty { firstClassDefMutable(predicate) } - -fun gettingFirstClassDefOrNull( - type: String, predicate: (context(MatchContext) ClassDef.() -> Boolean)? = null -) = CachedReadOnlyProperty { firstClassDefOrNull(type, predicate) } - -fun gettingFirstClassDef( - type: String, predicate: (context(MatchContext) ClassDef.() -> Boolean)? = null -) = CachedReadOnlyProperty { firstClassDef(type, predicate) } - -fun gettingFirstClassDefMutableOrNull( - type: String, predicate: (context(MatchContext) ClassDef.() -> Boolean)? = null -) = CachedReadOnlyProperty { firstClassDefMutableOrNull(type, predicate) } - -fun gettingFirstClassDefMutable( - type: String, predicate: (context(MatchContext) ClassDef.() -> Boolean)? = null -) = CachedReadOnlyProperty { firstClassDefMutable(type, predicate) } - -fun gettingFirstMethodOrNull(predicate: context(MatchContext) Method.() -> Boolean) = - CachedReadOnlyProperty { firstMethodOrNull(predicate) } - -fun gettingFirstMethod(predicate: context(MatchContext) Method.() -> Boolean) = - CachedReadOnlyProperty { firstMethod(predicate) } - -fun gettingFirstMethodMutableOrNull(predicate: context(MatchContext) Method.() -> Boolean) = - CachedReadOnlyProperty { firstMethodMutableOrNull(predicate) } - -fun gettingFirstMethodMutable(predicate: context(MatchContext) Method.() -> Boolean) = - CachedReadOnlyProperty { firstMethodMutable(predicate) } - -fun gettingFirstMethodOrNull( - vararg strings: String, - predicate: context(MatchContext) Method.() -> Boolean = { true }, -) = CachedReadOnlyProperty { firstMethodOrNull(*strings, predicate = predicate) } - -fun gettingFirstMethod( - vararg strings: String, - predicate: context(MatchContext) Method.() -> Boolean = { true }, -) = CachedReadOnlyProperty { firstMethod(*strings, predicate = predicate) } - -fun gettingFirstMethodMutableOrNull( - vararg strings: String, - predicate: context(MatchContext) Method.() -> Boolean = { true }, -) = CachedReadOnlyProperty { firstMethodMutableOrNull(*strings, predicate = predicate) } - -fun gettingFirstMethodMutable( - vararg strings: String, - predicate: context(MatchContext) Method.() -> Boolean = { true }, -) = CachedReadOnlyProperty { firstMethodMutable(*strings, predicate = predicate) } - -fun indexedMatcher() = IndexedMatcher() - -fun indexedMatcher(build: IndexedMatcher.() -> Unit) = - IndexedMatcher().apply(build) - -fun Iterable.matchIndexed(build: IndexedMatcher.() -> Unit) = - indexedMatcher(build)(this) - -context(_: MatchContext) -fun Iterable.matchIndexed(key: Any, build: IndexedMatcher.() -> Unit) = - indexedMatcher()(key, this, build) - -context(_: MatchContext) -operator fun IndexedMatcher.invoke(key: Any, iterable: Iterable, builder: IndexedMatcher.() -> Unit) = - remember(key) { apply(builder) }(iterable) - -context(_: MatchContext) -operator fun IndexedMatcher.invoke(iterable: Iterable, builder: IndexedMatcher.() -> Unit) = - invoke(this@invoke.hashCode(), iterable, builder) - -abstract class Matcher : MutableList by mutableListOf() { - var matchIndex = -1 - protected set - - abstract operator fun invoke(haystack: Iterable): Boolean - - class MatchContext internal constructor() : MutableMap by mutableMapOf() -} - -context(context: MatchContext) -inline fun remember(key: Any, defaultValue: () -> V) = - context[key] as? V ?: defaultValue().also { context[key] = it } - -class IndexedMatcher() : Matcher Boolean>() { - private val _indices: MutableList = mutableListOf() - val indices: List = _indices - - private var lastMatchedIndex = -1 - private var currentIndex = -1 - - private var nextIndex: Int? = null - - override fun invoke(haystack: Iterable): Boolean { - // Normalize to list - val hay = haystack as? List ?: haystack.toList() - - _indices.clear() - this@IndexedMatcher.lastMatchedIndex = -1 - currentIndex = -1 - - data class Frame( - val patternIndex: Int, - val lastMatchedIndex: Int, - val previousFrame: Frame?, - var nextHayIndex: Int, - val matchedIndex: Int - ) - - val stack = ArrayDeque() - stack.add( - Frame( - patternIndex = 0, - lastMatchedIndex = -1, - previousFrame = null, - nextHayIndex = 0, - matchedIndex = -1 - ) - ) - - while (stack.isNotEmpty()) { - val frame = stack.last() - - if (frame.nextHayIndex >= hay.size || nextIndex == -1) { - stack.removeLast() - nextIndex = null - continue - } - - val i = frame.nextHayIndex - currentIndex = i - lastMatchedIndex = frame.lastMatchedIndex - nextIndex = null - - if (this[frame.patternIndex](hay[i], lastMatchedIndex, currentIndex)) { - Frame( - patternIndex = frame.patternIndex + 1, - lastMatchedIndex = i, - previousFrame = frame, - nextHayIndex = i + 1, - matchedIndex = i - ).also { - if (it.patternIndex == size) { - _indices += buildList(size) { - var f: Frame? = it - while (f != null && f.matchedIndex != -1) { - add(f.matchedIndex) - f = f.previousFrame - } - }.asReversed() - - return true - } - }.let(stack::add) - } - - frame.nextHayIndex = when (val nextIndex = nextIndex) { - null -> frame.nextHayIndex + 1 - -1 -> 0 // Frame will be removed next loop. - else -> nextIndex - } - } - - return false - } - - fun head(predicate: T.(lastMatchedIndex: Int, currentIndex: Int) -> Boolean) = - add { lastMatchedIndex, currentIndex -> - currentIndex == 0 && predicate(lastMatchedIndex, currentIndex) - } - - fun head(predicate: T.() -> Boolean) = - head { _, _ -> predicate() } - - fun after(range: IntRange = 1..1, predicate: T.(lastMatchedIndex: Int, currentIndex: Int) -> Boolean) = - add { lastMatchedIndex, currentIndex -> - val distance = currentIndex - lastMatchedIndex - - nextIndex = when { - distance < range.first -> lastMatchedIndex + range.first - distance > range.last -> -1 - else -> return@add predicate(lastMatchedIndex, currentIndex) - } - - false - } - - fun after(range: IntRange = 1..1, predicate: T.() -> Boolean) = - after(range) { _, _ -> predicate() } - - fun add(predicate: T.() -> Boolean) = add { _, _ -> predicate() } -} - -fun T.declarativePredicate(build: DeclarativePredicateBuilder.() -> Unit) = - DeclarativePredicateBuilder().apply(build).all(this) - -context(_: MatchContext) -fun T.rememberDeclarativePredicate(key: Any, block: DeclarativePredicateBuilder.() -> Unit): Boolean = - remember(key) { DeclarativePredicateBuilder().apply(block) }.all(this) - -context(_: MatchContext) -private fun T.rememberDeclarativePredicate(predicate: context(MatchContext, T) DeclarativePredicateBuilder.() -> Unit) = - rememberDeclarativePredicate("declarative predicate build") { predicate() } - -fun BytecodePatchContext.firstClassDefByDeclarativePredicateOrNull( - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = firstClassDefOrNull { rememberDeclarativePredicate(predicate) } - -fun BytecodePatchContext.firstClassDefByDeclarativePredicate( - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = requireNotNull(firstClassDefByDeclarativePredicateOrNull(predicate)) - -fun BytecodePatchContext.firstClassDefMutableByDeclarativePredicateOrNull( - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = firstClassDefMutableOrNull { rememberDeclarativePredicate(predicate) } - -fun BytecodePatchContext.firstClassDefMutableByDeclarativePredicate( - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = requireNotNull(firstClassDefMutableByDeclarativePredicateOrNull(predicate)) - -fun BytecodePatchContext.firstClassDefByDeclarativePredicateOrNull( - type: String, - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = firstClassDefOrNull(type) { rememberDeclarativePredicate(predicate) } - -fun BytecodePatchContext.firstClassDefByDeclarativePredicate( - type: String, - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = requireNotNull(firstClassDefByDeclarativePredicateOrNull(type, predicate)) - -fun BytecodePatchContext.firstClassDefMutableByDeclarativePredicateOrNull( - type: String, - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = firstClassDefMutableOrNull(type) { rememberDeclarativePredicate(predicate) } - -fun BytecodePatchContext.firstClassDefMutableByDeclarativePredicate( - type: String, - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = requireNotNull(firstClassDefMutableByDeclarativePredicateOrNull(type, predicate)) - -fun BytecodePatchContext.firstMethodByDeclarativePredicateOrNull( - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = firstMethodOrNull { rememberDeclarativePredicate(predicate) } - -fun BytecodePatchContext.firstMethodByDeclarativePredicate( - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = requireNotNull(firstMethodByDeclarativePredicateOrNull(predicate)) - -fun BytecodePatchContext.firstMethodMutableByDeclarativePredicateOrNull( - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = firstMethodMutableOrNull { rememberDeclarativePredicate(predicate) } - -fun BytecodePatchContext.firstMethodMutableByDeclarativePredicate( - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = requireNotNull(firstMethodMutableByDeclarativePredicateOrNull(predicate)) - -fun BytecodePatchContext.firstMethodByDeclarativePredicateOrNull( - vararg strings: String, - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = firstMethodOrNull(*strings) { rememberDeclarativePredicate(predicate) } - -fun BytecodePatchContext.firstMethodByDeclarativePredicate( - vararg strings: String, - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = requireNotNull(firstMethodByDeclarativePredicateOrNull(*strings, predicate = predicate)) - -fun BytecodePatchContext.firstMethodMutableByDeclarativePredicateOrNull( - vararg strings: String, - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = firstMethodMutableOrNull(*strings) { rememberDeclarativePredicate(predicate) } - -fun BytecodePatchContext.firstMethodMutableByDeclarativePredicate( - vararg strings: String, - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = requireNotNull(firstMethodMutableByDeclarativePredicateOrNull(*strings, predicate = predicate)) - -fun gettingFirstClassDefByDeclarativePredicateOrNull( - type: String, - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = gettingFirstClassDefOrNull(type) { rememberDeclarativePredicate(predicate) } - -fun gettingFirstClassDefByDeclarativePredicate( - type: String, - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = CachedReadOnlyProperty { firstClassDefByDeclarativePredicate(type, predicate) } - -fun gettingFirstClassDefMutableByDeclarativePredicateOrNull( - type: String, - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = gettingFirstClassDefMutableOrNull(type) { rememberDeclarativePredicate(predicate) } - -fun gettingFirstClassDefMutableByDeclarativePredicate( - type: String, - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = CachedReadOnlyProperty { firstClassDefMutableByDeclarativePredicate(type, predicate) } - -fun gettingFirstClassDefByDeclarativePredicateOrNull( - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = gettingFirstClassDefOrNull { rememberDeclarativePredicate(predicate) } - -fun gettingFirstClassDefByDeclarativePredicate( - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = CachedReadOnlyProperty { firstClassDefByDeclarativePredicate(predicate) } - -fun gettingFirstClassDefMutableByDeclarativePredicateOrNull( - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = gettingFirstClassDefMutableOrNull { rememberDeclarativePredicate(predicate) } - -fun gettingFirstClassDefMutableByDeclarativePredicate( - predicate: context(MatchContext, ClassDef) DeclarativePredicateBuilder.() -> Unit -) = CachedReadOnlyProperty { firstClassDefMutableByDeclarativePredicate(predicate) } - -fun gettingFirstMethodByDeclarativePredicateOrNull( - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = gettingFirstMethodOrNull { rememberDeclarativePredicate(predicate) } - -fun gettingFirstMethodByDeclarativePredicate( - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = CachedReadOnlyProperty { firstMethodByDeclarativePredicate(predicate = predicate) } - -fun gettingFirstMethodMutableByDeclarativePredicateOrNull( - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = gettingFirstMethodMutableOrNull { rememberDeclarativePredicate(predicate) } - -fun gettingFirstMethodMutableByDeclarativePredicate( - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = CachedReadOnlyProperty { firstMethodMutableByDeclarativePredicate(predicate = predicate) } - -fun gettingFirstMethodByDeclarativePredicateOrNull( - vararg strings: String, - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = gettingFirstMethodOrNull(*strings) { rememberDeclarativePredicate(predicate) } - -fun gettingFirstMethodByDeclarativePredicate( - vararg strings: String, - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = CachedReadOnlyProperty { firstMethodByDeclarativePredicate(*strings, predicate = predicate) } - -fun gettingFirstMethodMutableByDeclarativePredicateOrNull( - vararg strings: String, - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = gettingFirstMethodMutableOrNull(*strings) { rememberDeclarativePredicate(predicate) } - -fun gettingFirstMethodMutableByDeclarativePredicate( - vararg strings: String, - predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) = CachedReadOnlyProperty { firstMethodMutableByDeclarativePredicate(*strings, predicate = predicate) } - - -class DeclarativePredicateBuilder internal constructor() { - private val children = mutableListOf Boolean>() - - fun anyOf(block: DeclarativePredicateBuilder.() -> Unit) { - val child = DeclarativePredicateBuilder().apply(block) - children += { child.children.any { it() } } - } - - fun predicate(block: T.() -> Boolean) { - children += block - } - - fun all(target: T): Boolean = children.all { target.it() } - fun any(target: T): Boolean = children.all { target.it() } -} - -fun firstMethodComposite( - predicate: - context(MatchContext, Method, IndexedMatcher) DeclarativePredicateBuilder.() -> Unit -) = with(indexedMatcher()) { Composition(indices = this.indices) { predicate() } } - -fun DeclarativePredicateBuilder.accessFlags(vararg flags: AccessFlags) { - predicate { accessFlags(*flags) } -} - -fun DeclarativePredicateBuilder.returns(returnType: String) { - predicate { this.returnType.startsWith(returnType) } -} - -fun DeclarativePredicateBuilder.parameterTypes(vararg parameterTypes: String) = predicate { - this.parameterTypes.size == parameterTypes.size && this.parameterTypes.zip(parameterTypes) - .all { (a, b) -> a.startsWith(b) } -} - -context(_: MatchContext, indexedMatcher: IndexedMatcher) -fun DeclarativePredicateBuilder.instructions( - build: context(MatchContext, Method) IndexedMatcher.() -> Unit -) = predicate { implementation { indexedMatcher(indexedMatcher.hashCode(), instructions) { build() } } } - -context(_: MatchContext) -fun DeclarativePredicateBuilder.custom(block: context(MatchContext) Method.() -> Boolean) { - predicate { block() } -} - -class Composition internal constructor( - val indices: List, - private val predicate: context(MatchContext, Method) DeclarativePredicateBuilder.() -> Unit -) { - private var _methodOrNull: MutableMethod? = null - - context(context: BytecodePatchContext) - val methodOrNull: MutableMethod? - get() { - if (_methodOrNull == null) { - _methodOrNull = context.firstMethodMutableByDeclarativePredicateOrNull(predicate) - } - - return _methodOrNull - } - - context(_: BytecodePatchContext) - val method get() = requireNotNull(methodOrNull) -} diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableMethodParameter.kt b/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableMethodParameter.kt deleted file mode 100644 index 57097fe..0000000 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/MutableMethodParameter.kt +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.patcher.dex.mutable - -import app.revanced.patcher.dex.mutable.MutableAnnotation.Companion.toMutable -import com.android.tools.smali.dexlib2.base.BaseMethodParameter -import com.android.tools.smali.dexlib2.iface.MethodParameter - -// TODO: finish overriding all members if necessary -class MutableMethodParameter(parameter: MethodParameter) : - BaseMethodParameter(), - MethodParameter { - private var type = parameter.type - private var name = parameter.name - private var signature = parameter.signature - private val _annotations by lazy { - parameter.annotations.map { annotation -> annotation.toMutable() }.toMutableSet() - } - - override fun getType(): String = type - - override fun getName(): String? = name - - override fun getSignature(): String? = signature - - override fun getAnnotations(): MutableSet = _annotations - - companion object { - fun MethodParameter.toMutable(): MutableMethodParameter = MutableMethodParameter(this) - } -} diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableArrayEncodedValue.kt b/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableArrayEncodedValue.kt deleted file mode 100644 index 69b0664..0000000 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableArrayEncodedValue.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.revanced.patcher.dex.mutable.encodedValue - -import app.revanced.patcher.dex.mutable.encodedValue.MutableEncodedValue.Companion.toMutable -import com.android.tools.smali.dexlib2.base.value.BaseArrayEncodedValue -import com.android.tools.smali.dexlib2.iface.value.ArrayEncodedValue -import com.android.tools.smali.dexlib2.iface.value.EncodedValue - -class MutableArrayEncodedValue(arrayEncodedValue: ArrayEncodedValue) : - BaseArrayEncodedValue(), - MutableEncodedValue { - private val _value by lazy { - arrayEncodedValue.value.map { encodedValue -> encodedValue.toMutable() }.toMutableList() - } - - override fun getValue(): MutableList = _value - - companion object { - fun ArrayEncodedValue.toMutable(): MutableArrayEncodedValue = MutableArrayEncodedValue(this) - } -} diff --git a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableNullEncodedValue.kt b/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableNullEncodedValue.kt deleted file mode 100644 index 25ca990..0000000 --- a/src/main/kotlin/app/revanced/patcher/dex/mutable/encodedValue/MutableNullEncodedValue.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patcher.dex.mutable.encodedValue - -import com.android.tools.smali.dexlib2.base.value.BaseNullEncodedValue -import com.android.tools.smali.dexlib2.iface.value.ByteEncodedValue - -class MutableNullEncodedValue : - BaseNullEncodedValue(), - MutableEncodedValue { - companion object { - fun ByteEncodedValue.toMutable(): MutableByteEncodedValue = MutableByteEncodedValue(this) - } -} diff --git a/src/main/kotlin/app/revanced/patcher/patch/BytecodePatchContext.kt b/src/main/kotlin/app/revanced/patcher/patch/BytecodePatchContext.kt deleted file mode 100644 index b1727de..0000000 --- a/src/main/kotlin/app/revanced/patcher/patch/BytecodePatchContext.kt +++ /dev/null @@ -1,228 +0,0 @@ -package app.revanced.patcher.patch - -import app.revanced.patcher.InternalApi -import app.revanced.patcher.PatcherConfig -import app.revanced.patcher.PatcherResult -import app.revanced.patcher.dex.mutable.MutableClassDef -import app.revanced.patcher.dex.mutable.MutableClassDef.Companion.toMutable -import app.revanced.patcher.extensions.instructionsOrNull -import app.revanced.patcher.util.ClassMerger.merge -import app.revanced.patcher.util.MethodNavigator -import com.android.tools.smali.dexlib2.Opcodes -import com.android.tools.smali.dexlib2.iface.ClassDef -import com.android.tools.smali.dexlib2.iface.DexFile -import com.android.tools.smali.dexlib2.iface.Method -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import com.android.tools.smali.dexlib2.iface.reference.StringReference -import lanchon.multidexlib2.BasicDexFileNamer -import lanchon.multidexlib2.DexIO -import lanchon.multidexlib2.MultiDexIO -import lanchon.multidexlib2.RawDexIO -import java.io.Closeable -import java.io.IOException -import java.util.LinkedHashMap -import java.util.logging.Logger - - -/** - * A context for patches containing the current state of the bytecode. - * - * @param config The [PatcherConfig] used to create this context. - */ -@Suppress("MemberVisibilityCanBePrivate") -class BytecodePatchContext internal constructor(private val config: PatcherConfig) : - PatchContext>, - Closeable { - private val logger = Logger.getLogger(this::class.java.name) - - /** - * [Opcodes] of the supplied [PatcherConfig.apkFile]. - */ - internal val opcodes: Opcodes - - /** - * The list of classes. - */ - val classDefs = MultiDexIO.readDexFile( - true, - config.apkFile, - BasicDexFileNamer(), - null, - null, - ).also { opcodes = it.opcodes }.classes.toMutableSet() - - /** - * The lookup maps for methods and the class they are a member of from the [classDefs]. - */ - internal val lookupMaps by lazy { _lookupMaps ?: LookupMaps().also { _lookupMaps = it } } - private var _lookupMaps: LookupMaps? = null // For freeing up memory when compiling. - - /** - * Merge the extension of [bytecodePatch] into the [BytecodePatchContext]. - * If no extension is present, the function will return early. - * - * @param bytecodePatch The [BytecodePatch] to merge the extension of. - */ - internal fun mergeExtension(bytecodePatch: BytecodePatch) { - bytecodePatch.extensionInputStream?.get()?.use { extensionStream -> - RawDexIO.readRawDexFile(extensionStream, 0, null).classes.forEach { classDef -> - val existingClass = lookupMaps.classDefsByType[classDef.type] ?: run { - logger.fine { "Adding class \"$classDef\"" } - - classDefs += classDef - lookupMaps += classDef - - return@forEach - } - - logger.fine { "Class \"$classDef\" exists already. Adding missing methods and fields." } - - existingClass.merge(classDef, this@BytecodePatchContext).let { mergedClass -> - // If the class was merged, replace the original class with the merged class. - if (mergedClass === existingClass) { - return@let - } - - classDefs -= existingClass - lookupMaps -= existingClass - - classDefs += mergedClass - lookupMaps += mergedClass - } - } - } ?: logger.fine("No extension to merge") - } - - /** - * Convert a [ClassDef] to a [MutableClassDef]. - * If the [ClassDef] is already a [MutableClassDef], it is returned as is. - * - * @return The mutable version of the [ClassDef]. - */ - fun ClassDef.mutable(): MutableClassDef = this as? MutableClassDef ?: also { - classDefs -= this - lookupMaps -= this - }.toMutable().also { - classDefs += it - lookupMaps += it - } - - /** - * Navigate a method. - * - * @param method The method to navigate. - * - * @return A [MethodNavigator] for the method. - */ - fun navigate(method: MethodReference) = MethodNavigator(method) - - /** - * Compile bytecode from the [BytecodePatchContext]. - * - * @return The compiled bytecode. - */ - @InternalApi - override fun get(): Set { - logger.info("Compiling patched dex files") - - // Free up memory before compiling the dex files. - close() - System.gc() - - val patchedDexFileResults = - config.patchedFiles.resolve("dex").also { - it.deleteRecursively() // Make sure the directory is empty. - it.mkdirs() - }.apply { - MultiDexIO.writeDexFile( - true, - -1, - this, - BasicDexFileNamer(), - object : DexFile { - override fun getClasses() = this@BytecodePatchContext.classDefs.let { - // More performant according to - // https://github.com/LisoUseInAIKyrios/revanced-patcher/commit/8c26ad08457fb1565ea5794b7930da42a1c81cf1#diff-be698366d9868784ecf7da3fd4ac9d2b335b0bb637f9f618fbe067dbd6830b8fR197 - // TODO: Benchmark, if actually faster. - HashSet(it.size * 3 / 2).apply { addAll(it) } - } - - override fun getOpcodes() = this@BytecodePatchContext.opcodes - }, - DexIO.DEFAULT_MAX_DEX_POOL_SIZE, - ) { _, entryName, _ -> logger.info { "Compiled $entryName" } } - }.listFiles { it.isFile }!!.map { - PatcherResult.PatchedDexFile(it.name, it.inputStream()) - }.toSet() - - // Free up more memory, although it is unclear if this is actually helpful. - classDefs.clear() - System.gc() - - return patchedDexFileResults - } - - override fun close() { - try { - _lookupMaps = null - } catch (e: IOException) { - logger.warning("Failed to clear BytecodePatchContext: ${e.message}") - } - } - - internal inner class LookupMaps { - // No custom HashMap needed here, according to - // https://github.com/LisoUseInAIKyrios/revanced-patcher/commit/9b6d95d4f414a35ed68da37b0ecd8549df1ef63a - // TODO: Benchmark, if actually faster. - private val _classDefsByType = mutableMapOf() - val classDefsByType: Map = _classDefsByType - - // Better performance according to - // https://github.com/LisoUseInAIKyrios/revanced-patcher/commit/9b6d95d4f414a35ed68da37b0ecd8549df1ef63a - private val _methodsByStrings = - LinkedHashMap>(2 * classDefs.size, 0.5f) - - val methodsByStrings: Map> = _methodsByStrings - - private val _methodsWithString = methodsByStrings.values.flatten().toMutableSet() - val methodsWithString: Set = _methodsWithString - - init { - classDefs.forEach(::plusAssign) - } - - private fun ClassDef.forEachString(action: (Method, String) -> Unit) = methods.asSequence().forEach { method -> - method.instructionsOrNull?.asSequence() - ?.filterIsInstance() - ?.map { it.reference } - ?.filterIsInstance() - ?.map { it.string } - ?.forEach { string -> - action(method, string) - } - } - - operator fun plusAssign(classDef: ClassDef) { - _classDefsByType[classDef.type] = classDef - - classDef.forEachString { method, string -> - _methodsWithString += method - _methodsByStrings.getOrPut(string) { - mutableListOf() - } += method - } - } - - operator fun minusAssign(classDef: ClassDef) { - _classDefsByType -= classDef.type - - classDef.forEachString { method, string -> - _methodsWithString.remove(method) - - if (_methodsByStrings[string]?.also { it -= method }?.isEmpty() == true) - _methodsByStrings -= string - } - } - } -} diff --git a/src/main/resources/app/revanced/patcher/version.properties b/src/main/resources/app/revanced/patcher/version.properties deleted file mode 100644 index 308c9f8..0000000 --- a/src/main/resources/app/revanced/patcher/version.properties +++ /dev/null @@ -1 +0,0 @@ -version=${projectVersion} \ No newline at end of file