chore: Merge branch dev to main (#257)

This commit is contained in:
oSumAtrIX 2023-10-23 01:56:40 +02:00 committed by GitHub
commit 49ed096e85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
110 changed files with 2054 additions and 2772 deletions

View file

@ -1,3 +1,92 @@
# [18.0.0-dev.6](https://github.com/ReVanced/revanced-patcher/compare/v18.0.0-dev.5...v18.0.0-dev.6) (2023-10-22)
### Bug Fixes
* Only allow setting `MethodFingerprint#result` privately ([aed1eac](https://github.com/ReVanced/revanced-patcher/commit/aed1eac3157317acf87f522750cf2f41509606c3))
### Code Refactoring
* Change data classes to actual classes ([6192089](https://github.com/ReVanced/revanced-patcher/commit/6192089b71bdca15765369f3e607ddd1f8266205))
* Convert extension functions to member functions ([e2ca507](https://github.com/ReVanced/revanced-patcher/commit/e2ca50729da7085799c0ff6fc4f7afaf82579738))
* Move files to simplify package structure ([124a2e9](https://github.com/ReVanced/revanced-patcher/commit/124a2e9d3efb88f0f038ae306d941e918ad3ad3c))
* Remove deprecated classes and members ([a4212f6](https://github.com/ReVanced/revanced-patcher/commit/a4212f6bf952971541c4550e20f6bf57a382e19a))
* refactor!: Remove `Fingerprint` interface ([54a2f8f](https://github.com/ReVanced/revanced-patcher/commit/54a2f8f16fddf2b2ed47eb23717ba3734c4a6c5d))
### BREAKING CHANGES
* The `MethodFingerprint#result` member can now only be set inside `MethodFingerprint`.
* The `Fingerprint` interface is no longer present.
* Some extension functions are now member functions.
* This gets rid of data class members.
* Some deprecated classes and members are not present anymore.
* Classes and members have changed packages.
# [18.0.0-dev.5](https://github.com/ReVanced/revanced-patcher/compare/v18.0.0-dev.4...v18.0.0-dev.5) (2023-10-22)
### Bug Fixes
* Do not set patch fields if they are empty ([a76ac04](https://github.com/ReVanced/revanced-patcher/commit/a76ac04214a2ab91e3b2f9dddb13ed52816fe723))
# [18.0.0-dev.4](https://github.com/ReVanced/revanced-patcher/compare/v18.0.0-dev.3...v18.0.0-dev.4) (2023-10-22)
### Features
* Use a map for `PatchOption#values` ([54ac139](https://github.com/ReVanced/revanced-patcher/commit/54ac1394a914d3eed7865ec697e8016834134911))
# [18.0.0-dev.3](https://github.com/ReVanced/revanced-patcher/compare/v18.0.0-dev.2...v18.0.0-dev.3) (2023-10-22)
### Features
* Make `PatchOption#values` nullable ([56ce9ec](https://github.com/ReVanced/revanced-patcher/commit/56ce9ec2f98ff351c3d42df71b49e5c88f07e665))
# [18.0.0-dev.2](https://github.com/ReVanced/revanced-patcher/compare/v18.0.0-dev.1...v18.0.0-dev.2) (2023-10-22)
### Code Refactoring
* Change `PatchOption` from abstract to open class ([09cd6aa](https://github.com/ReVanced/revanced-patcher/commit/09cd6aa568988dd5241bfa6a2e12b7926a7b0683))
### Features
* Add function to reset options to their default value ([ebbaafb](https://github.com/ReVanced/revanced-patcher/commit/ebbaafb78e88f34faeafe9ff8532afe29231bd79))
* Add function to reset options to their default value ([e6de90d](https://github.com/ReVanced/revanced-patcher/commit/e6de90d300bc9c82ca1696cb898db04c65a1cd5b))
* Add getter for default option value ([c7922e9](https://github.com/ReVanced/revanced-patcher/commit/c7922e90d0c6ae83f513611c706ebea33c1a2b63))
* Name patch option value validator property correctly ([caa634f](https://github.com/ReVanced/revanced-patcher/commit/caa634fac6d7a717f54e3b015827c8858fd637b9))
### BREAKING CHANGES
* This gets rid of the existing basic implementations of the `PatchOptions` type and moves extension functions.
* This changes the getter name of the property.
# [18.0.0-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v17.0.1-dev.1...v18.0.0-dev.1) (2023-10-14)
### Features
* Remove patch annotation processor ([4456031](https://github.com/ReVanced/revanced-patcher/commit/445603145979a6f67823a79f9d6cd140299cff37))
### BREAKING CHANGES
* Various patch constructor signatures have changed.
## [17.0.1-dev.1](https://github.com/ReVanced/revanced-patcher/compare/v17.0.0...v17.0.1-dev.1) (2023-10-10)
### Performance Improvements
* Run the garbage collector after writing dex files ([d9fb241](https://github.com/ReVanced/revanced-patcher/commit/d9fb241d57b0c4340130c0e5900250e66730ea56))
# [17.0.0](https://github.com/ReVanced/revanced-patcher/compare/v16.0.2...v17.0.0) (2023-10-09)

View file

@ -0,0 +1,769 @@
public abstract interface class app/revanced/patcher/IntegrationsConsumer {
public abstract fun acceptIntegrations (Ljava/util/List;)V
}
public final class app/revanced/patcher/PackageMetadata {
public final fun getPackageName ()Ljava/lang/String;
public final fun getPackageVersion ()Ljava/lang/String;
}
public abstract class app/revanced/patcher/PatchBundleLoader : java/util/Set, kotlin/jvm/internal/markers/KMappedMarker {
public synthetic fun <init> (Ljava/lang/ClassLoader;[Ljava/io/File;Lkotlin/jvm/functions/Function1;Ljava/util/Set;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
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 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/PatchBundleLoader$Dex : app/revanced/patcher/PatchBundleLoader {
public fun <init> ([Ljava/io/File;)V
public fun <init> ([Ljava/io/File;Ljava/io/File;)V
public synthetic fun <init> ([Ljava/io/File;Ljava/io/File;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/PatchBundleLoader$Jar : app/revanced/patcher/PatchBundleLoader {
public fun <init> ([Ljava/io/File;)V
}
public abstract interface class app/revanced/patcher/PatchExecutorFunction : java/util/function/Function {
}
public final class app/revanced/patcher/Patcher : app/revanced/patcher/IntegrationsConsumer, app/revanced/patcher/PatchExecutorFunction, app/revanced/patcher/PatchesConsumer, java/io/Closeable, java/util/function/Supplier {
public fun <init> (Lapp/revanced/patcher/PatcherOptions;)V
public fun acceptIntegrations (Ljava/util/List;)V
public fun acceptPatches (Ljava/util/List;)V
public synthetic fun apply (Ljava/lang/Object;)Ljava/lang/Object;
public fun apply (Z)Lkotlinx/coroutines/flow/Flow;
public fun close ()V
public fun get ()Lapp/revanced/patcher/PatcherResult;
public synthetic fun get ()Ljava/lang/Object;
public final fun getContext ()Lapp/revanced/patcher/PatcherContext;
}
public final class app/revanced/patcher/PatcherContext {
public final fun getPackageMetadata ()Lapp/revanced/patcher/PackageMetadata;
}
public abstract class app/revanced/patcher/PatcherException : java/lang/Exception {
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Throwable;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/PatcherException$CircularDependencyException : app/revanced/patcher/PatcherException {
}
public final class app/revanced/patcher/PatcherOptions {
public fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Z)V
public synthetic fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun copy (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Z)Lapp/revanced/patcher/PatcherOptions;
public static synthetic fun copy$default (Lapp/revanced/patcher/PatcherOptions;Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Lapp/revanced/patcher/PatcherOptions;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public final fun recreateResourceCacheDirectory ()Ljava/io/File;
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/PatcherResult {
public fun <init> (Ljava/util/List;Ljava/io/File;Ljava/util/List;)V
public synthetic fun <init> (Ljava/util/List;Ljava/io/File;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/util/List;
public final fun component2 ()Ljava/io/File;
public final fun component3 ()Ljava/util/List;
public final fun copy (Ljava/util/List;Ljava/io/File;Ljava/util/List;)Lapp/revanced/patcher/PatcherResult;
public static synthetic fun copy$default (Lapp/revanced/patcher/PatcherResult;Ljava/util/List;Ljava/io/File;Ljava/util/List;ILjava/lang/Object;)Lapp/revanced/patcher/PatcherResult;
public fun equals (Ljava/lang/Object;)Z
public final fun getDexFiles ()Ljava/util/List;
public final fun getDoNotCompress ()Ljava/util/List;
public final fun getResourceFile ()Ljava/io/File;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/PatcherResult$PatchedDexFile {
public fun <init> (Ljava/lang/String;Ljava/io/InputStream;)V
public final fun getName ()Ljava/lang/String;
public final fun getStream ()Ljava/io/InputStream;
}
public abstract interface class app/revanced/patcher/PatchesConsumer {
public abstract fun acceptPatches (Ljava/util/List;)V
}
public final class app/revanced/patcher/data/BytecodeContext : app/revanced/patcher/data/Context {
public final fun findClass (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun findClass (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public synthetic fun get ()Ljava/lang/Object;
public fun get ()Ljava/util/List;
public final fun getClasses ()Lapp/revanced/patcher/util/ProxyClassList;
public final fun proxy (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun toMethodWalker (Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/method/MethodWalker;
}
public abstract interface class app/revanced/patcher/data/Context : java/util/function/Supplier {
}
public final class app/revanced/patcher/data/ResourceContext : app/revanced/patcher/data/Context, java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker {
public fun get ()Ljava/io/File;
public synthetic fun get ()Ljava/lang/Object;
public final fun get (Ljava/lang/String;)Ljava/io/File;
public final fun getXmlEditor ()Lapp/revanced/patcher/data/ResourceContext$XmlFileHolder;
public fun iterator ()Ljava/util/Iterator;
}
public final class app/revanced/patcher/data/ResourceContext$XmlFileHolder {
public fun <init> (Lapp/revanced/patcher/data/ResourceContext;)V
public final fun get (Ljava/io/InputStream;)Lapp/revanced/patcher/util/DomFileEditor;
public final fun get (Ljava/lang/String;)Lapp/revanced/patcher/util/DomFileEditor;
}
public final class app/revanced/patcher/extensions/ExtensionsKt {
public static final fun newLabel (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/Label;
public static final fun or (ILcom/android/tools/smali/dexlib2/AccessFlags;)I
public static final fun or (Lcom/android/tools/smali/dexlib2/AccessFlags;I)I
public static final fun or (Lcom/android/tools/smali/dexlib2/AccessFlags;Lcom/android/tools/smali/dexlib2/AccessFlags;)I
}
public final class app/revanced/patcher/extensions/InstructionExtensions {
public static final field INSTANCE Lapp/revanced/patcher/extensions/InstructionExtensions;
public final fun addInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V
public final fun addInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
public final fun addInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V
public final fun addInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/String;)V
public final fun addInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
public final fun addInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/util/List;)V
public final fun addInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/String;)V
public final fun addInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/util/List;)V
public final fun addInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V
public final fun addInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;Ljava/util/List;)V
public final fun addInstructionsWithLabels (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;[Lapp/revanced/patcher/util/smali/ExternalLabel;)V
public final fun getInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;
public final fun getInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)Ljava/lang/Object;
public final fun getInstruction (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;
public final fun getInstruction (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)Ljava/lang/Object;
public final fun getInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;)Ljava/util/List;
public final fun removeInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)V
public final fun removeInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)V
public final fun removeInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;II)V
public final fun removeInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)V
public final fun removeInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;II)V
public final fun replaceInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V
public final fun replaceInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
public final fun replaceInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
public final fun replaceInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/util/List;)V
public final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V
}
public final class app/revanced/patcher/extensions/MethodFingerprintExtensions {
public static final field INSTANCE Lapp/revanced/patcher/extensions/MethodFingerprintExtensions;
public final fun getFuzzyPatternScanMethod (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/annotation/FuzzyPatternScanMethod;
}
public abstract class app/revanced/patcher/fingerprint/MethodFingerprint {
public static final field Companion Lapp/revanced/patcher/fingerprint/MethodFingerprint$Companion;
public fun <init> ()V
public fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getResult ()Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
public final fun resolve (Lapp/revanced/patcher/data/BytecodeContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
public final fun resolve (Lapp/revanced/patcher/data/BytecodeContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
}
public final class app/revanced/patcher/fingerprint/MethodFingerprint$Companion {
public final fun resolve (Ljava/lang/Iterable;Lapp/revanced/patcher/data/BytecodeContext;Ljava/lang/Iterable;)V
}
public final class app/revanced/patcher/fingerprint/MethodFingerprintResult {
public fun <init> (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lapp/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult;Lapp/revanced/patcher/data/BytecodeContext;)V
public final fun getClassDef ()Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun getMethod ()Lcom/android/tools/smali/dexlib2/iface/Method;
public final fun getMutableClass ()Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun getMutableMethod ()Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public final fun getScanResult ()Lapp/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult;
}
public final class app/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult {
public fun <init> (Lapp/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;Lapp/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;)V
public final fun getPatternScanResult ()Lapp/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;
public final fun getStringsScanResult ()Lapp/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;
}
public final class app/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult {
public fun <init> (IILjava/util/List;)V
public synthetic fun <init> (IILjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getEndIndex ()I
public final fun getStartIndex ()I
public final fun getWarnings ()Ljava/util/List;
public final fun setWarnings (Ljava/util/List;)V
}
public final class app/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult$Warning {
public fun <init> (Lcom/android/tools/smali/dexlib2/Opcode;Lcom/android/tools/smali/dexlib2/Opcode;II)V
public final fun getCorrectOpcode ()Lcom/android/tools/smali/dexlib2/Opcode;
public final fun getInstructionIndex ()I
public final fun getPatternIndex ()I
public final fun getWrongOpcode ()Lcom/android/tools/smali/dexlib2/Opcode;
}
public final class app/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult {
public fun <init> (Ljava/util/List;)V
public final fun getMatches ()Ljava/util/List;
}
public final class app/revanced/patcher/fingerprint/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult$StringMatch {
public fun <init> (Ljava/lang/String;I)V
public final fun getIndex ()I
public final fun getString ()Ljava/lang/String;
}
public abstract interface annotation class app/revanced/patcher/fingerprint/annotation/FuzzyPatternScanMethod : java/lang/annotation/Annotation {
public abstract fun threshold ()I
}
public abstract class app/revanced/patcher/patch/BytecodePatch : app/revanced/patcher/patch/Patch {
public fun <init> ()V
public fun <init> (Ljava/util/Set;)V
public synthetic fun <init> (Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public abstract class app/revanced/patcher/patch/Patch {
public fun equals (Ljava/lang/Object;)Z
public abstract fun execute (Lapp/revanced/patcher/data/Context;)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/PatchOptions;
public final fun getRequiresIntegrations ()Z
public final fun getUse ()Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/patch/Patch$CompatiblePackage {
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getName ()Ljava/lang/String;
public final fun getVersions ()Ljava/util/Set;
}
public final class app/revanced/patcher/patch/PatchException : java/lang/Exception {
public fun <init> (Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;Ljava/lang/Throwable;)V
public fun <init> (Ljava/lang/Throwable;)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 abstract class app/revanced/patcher/patch/ResourcePatch : app/revanced/patcher/patch/Patch {
public fun <init> ()V
}
public abstract interface annotation class app/revanced/patcher/patch/annotation/CompatiblePackage : java/lang/annotation/Annotation {
public abstract fun name ()Ljava/lang/String;
public abstract fun versions ()[Ljava/lang/String;
}
public abstract interface annotation class app/revanced/patcher/patch/annotation/Patch : java/lang/annotation/Annotation {
public abstract fun compatiblePackages ()[Lapp/revanced/patcher/patch/annotation/CompatiblePackage;
public abstract fun dependencies ()[Ljava/lang/Class;
public abstract fun description ()Ljava/lang/String;
public abstract fun name ()Ljava/lang/String;
public abstract fun requiresIntegrations ()Z
public abstract fun use ()Z
}
public class app/revanced/patcher/patch/options/PatchOption {
public static final field PatchExtensions Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;
public fun <init> (Ljava/lang/String;Ljava/lang/Object;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)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 getRequired ()Z
public final fun getTitle ()Ljava/lang/String;
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 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 final class app/revanced/patcher/patch/options/PatchOption$PatchExtensions {
public final fun booleanArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun booleanArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun booleanPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun booleanPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun floatArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun floatArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun floatPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Float;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun floatPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun intArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun intArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun intPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Integer;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun intPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun longArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun longArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun longPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Long;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun longPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun stringArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun stringArrayPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
public final fun stringPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function2;)Lapp/revanced/patcher/patch/options/PatchOption;
public static synthetic fun stringPatchOption$default (Lapp/revanced/patcher/patch/options/PatchOption$PatchExtensions;Lapp/revanced/patcher/patch/Patch;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/options/PatchOption;
}
public abstract class app/revanced/patcher/patch/options/PatchOptionException : java/lang/Exception {
public synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/PatchOptionException$InvalidValueTypeException : app/revanced/patcher/patch/options/PatchOptionException {
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
}
public final class app/revanced/patcher/patch/options/PatchOptionException$PatchOptionNotFoundException : app/revanced/patcher/patch/options/PatchOptionException {
public fun <init> (Ljava/lang/String;)V
}
public final class app/revanced/patcher/patch/options/PatchOptionException$ValueRequiredException : app/revanced/patcher/patch/options/PatchOptionException {
public fun <init> (Lapp/revanced/patcher/patch/options/PatchOption;)V
}
public final class app/revanced/patcher/patch/options/PatchOptionException$ValueValidationException : app/revanced/patcher/patch/options/PatchOptionException {
public fun <init> (Ljava/lang/Object;Lapp/revanced/patcher/patch/options/PatchOption;)V
}
public final class app/revanced/patcher/patch/options/PatchOptions : java/util/Map, kotlin/jvm/internal/markers/KMutableMap {
public fun <init> ()V
public fun clear ()V
public final fun containsKey (Ljava/lang/Object;)Z
public fun containsKey (Ljava/lang/String;)Z
public fun containsValue (Lapp/revanced/patcher/patch/options/PatchOption;)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/options/PatchOption;
public final synthetic fun get (Ljava/lang/Object;)Ljava/lang/Object;
public fun get (Ljava/lang/String;)Lapp/revanced/patcher/patch/options/PatchOption;
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;Lapp/revanced/patcher/patch/options/PatchOption;)Lapp/revanced/patcher/patch/options/PatchOption;
public fun putAll (Ljava/util/Map;)V
public final fun register (Lapp/revanced/patcher/patch/options/PatchOption;)V
public final fun remove (Ljava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
public final synthetic fun remove (Ljava/lang/Object;)Ljava/lang/Object;
public fun remove (Ljava/lang/String;)Lapp/revanced/patcher/patch/options/PatchOption;
public final fun set (Ljava/lang/String;Ljava/lang/Object;)V
public final fun size ()I
public final fun values ()Ljava/util/Collection;
}
public final class app/revanced/patcher/util/DomFileEditor : java/io/Closeable {
public fun <init> (Ljava/io/File;)V
public fun close ()V
public final fun getFile ()Lorg/w3c/dom/Document;
}
public final class app/revanced/patcher/util/ProxyClassList : java/util/Set, kotlin/jvm/internal/markers/KMutableSet {
public final fun add (Lapp/revanced/patcher/util/proxy/ClassProxy;)Z
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 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 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/util/method/MethodWalker {
public final fun getMethod ()Lcom/android/tools/smali/dexlib2/iface/Method;
public final fun nextMethod (IZ)Lapp/revanced/patcher/util/method/MethodWalker;
public static synthetic fun nextMethod$default (Lapp/revanced/patcher/util/method/MethodWalker;IZILjava/lang/Object;)Lapp/revanced/patcher/util/method/MethodWalker;
}
public final class app/revanced/patcher/util/proxy/ClassProxy {
public final fun getImmutableClass ()Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun getMutableClass ()Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableAnnotation : com/android/tools/smali/dexlib2/base/BaseAnnotation {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableAnnotation$Companion;
public fun <init> (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/util/proxy/mutableTypes/MutableAnnotation$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Annotation;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableAnnotation;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableAnnotationElement : com/android/tools/smali/dexlib2/base/BaseAnnotationElement {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableAnnotationElement$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableEncodedValue;)V
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableAnnotationElement$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/AnnotationElement;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableAnnotationElement;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableClass : com/android/tools/smali/dexlib2/base/reference/BaseTypeReference, com/android/tools/smali/dexlib2/iface/ClassDef {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass$Companion;
public fun <init> (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/util/proxy/mutableTypes/MutableClass$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableField : com/android/tools/smali/dexlib2/base/reference/BaseFieldReference, com/android/tools/smali/dexlib2/iface/Field {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableField$Companion;
public fun <init> (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/util/proxy/mutableTypes/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/util/proxy/mutableTypes/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/util/proxy/mutableTypes/MutableField$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Field;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableField;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableMethod : com/android/tools/smali/dexlib2/base/reference/BaseMethodReference, com/android/tools/smali/dexlib2/iface/Method {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod$Companion;
public fun <init> (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/util/proxy/mutableTypes/MutableMethod$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableMethodParameter : com/android/tools/smali/dexlib2/base/BaseMethodParameter, com/android/tools/smali/dexlib2/iface/MethodParameter {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethodParameter$Companion;
public fun <init> (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/util/proxy/mutableTypes/MutableMethodParameter$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/MethodParameter;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethodParameter;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableAnnotationEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseAnnotationEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableAnnotationEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableAnnotationEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/AnnotationEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableAnnotationEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableArrayEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseArrayEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableArrayEncodedValue$Companion;
public fun <init> (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)V
public fun getValue ()Ljava/util/List;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableArrayEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableArrayEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableBooleanEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseBooleanEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableBooleanEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableBooleanEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/BooleanEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableBooleanEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseByteEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableCharEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseCharEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableCharEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableCharEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/CharEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableCharEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableDoubleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseDoubleEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableDoubleEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableDoubleEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/DoubleEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableDoubleEncodedValue;
}
public abstract interface class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue : com/android/tools/smali/dexlib2/iface/value/EncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue$Companion;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEnumEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseEnumEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEnumEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableEnumEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EnumEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEnumEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFieldEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFieldEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFieldEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableFieldEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FieldEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFieldEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFloatEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFloatEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFloatEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableFloatEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FloatEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFloatEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableIntEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseIntEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableIntEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableIntEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/IntEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableIntEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableLongEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseLongEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableLongEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableLongEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/LongEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableLongEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableMethodEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodHandleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodHandleEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodHandleEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableMethodHandleEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodHandleEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodHandleEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodTypeEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodTypeEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableMethodTypeEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodTypeEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodTypeEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableNullEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseNullEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableNullEncodedValue$Companion;
public fun <init> ()V
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableNullEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableShortEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseShortEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableShortEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableShortEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ShortEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableShortEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableStringEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseStringEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableStringEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableStringEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseTypeEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableTypeEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableTypeEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/TypeEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableTypeEncodedValue;
}
public final class app/revanced/patcher/util/smali/ExternalLabel {
public fun <init> (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/util/smali/ExternalLabel;
public static synthetic fun copy$default (Lapp/revanced/patcher/util/smali/ExternalLabel;Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;ILjava/lang/Object;)Lapp/revanced/patcher/util/smali/ExternalLabel;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/util/smali/InlineSmaliCompiler {
public static final field Companion Lapp/revanced/patcher/util/smali/InlineSmaliCompiler$Companion;
public fun <init> ()V
}
public final class app/revanced/patcher/util/smali/InlineSmaliCompiler$Companion {
public final fun compile (Ljava/lang/String;Ljava/lang/String;IZ)Ljava/util/List;
}
public final class app/revanced/patcher/util/smali/InlineSmaliCompilerKt {
public static final fun toInstruction (Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;
public static synthetic fun toInstruction$default (Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;
public static final fun toInstructions (Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;)Ljava/util/List;
public static synthetic fun toInstructions$default (Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/Object;)Ljava/util/List;
}

View file

@ -1,46 +1,86 @@
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
plugins {
kotlin("jvm") version "1.9.0"
kotlin("jvm") version "1.9.10"
alias(libs.plugins.binary.compatibility.validator)
`maven-publish`
signing
java
}
val publicationVersion = project.version.toString()
group = "app.revanced"
subprojects {
apply(plugin = "maven-publish")
apply(plugin = "signing")
apply(plugin = "java")
apply(plugin ="kotlin")
group = "app.revanced"
version = publicationVersion
repositories {
mavenCentral()
mavenLocal()
maven { url = uri("https://jitpack.io") }
google()
tasks {
processResources {
expand("projectVersion" to project.version)
}
java {
withJavadocJar()
withSourcesJar()
}
configure<KotlinJvmProjectExtension> {
kotlin { jvmToolchain(11) }
}
tasks {
test {
useJUnitPlatform()
testLogging {
events("PASSED", "SKIPPED", "FAILED")
}
test {
useJUnitPlatform()
testLogging {
events("PASSED", "SKIPPED", "FAILED")
}
}
}
repositories {
mavenCentral()
mavenLocal()
maven { url = uri("https://jitpack.io") }
google()
}
dependencies {
implementation(libs.kotlinx.coroutines.core)
implementation(libs.xpp3)
implementation(libs.smali)
implementation(libs.multidexlib2)
implementation(libs.apktool.lib)
implementation(libs.kotlin.reflect)
compileOnly(libs.android)
testImplementation(libs.kotlin.test)
}
java {
withJavadocJar()
withSourcesJar()
}
kotlin {
jvmToolchain(11)
}
publishing {
publications {
create<MavenPublication>("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"
}
}
}
}
}

View file

@ -1,4 +1,4 @@
org.gradle.parallel = true
org.gradle.caching = true
kotlin.code.style = official
version = 17.0.0
version = 18.0.0-dev.6

View file

@ -6,12 +6,8 @@ kotlin-test = "1.8.20-RC"
kotlinx-coroutines-core = "1.7.3"
multidexlib2 = "3.0.3.r3"
smali = "3.0.3"
symbol-processing-api = "1.9.10-1.0.13"
xpp3 = "1.1.4c"
binary-compatibility-validator = "0.13.2"
kotlin-compile-testing-ksp = "1.5.0"
kotlinpoet-ksp = "1.14.2"
ksp = "1.9.0-1.0.11"
[libraries]
android = { module = "com.google.android:android", version.ref = "android" }
@ -21,11 +17,7 @@ kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotl
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines-core" }
multidexlib2 = { module = "app.revanced:multidexlib2", version.ref = "multidexlib2" }
smali = { module = "com.android.tools.smali:smali", version.ref = "smali" }
symbol-processing-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "symbol-processing-api" }
xpp3 = { module = "xpp3:xpp3", version.ref = "xpp3" }
kotlin-compile-testing = { module = "com.github.tschuchortdev:kotlin-compile-testing-ksp", version.ref = "kotlin-compile-testing-ksp" }
kotlinpoet-ksp = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlinpoet-ksp" }
[plugins]
binary-compatibility-validator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version.ref = "binary-compatibility-validator" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }

View file

@ -1,24 +0,0 @@
public abstract interface annotation class app/revanced/patcher/patch/annotation/CompatiblePackage : java/lang/annotation/Annotation {
public abstract fun name ()Ljava/lang/String;
public abstract fun versions ()[Ljava/lang/String;
}
public abstract interface annotation class app/revanced/patcher/patch/annotation/Patch : java/lang/annotation/Annotation {
public abstract fun compatiblePackages ()[Lapp/revanced/patcher/patch/annotation/CompatiblePackage;
public abstract fun dependencies ()[Ljava/lang/Class;
public abstract fun description ()Ljava/lang/String;
public abstract fun name ()Ljava/lang/String;
public abstract fun requiresIntegrations ()Z
public abstract fun use ()Z
}
public final class app/revanced/patcher/patch/annotation/processor/PatchProcessor : com/google/devtools/ksp/processing/SymbolProcessor {
public fun process (Lcom/google/devtools/ksp/processing/Resolver;)Ljava/util/List;
}
public final class app/revanced/patcher/patch/annotation/processor/PatchProcessorProvider : com/google/devtools/ksp/processing/SymbolProcessorProvider {
public fun <init> ()V
public fun create (Lcom/google/devtools/ksp/processing/SymbolProcessorEnvironment;)Lapp/revanced/patcher/patch/annotation/processor/PatchProcessor;
public synthetic fun create (Lcom/google/devtools/ksp/processing/SymbolProcessorEnvironment;)Lcom/google/devtools/ksp/processing/SymbolProcessor;
}

View file

@ -1,45 +0,0 @@
plugins {
alias(libs.plugins.ksp)
}
dependencies {
implementation(libs.symbol.processing.api)
implementation(libs.kotlinpoet.ksp)
implementation(project(":revanced-patcher"))
testImplementation(libs.kotlin.test)
testImplementation(libs.kotlin.compile.testing)
}
publishing {
publications {
create<MavenPublication>("revanced-patch-annotation-processor-publication") {
from(components["java"])
pom {
name = "ReVanced patch annotation processor"
description = "Annotation processor for patches."
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"
}
}
}
}
}

View file

@ -1,2 +0,0 @@
rootProject.name = "revanced-patch-annotation-processor"

View file

@ -1,207 +0,0 @@
package app.revanced.patcher.patch.annotation.processor
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import com.google.devtools.ksp.processing.CodeGenerator
import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSAnnotation
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.validate
import com.squareup.kotlinpoet.*
import com.squareup.kotlinpoet.ksp.toClassName
import com.squareup.kotlinpoet.ksp.writeTo
import kotlin.reflect.KClass
class PatchProcessor internal constructor(
private val codeGenerator: CodeGenerator,
) : SymbolProcessor {
private fun KSAnnotated.isSubclassOf(cls: KClass<*>): Boolean {
if (this !is KSClassDeclaration) return false
if (qualifiedName?.asString() == cls.qualifiedName) return true
return superTypes.any { it.resolve().declaration.isSubclassOf(cls) }
}
@Suppress("UNCHECKED_CAST")
override fun process(resolver: Resolver): List<KSAnnotated> {
val patches = buildMap {
resolver.getSymbolsWithAnnotation(Patch::class.qualifiedName!!).filter {
// Do not check here if Patch is super of the class, because it is expensive.
// Check it later when processing.
it.validate() && it.isSubclassOf(app.revanced.patcher.patch.Patch::class)
}.map {
it as KSClassDeclaration
}.forEach { patchDeclaration ->
patchDeclaration.annotations.find {
it.annotationType.resolve().declaration.qualifiedName!!.asString() == Patch::class.qualifiedName!!
}?.let { annotation ->
fun KSAnnotation.property(name: String) =
arguments.find { it.name!!.asString() == name }?.value!!
val name =
annotation.property("name").toString().ifEmpty { null }
val description =
annotation.property("description").toString().ifEmpty { null }
val dependencies =
(annotation.property("dependencies") as List<KSType>).ifEmpty { null }
val compatiblePackages =
(annotation.property("compatiblePackages") as List<KSAnnotation>).ifEmpty { null }
val use =
annotation.property("use") as Boolean
val requiresIntegrations =
annotation.property("requiresIntegrations") as Boolean
// Data class for KotlinPoet
data class PatchData(
val name: String?,
val description: String?,
val dependencies: List<ClassName>?,
val compatiblePackages: List<CodeBlock>?,
val use: Boolean,
val requiresIntegrations: Boolean
)
this[patchDeclaration] = PatchData(
name,
description,
dependencies?.map { dependency -> dependency.toClassName() },
compatiblePackages?.map {
val packageName = it.property("name")
val packageVersions = (it.property("versions") as List<String>).ifEmpty { null }
?.joinToString(", ") { version -> "\"$version\"" }
CodeBlock.of(
"%T(%S, %L)",
app.revanced.patcher.patch.Patch.CompatiblePackage::class,
packageName,
packageVersions?.let { "setOf($packageVersions)" },
)
},
use,
requiresIntegrations
)
}
}
}
// If a patch depends on another, that is annotated, the dependency should be replaced with the generated patch,
// because the generated patch has all the necessary properties to invoke the super constructor with,
// unlike the annotated patch.
val dependencyResolutionMap = buildMap {
patches.values.filter { it.dependencies != null }.flatMap {
it.dependencies!!
}.distinct().forEach { dependency ->
patches.keys.find { it.qualifiedName?.asString() == dependency.toString() }
?.let { patch ->
this[dependency] = ClassName(
patch.packageName.asString(),
patch.simpleName.asString() + "Generated"
)
}
}
}
patches.forEach { (patchDeclaration, patchAnnotation) ->
val isBytecodePatch = patchDeclaration.isSubclassOf(BytecodePatch::class)
val superClass = if (isBytecodePatch) {
BytecodePatch::class
} else {
ResourcePatch::class
}
val contextClass = if (isBytecodePatch) {
BytecodeContext::class
} else {
ResourceContext::class
}
val generatedPatchClassName = ClassName(
patchDeclaration.packageName.asString(),
patchDeclaration.simpleName.asString() + "Generated"
)
FileSpec.builder(generatedPatchClassName)
.addType(
TypeSpec.objectBuilder(generatedPatchClassName)
.superclass(superClass).apply {
patchAnnotation.name?.let { name ->
addSuperclassConstructorParameter("name = %S", name)
}
patchAnnotation.description?.let { description ->
addSuperclassConstructorParameter("description = %S", description)
}
patchAnnotation.compatiblePackages?.let { compatiblePackages ->
addSuperclassConstructorParameter(
"compatiblePackages = setOf(%L)",
compatiblePackages.joinToString(", ")
)
}
// The generated patch always depends on the source patch.
addSuperclassConstructorParameter(
"dependencies = setOf(%L)",
buildList {
patchAnnotation.dependencies?.forEach { dependency ->
add("${(dependencyResolutionMap[dependency] ?: dependency)}::class")
}
add("${patchDeclaration.toClassName()}::class")
}.joinToString(", "),
)
addSuperclassConstructorParameter(
"use = %L", patchAnnotation.use
)
addSuperclassConstructorParameter(
"requiresIntegrations = %L",
patchAnnotation.requiresIntegrations
)
}
.addFunction(
FunSpec.builder("execute")
.addModifiers(KModifier.OVERRIDE)
.addParameter("context", contextClass)
.build()
)
.addInitializerBlock(
CodeBlock.builder()
.add(
"%T.options.forEach { (_, option) ->",
patchDeclaration.toClassName()
)
.addStatement(
"options.register(option)"
)
.add(
"}"
)
.build()
)
.build()
).build().writeTo(
codeGenerator,
Dependencies(false, patchDeclaration.containingFile!!)
)
}
return emptyList()
}
}

View file

@ -1,9 +0,0 @@
package app.revanced.patcher.patch.annotation.processor
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider
class PatchProcessorProvider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment) =
PatchProcessor(environment.codeGenerator)
}

View file

@ -1 +0,0 @@
app.revanced.patcher.patch.annotation.processor.PatchProcessorProvider

View file

@ -1,147 +0,0 @@
package app.revanced.patcher.patch.annotation.processor
import app.revanced.patcher.patch.Patch
import com.tschuchort.compiletesting.KotlinCompilation
import com.tschuchort.compiletesting.SourceFile
import com.tschuchort.compiletesting.kspWithCompilation
import com.tschuchort.compiletesting.symbolProcessorProviders
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
class TestPatchAnnotationProcessor {
// region Processing
@Test
fun testProcessing() = assertEquals(
"Processable patch", compile(
getSourceFile(
"processing", "ProcessablePatch"
)
).loadPatch("$SAMPLE_PACKAGE.processing.ProcessablePatchGenerated").name
)
@Test
fun generateNullProperties() = compile(
getSourceFile(
"null", "NullPropertiesPatch"
)
).loadPatch("$SAMPLE_PACKAGE.null.NullPropertiesPatchGenerated").let {
assertNull(it.description) // Because no description was provided.
assertNull(it.compatiblePackages!!.first().versions) // Because no versions were provided.
}
// endregion
// region Dependencies
@Test
fun testDependencies() {
compile(
getSourceFile(
"dependencies", "DependentPatch"
), getSourceFile(
"dependencies", "DependencyPatch"
)
).let { result ->
result.loadPatch("$SAMPLE_PACKAGE.dependencies.DependentPatchGenerated").let {
// Dependency as well as the source class of the generated class.
assertEquals(
2,
it.dependencies!!.size
)
// The last dependency is always the source class of the generated class to respect
// order of dependencies.
assertEquals(
result.loadPatch("$SAMPLE_PACKAGE.dependencies.DependentPatch")::class,
it.dependencies!!.last()
)
}
}
}
// endregion
// region Options
@Test
fun testOptions() {
val patch = compile(
getSourceFile(
"options", "OptionsPatch"
)
).loadPatch("$SAMPLE_PACKAGE.options.OptionsPatchGenerated")
assert(patch.options.isNotEmpty())
assertEquals(patch.options["print"].title, "Print message")
}
// endregion
// region Limitations
@Test
fun failingManualDependency() = assertEquals(
1, // Generated patch is always dependent on source class.
compile(
getSourceFile(
"limitations/manualdependency", "DependentPatch"
), getSourceFile(
"limitations/manualdependency", "DependencyPatch"
)
).loadPatch("$SAMPLE_PACKAGE.limitations.manualdependency.DependentPatchGenerated").dependencies!!.size
)
// endregion
private companion object Utils {
const val SAMPLE_PACKAGE = "app.revanced.patcher.patch.annotation.processor.samples"
/**
* Get a source file from the given sample and class name.
*
* @param sample The sample to get the source file from.
* @param className The name of the class to get the source file from.
* @return The source file.
*/
fun getSourceFile(sample: String, className: String): SourceFile {
val resourceName = "app/revanced/patcher/patch/annotation/processor/samples/$sample/$className.kt"
return SourceFile.kotlin(
"$className.kt",
TestPatchAnnotationProcessor::class.java.classLoader.getResourceAsStream(resourceName)
?.readAllBytes()
?.toString(Charsets.UTF_8)
?: error("Could not find resource $resourceName")
)
}
/**
* Compile the given source files and return the result.
*
* @param sourceFiles The source files to compile.
* @return The result of the compilation.
*/
fun compile(vararg sourceFiles: SourceFile) = KotlinCompilation().apply {
sources = sourceFiles.asList()
symbolProcessorProviders = listOf(PatchProcessorProvider())
// Required until https://github.com/tschuchortdev/kotlin-compile-testing/issues/312 closed.
kspWithCompilation = true
inheritClassPath = true
messageOutputStream = System.out
}.compile().also { result ->
assertEquals(KotlinCompilation.ExitCode.OK, result.exitCode)
}
// region Class loading
fun KotlinCompilation.Result.loadPatch(name: String) = classLoader.loadClass(name).loadPatch()
fun Class<*>.loadPatch() = this.getField("INSTANCE").get(null) as Patch<*>
// endregion
}
}

View file

@ -1,10 +0,0 @@
package app.revanced.patcher.patch.annotation.processor.samples.dependencies
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
@Patch(name = "Dependency patch")
object DependencyPatch : ResourcePatch() {
override fun execute(context: ResourceContext) {}
}

View file

@ -1,12 +0,0 @@
package app.revanced.patcher.patch.annotation.processor.samples.dependencies
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
@Patch(
name = "Dependent patch",
dependencies = [DependencyPatch::class],
)
object DependentPatch : BytecodePatch() {
override fun execute(context: BytecodeContext) {}
}

View file

@ -1,10 +0,0 @@
package app.revanced.patcher.patch.annotation.processor.samples.limitations.manualdependency
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
@Patch(name = "Dependency patch")
object DependencyPatch : ResourcePatch() {
override fun execute(context: ResourceContext) { }
}

View file

@ -1,17 +0,0 @@
package app.revanced.patcher.patch.annotation.processor.samples.limitations.manualdependency
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
@Patch(name = "Dependent patch")
object DependentPatch : BytecodePatch(
// Dependency will not be executed correctly if it is manually specified.
// The reason for this is that the dependency patch is annotated too,
// so the processor will generate a new patch class for it embedding the annotated information.
// Because the dependency is manually specified,
// the processor will not be able to change this dependency to the generated class,
// which means that the dependency will lose the annotated information.
dependencies = setOf(DependencyPatch::class)
) {
override fun execute(context: BytecodeContext) {}
}

View file

@ -1,14 +0,0 @@
package app.revanced.patcher.patch.annotation.processor.samples.`null`
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
@Patch(
"Patch with null properties",
compatiblePackages = [CompatiblePackage("com.google.android.youtube")],
)
object NullPropertiesPatch : BytecodePatch() {
override fun execute(context: BytecodeContext) {}
}

View file

@ -1,19 +0,0 @@
package app.revanced.patcher.patch.annotation.processor.samples.options
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patcher.patch.options.types.StringPatchOption.Companion.stringPatchOption
@Patch(name = "Options patch")
object OptionsPatch : ResourcePatch() {
override fun execute(context: ResourceContext) {}
@Suppress("unused")
private val printOption by stringPatchOption(
"print",
null,
"Print message",
"The message to print."
)
}

View file

@ -1,10 +0,0 @@
package app.revanced.patcher.patch.annotation.processor.samples.processing
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.annotation.Patch
@Patch("Processable patch")
object ProcessablePatch : BytecodePatch() {
override fun execute(context: BytecodeContext) {}
}

View file

@ -1,904 +0,0 @@
public abstract interface class app/revanced/patcher/IntegrationsConsumer {
public abstract fun acceptIntegrations (Ljava/util/List;)V
}
public final class app/revanced/patcher/PackageMetadata {
public final fun getPackageName ()Ljava/lang/String;
public final fun getPackageVersion ()Ljava/lang/String;
}
public abstract class app/revanced/patcher/PatchBundleLoader : java/util/Set, kotlin/jvm/internal/markers/KMappedMarker {
public synthetic fun <init> (Ljava/lang/ClassLoader;[Ljava/io/File;Lkotlin/jvm/functions/Function1;Ljava/util/Set;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
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 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/PatchBundleLoader$Dex : app/revanced/patcher/PatchBundleLoader {
public fun <init> ([Ljava/io/File;)V
public fun <init> ([Ljava/io/File;Ljava/io/File;)V
public synthetic fun <init> ([Ljava/io/File;Ljava/io/File;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/PatchBundleLoader$Jar : app/revanced/patcher/PatchBundleLoader {
public fun <init> ([Ljava/io/File;)V
}
public abstract interface class app/revanced/patcher/PatchExecutorFunction : java/util/function/Function {
}
public final class app/revanced/patcher/Patcher : app/revanced/patcher/IntegrationsConsumer, app/revanced/patcher/PatchExecutorFunction, app/revanced/patcher/PatchesConsumer, java/io/Closeable, java/util/function/Supplier {
public fun <init> (Lapp/revanced/patcher/PatcherOptions;)V
public fun acceptIntegrations (Ljava/util/List;)V
public fun acceptPatches (Ljava/util/List;)V
public synthetic fun apply (Ljava/lang/Object;)Ljava/lang/Object;
public fun apply (Z)Lkotlinx/coroutines/flow/Flow;
public fun close ()V
public fun get ()Lapp/revanced/patcher/PatcherResult;
public synthetic fun get ()Ljava/lang/Object;
public final fun getContext ()Lapp/revanced/patcher/PatcherContext;
}
public final class app/revanced/patcher/PatcherContext {
public final fun getPackageMetadata ()Lapp/revanced/patcher/PackageMetadata;
}
public abstract class app/revanced/patcher/PatcherException : java/lang/Exception {
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Throwable;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/PatcherException$CircularDependencyException : app/revanced/patcher/PatcherException {
}
public final class app/revanced/patcher/PatcherOptions {
public fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Z)V
public synthetic fun <init> (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun copy (Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;Z)Lapp/revanced/patcher/PatcherOptions;
public static synthetic fun copy$default (Lapp/revanced/patcher/PatcherOptions;Ljava/io/File;Ljava/io/File;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Lapp/revanced/patcher/PatcherOptions;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public final fun recreateResourceCacheDirectory ()Ljava/io/File;
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/PatcherResult {
public fun <init> (Ljava/util/List;Ljava/io/File;Ljava/util/List;)V
public synthetic fun <init> (Ljava/util/List;Ljava/io/File;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/util/List;
public final fun component2 ()Ljava/io/File;
public final fun component3 ()Ljava/util/List;
public final fun copy (Ljava/util/List;Ljava/io/File;Ljava/util/List;)Lapp/revanced/patcher/PatcherResult;
public static synthetic fun copy$default (Lapp/revanced/patcher/PatcherResult;Ljava/util/List;Ljava/io/File;Ljava/util/List;ILjava/lang/Object;)Lapp/revanced/patcher/PatcherResult;
public fun equals (Ljava/lang/Object;)Z
public final fun getDexFiles ()Ljava/util/List;
public final fun getDoNotCompress ()Ljava/util/List;
public final fun getResourceFile ()Ljava/io/File;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/PatcherResult$PatchedDexFile {
public fun <init> (Ljava/lang/String;Ljava/io/InputStream;)V
public final fun getName ()Ljava/lang/String;
public final fun getStream ()Ljava/io/InputStream;
}
public abstract interface class app/revanced/patcher/PatchesConsumer {
public abstract fun acceptPatches (Ljava/util/List;)V
}
public final class app/revanced/patcher/data/BytecodeContext : app/revanced/patcher/data/Context {
public final fun findClass (Ljava/lang/String;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun findClass (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public synthetic fun get ()Ljava/lang/Object;
public fun get ()Ljava/util/List;
public final fun getClasses ()Lapp/revanced/patcher/util/ProxyClassList;
public final fun proxy (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/util/proxy/ClassProxy;
public final fun toMethodWalker (Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/method/MethodWalker;
}
public abstract interface class app/revanced/patcher/data/Context : java/util/function/Supplier {
}
public final class app/revanced/patcher/data/ResourceContext : app/revanced/patcher/data/Context, java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker {
public fun get ()Ljava/io/File;
public synthetic fun get ()Ljava/lang/Object;
public final fun get (Ljava/lang/String;)Ljava/io/File;
public final fun getXmlEditor ()Lapp/revanced/patcher/data/ResourceContext$XmlFileHolder;
public fun iterator ()Ljava/util/Iterator;
}
public final class app/revanced/patcher/data/ResourceContext$XmlFileHolder {
public fun <init> (Lapp/revanced/patcher/data/ResourceContext;)V
public final fun get (Ljava/io/InputStream;)Lapp/revanced/patcher/util/DomFileEditor;
public final fun get (Ljava/lang/String;)Lapp/revanced/patcher/util/DomFileEditor;
}
public final class app/revanced/patcher/extensions/ExtensionsKt {
public static final fun newLabel (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/Label;
public static final fun or (ILcom/android/tools/smali/dexlib2/AccessFlags;)I
public static final fun or (Lcom/android/tools/smali/dexlib2/AccessFlags;I)I
public static final fun or (Lcom/android/tools/smali/dexlib2/AccessFlags;Lcom/android/tools/smali/dexlib2/AccessFlags;)I
}
public final class app/revanced/patcher/extensions/InstructionExtensions {
public static final field INSTANCE Lapp/revanced/patcher/extensions/InstructionExtensions;
public final fun addInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V
public final fun addInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
public final fun addInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V
public final fun addInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/String;)V
public final fun addInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
public final fun addInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/util/List;)V
public final fun addInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/String;)V
public final fun addInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/util/List;)V
public final fun addInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V
public final fun addInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;Ljava/util/List;)V
public final fun addInstructionsWithLabels (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;[Lapp/revanced/patcher/util/smali/ExternalLabel;)V
public final fun getInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;
public final fun getInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)Ljava/lang/Object;
public final fun getInstruction (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;
public final fun getInstruction (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)Ljava/lang/Object;
public final fun getInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;)Ljava/util/List;
public final fun removeInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)V
public final fun removeInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;I)V
public final fun removeInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;II)V
public final fun removeInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;I)V
public final fun removeInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;II)V
public final fun replaceInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILcom/android/tools/smali/dexlib2/builder/BuilderInstruction;)V
public final fun replaceInstruction (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
public final fun replaceInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/String;)V
public final fun replaceInstructions (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/util/List;)V
public final fun replaceInstructions (Lcom/android/tools/smali/dexlib2/builder/MutableMethodImplementation;ILjava/util/List;)V
}
public final class app/revanced/patcher/extensions/MethodFingerprintExtensions {
public static final field INSTANCE Lapp/revanced/patcher/extensions/MethodFingerprintExtensions;
public final fun getFuzzyPatternScanMethod (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/method/annotation/FuzzyPatternScanMethod;
}
public abstract interface class app/revanced/patcher/fingerprint/Fingerprint {
}
public abstract interface annotation class app/revanced/patcher/fingerprint/method/annotation/FuzzyPatternScanMethod : java/lang/annotation/Annotation {
public abstract fun threshold ()I
}
public abstract class app/revanced/patcher/fingerprint/method/impl/MethodFingerprint : app/revanced/patcher/fingerprint/Fingerprint {
public static final field Companion Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprint$Companion;
public fun <init> ()V
public fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getResult ()Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult;
public final fun setResult (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult;)V
}
public final class app/revanced/patcher/fingerprint/method/impl/MethodFingerprint$Companion {
public final fun resolve (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprint;Lapp/revanced/patcher/data/BytecodeContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
public final fun resolve (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprint;Lapp/revanced/patcher/data/BytecodeContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Z
public final fun resolve (Ljava/lang/Iterable;Lapp/revanced/patcher/data/BytecodeContext;Ljava/lang/Iterable;)V
}
public final class app/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult {
public fun <init> (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult;Lapp/revanced/patcher/data/BytecodeContext;)V
public final fun component1 ()Lcom/android/tools/smali/dexlib2/iface/Method;
public final fun component2 ()Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun component3 ()Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult;
public final fun copy (Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult;Lapp/revanced/patcher/data/BytecodeContext;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult;
public static synthetic fun copy$default (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult;Lapp/revanced/patcher/data/BytecodeContext;ILjava/lang/Object;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult;
public fun equals (Ljava/lang/Object;)Z
public final fun getClassDef ()Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun getMethod ()Lcom/android/tools/smali/dexlib2/iface/Method;
public final fun getMutableClass ()Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
public final fun getMutableMethod ()Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
public final fun getScanResult ()Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult {
public fun <init> (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;)V
public final fun component1 ()Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;
public final fun component2 ()Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;
public final fun copy (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult;
public static synthetic fun copy$default (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult;Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;ILjava/lang/Object;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult;
public fun equals (Ljava/lang/Object;)Z
public final fun getPatternScanResult ()Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;
public final fun getStringsScanResult ()Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult {
public fun <init> (IILjava/util/List;)V
public synthetic fun <init> (IILjava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()I
public final fun component2 ()I
public final fun component3 ()Ljava/util/List;
public final fun copy (IILjava/util/List;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;
public static synthetic fun copy$default (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;IILjava/util/List;ILjava/lang/Object;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult;
public fun equals (Ljava/lang/Object;)Z
public final fun getEndIndex ()I
public final fun getStartIndex ()I
public final fun getWarnings ()Ljava/util/List;
public fun hashCode ()I
public final fun setWarnings (Ljava/util/List;)V
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult$Warning {
public fun <init> (Lcom/android/tools/smali/dexlib2/Opcode;Lcom/android/tools/smali/dexlib2/Opcode;II)V
public final fun component1 ()Lcom/android/tools/smali/dexlib2/Opcode;
public final fun component2 ()Lcom/android/tools/smali/dexlib2/Opcode;
public final fun component3 ()I
public final fun component4 ()I
public final fun copy (Lcom/android/tools/smali/dexlib2/Opcode;Lcom/android/tools/smali/dexlib2/Opcode;II)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult$Warning;
public static synthetic fun copy$default (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult$Warning;Lcom/android/tools/smali/dexlib2/Opcode;Lcom/android/tools/smali/dexlib2/Opcode;IIILjava/lang/Object;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$PatternScanResult$Warning;
public fun equals (Ljava/lang/Object;)Z
public final fun getCorrectOpcode ()Lcom/android/tools/smali/dexlib2/Opcode;
public final fun getInstructionIndex ()I
public final fun getPatternIndex ()I
public final fun getWrongOpcode ()Lcom/android/tools/smali/dexlib2/Opcode;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult {
public fun <init> (Ljava/util/List;)V
public final fun component1 ()Ljava/util/List;
public final fun copy (Ljava/util/List;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;
public static synthetic fun copy$default (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;Ljava/util/List;ILjava/lang/Object;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult;
public fun equals (Ljava/lang/Object;)Z
public final fun getMatches ()Ljava/util/List;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult$StringMatch {
public fun <init> (Ljava/lang/String;I)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()I
public final fun copy (Ljava/lang/String;I)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult$StringMatch;
public static synthetic fun copy$default (Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult$StringMatch;Ljava/lang/String;IILjava/lang/Object;)Lapp/revanced/patcher/fingerprint/method/impl/MethodFingerprintResult$MethodFingerprintScanResult$StringsScanResult$StringMatch;
public fun equals (Ljava/lang/Object;)Z
public final fun getIndex ()I
public final fun getString ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public abstract interface class app/revanced/patcher/logging/Logger {
public abstract fun error (Ljava/lang/String;)V
public abstract fun info (Ljava/lang/String;)V
public abstract fun trace (Ljava/lang/String;)V
public abstract fun warn (Ljava/lang/String;)V
}
public final class app/revanced/patcher/logging/Logger$DefaultImpls {
public static fun error (Lapp/revanced/patcher/logging/Logger;Ljava/lang/String;)V
public static fun info (Lapp/revanced/patcher/logging/Logger;Ljava/lang/String;)V
public static fun trace (Lapp/revanced/patcher/logging/Logger;Ljava/lang/String;)V
public static fun warn (Lapp/revanced/patcher/logging/Logger;Ljava/lang/String;)V
}
public final class app/revanced/patcher/logging/impl/NopLogger : app/revanced/patcher/logging/Logger {
public static final field INSTANCE Lapp/revanced/patcher/logging/impl/NopLogger;
public fun error (Ljava/lang/String;)V
public fun info (Ljava/lang/String;)V
public fun trace (Ljava/lang/String;)V
public fun warn (Ljava/lang/String;)V
}
public abstract class app/revanced/patcher/patch/BytecodePatch : app/revanced/patcher/patch/Patch {
public fun <init> ()V
public fun <init> (Ljava/util/Set;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZ)V
public synthetic fun <init> (Ljava/util/Set;Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public abstract class app/revanced/patcher/patch/Patch {
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun equals (Ljava/lang/Object;)Z
public abstract fun execute (Lapp/revanced/patcher/data/Context;)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/PatchOptions;
public final fun getRequiresIntegrations ()Z
public final fun getUse ()Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/patch/Patch$CompatiblePackage {
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getName ()Ljava/lang/String;
public final fun getVersions ()Ljava/util/Set;
}
public final class app/revanced/patcher/patch/PatchException : java/lang/Exception {
public fun <init> (Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;Ljava/lang/Throwable;)V
public fun <init> (Ljava/lang/Throwable;)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 abstract class app/revanced/patcher/patch/ResourcePatch : app/revanced/patcher/patch/Patch {
public fun <init> ()V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZ)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZZILkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public abstract class app/revanced/patcher/patch/options/PatchOption {
public fun <init> (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)V
public final fun getDescription ()Ljava/lang/String;
public final fun getKey ()Ljava/lang/String;
public final fun getRequired ()Z
public final fun getTitle ()Ljava/lang/String;
public final fun getValidate ()Lkotlin/jvm/functions/Function1;
public final fun getValue ()Ljava/lang/Object;
public final fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object;
public final fun setValue (Ljava/lang/Object;)V
public final fun setValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;Ljava/lang/Object;)V
}
public abstract class app/revanced/patcher/patch/options/PatchOptionException : java/lang/Exception {
public synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/PatchOptionException$InvalidValueTypeException : app/revanced/patcher/patch/options/PatchOptionException {
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
}
public final class app/revanced/patcher/patch/options/PatchOptionException$PatchOptionNotFoundException : app/revanced/patcher/patch/options/PatchOptionException {
public fun <init> (Ljava/lang/String;)V
}
public final class app/revanced/patcher/patch/options/PatchOptionException$ValueRequiredException : app/revanced/patcher/patch/options/PatchOptionException {
public fun <init> (Lapp/revanced/patcher/patch/options/PatchOption;)V
}
public final class app/revanced/patcher/patch/options/PatchOptionException$ValueValidationException : app/revanced/patcher/patch/options/PatchOptionException {
public fun <init> (Ljava/lang/Object;Lapp/revanced/patcher/patch/options/PatchOption;)V
}
public final class app/revanced/patcher/patch/options/PatchOptions : java/util/Map, kotlin/jvm/internal/markers/KMutableMap {
public fun <init> ()V
public fun clear ()V
public final fun containsKey (Ljava/lang/Object;)Z
public fun containsKey (Ljava/lang/String;)Z
public fun containsValue (Lapp/revanced/patcher/patch/options/PatchOption;)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/options/PatchOption;
public final synthetic fun get (Ljava/lang/Object;)Ljava/lang/Object;
public fun get (Ljava/lang/String;)Lapp/revanced/patcher/patch/options/PatchOption;
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;Lapp/revanced/patcher/patch/options/PatchOption;)Lapp/revanced/patcher/patch/options/PatchOption;
public fun putAll (Ljava/util/Map;)V
public final fun register (Lapp/revanced/patcher/patch/options/PatchOption;)V
public final fun remove (Ljava/lang/Object;)Lapp/revanced/patcher/patch/options/PatchOption;
public final synthetic fun remove (Ljava/lang/Object;)Ljava/lang/Object;
public fun remove (Ljava/lang/String;)Lapp/revanced/patcher/patch/options/PatchOption;
public final fun set (Ljava/lang/String;Ljava/lang/Object;)V
public final fun size ()I
public final fun values ()Ljava/util/Collection;
}
public final class app/revanced/patcher/patch/options/types/BooleanPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/BooleanPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/BooleanPatchOption$Companion {
public final fun booleanPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/BooleanPatchOption;
public static synthetic fun booleanPatchOption$default (Lapp/revanced/patcher/patch/options/types/BooleanPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/BooleanPatchOption;
}
public final class app/revanced/patcher/patch/options/types/FloatPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/FloatPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/FloatPatchOption$Companion {
public final fun floatPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/FloatPatchOption;
public static synthetic fun floatPatchOption$default (Lapp/revanced/patcher/patch/options/types/FloatPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/FloatPatchOption;
}
public final class app/revanced/patcher/patch/options/types/IntPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/IntPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/IntPatchOption$Companion {
public final fun intPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/IntPatchOption;
public static synthetic fun intPatchOption$default (Lapp/revanced/patcher/patch/options/types/IntPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/IntPatchOption;
}
public final class app/revanced/patcher/patch/options/types/LongPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/LongPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/LongPatchOption$Companion {
public final fun longPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/LongPatchOption;
public static synthetic fun longPatchOption$default (Lapp/revanced/patcher/patch/options/types/LongPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/LongPatchOption;
}
public final class app/revanced/patcher/patch/options/types/StringPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/StringPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/StringPatchOption$Companion {
public final fun stringPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/StringPatchOption;
public static synthetic fun stringPatchOption$default (Lapp/revanced/patcher/patch/options/types/StringPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/StringPatchOption;
}
public final class app/revanced/patcher/patch/options/types/array/BooleanArrayPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/array/BooleanArrayPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;[Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/array/BooleanArrayPatchOption$Companion {
public final fun booleanArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/array/BooleanArrayPatchOption;
public static synthetic fun booleanArrayPatchOption$default (Lapp/revanced/patcher/patch/options/types/array/BooleanArrayPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/array/BooleanArrayPatchOption;
}
public final class app/revanced/patcher/patch/options/types/array/FloatArrayPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/array/FloatArrayPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;[Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/array/FloatArrayPatchOption$Companion {
public final fun floatArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/array/FloatArrayPatchOption;
public static synthetic fun floatArrayPatchOption$default (Lapp/revanced/patcher/patch/options/types/array/FloatArrayPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Float;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/array/FloatArrayPatchOption;
}
public final class app/revanced/patcher/patch/options/types/array/IntArrayPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/array/IntArrayPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;[Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/array/IntArrayPatchOption$Companion {
public final fun intArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/array/IntArrayPatchOption;
public static synthetic fun intArrayPatchOption$default (Lapp/revanced/patcher/patch/options/types/array/IntArrayPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/array/IntArrayPatchOption;
}
public final class app/revanced/patcher/patch/options/types/array/LongArrayPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/array/LongArrayPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;[Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/array/LongArrayPatchOption$Companion {
public final fun longArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/array/LongArrayPatchOption;
public static synthetic fun longArrayPatchOption$default (Lapp/revanced/patcher/patch/options/types/array/LongArrayPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/array/LongArrayPatchOption;
}
public final class app/revanced/patcher/patch/options/types/array/StringArrayPatchOption : app/revanced/patcher/patch/options/PatchOption {
public static final field Companion Lapp/revanced/patcher/patch/options/types/array/StringArrayPatchOption$Companion;
public synthetic fun <init> (Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}
public final class app/revanced/patcher/patch/options/types/array/StringArrayPatchOption$Companion {
public final fun stringArrayPatchOption (Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/options/types/array/StringArrayPatchOption;
public static synthetic fun stringArrayPatchOption$default (Lapp/revanced/patcher/patch/options/types/array/StringArrayPatchOption$Companion;Lapp/revanced/patcher/patch/Patch;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/options/types/array/StringArrayPatchOption;
}
public final class app/revanced/patcher/util/DomFileEditor : java/io/Closeable {
public fun <init> (Ljava/io/File;)V
public fun close ()V
public final fun getFile ()Lorg/w3c/dom/Document;
}
public final class app/revanced/patcher/util/ProxyClassList : java/util/Set, kotlin/jvm/internal/markers/KMutableSet {
public final fun add (Lapp/revanced/patcher/util/proxy/ClassProxy;)Z
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 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 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/util/method/MethodWalker {
public final fun getMethod ()Lcom/android/tools/smali/dexlib2/iface/Method;
public final fun nextMethod (IZ)Lapp/revanced/patcher/util/method/MethodWalker;
public static synthetic fun nextMethod$default (Lapp/revanced/patcher/util/method/MethodWalker;IZILjava/lang/Object;)Lapp/revanced/patcher/util/method/MethodWalker;
}
public final class app/revanced/patcher/util/proxy/ClassProxy {
public final fun getImmutableClass ()Lcom/android/tools/smali/dexlib2/iface/ClassDef;
public final fun getMutableClass ()Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableAnnotation : com/android/tools/smali/dexlib2/base/BaseAnnotation {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableAnnotation$Companion;
public fun <init> (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/util/proxy/mutableTypes/MutableAnnotation$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Annotation;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableAnnotation;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableAnnotationElement : com/android/tools/smali/dexlib2/base/BaseAnnotationElement {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableAnnotationElement$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableEncodedValue;)V
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableAnnotationElement$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/AnnotationElement;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableAnnotationElement;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableClass : com/android/tools/smali/dexlib2/base/reference/BaseTypeReference, com/android/tools/smali/dexlib2/iface/ClassDef {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass$Companion;
public fun <init> (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/util/proxy/mutableTypes/MutableClass$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableField : com/android/tools/smali/dexlib2/base/reference/BaseFieldReference, com/android/tools/smali/dexlib2/iface/Field {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableField$Companion;
public fun <init> (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/util/proxy/mutableTypes/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/util/proxy/mutableTypes/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/util/proxy/mutableTypes/MutableField$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Field;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableField;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableMethod : com/android/tools/smali/dexlib2/base/reference/BaseMethodReference, com/android/tools/smali/dexlib2/iface/Method {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod$Companion;
public fun <init> (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/util/proxy/mutableTypes/MutableMethod$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/MutableMethodParameter : com/android/tools/smali/dexlib2/base/BaseMethodParameter, com/android/tools/smali/dexlib2/iface/MethodParameter {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethodParameter$Companion;
public fun <init> (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/util/proxy/mutableTypes/MutableMethodParameter$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/MethodParameter;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethodParameter;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableAnnotationEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseAnnotationEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableAnnotationEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableAnnotationEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/AnnotationEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableAnnotationEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableArrayEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseArrayEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableArrayEncodedValue$Companion;
public fun <init> (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)V
public fun getValue ()Ljava/util/List;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableArrayEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ArrayEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableArrayEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableBooleanEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseBooleanEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableBooleanEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableBooleanEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/BooleanEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableBooleanEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseByteEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableCharEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseCharEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableCharEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableCharEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/CharEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableCharEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableDoubleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseDoubleEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableDoubleEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableDoubleEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/DoubleEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableDoubleEncodedValue;
}
public abstract interface class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue : com/android/tools/smali/dexlib2/iface/value/EncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue$Companion;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEnumEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseEnumEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEnumEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableEnumEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/EnumEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEnumEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFieldEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFieldEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFieldEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableFieldEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FieldEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFieldEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFloatEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseFloatEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFloatEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableFloatEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/FloatEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableFloatEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableIntEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseIntEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableIntEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableIntEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/IntEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableIntEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableLongEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseLongEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableLongEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableLongEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/LongEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableLongEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableMethodEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodHandleEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodHandleEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodHandleEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableMethodHandleEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodHandleEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodHandleEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseMethodTypeEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodTypeEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableMethodTypeEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/MethodTypeEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableMethodTypeEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableNullEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseNullEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableNullEncodedValue$Companion;
public fun <init> ()V
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableNullEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableShortEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseShortEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableShortEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableShortEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ShortEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableShortEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableStringEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseStringEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableStringEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableStringEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/ByteEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableByteEncodedValue;
}
public final class app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableTypeEncodedValue : com/android/tools/smali/dexlib2/base/value/BaseTypeEncodedValue, app/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableEncodedValue {
public static final field Companion Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableTypeEncodedValue$Companion;
public fun <init> (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/util/proxy/mutableTypes/encodedValue/MutableTypeEncodedValue$Companion {
public final fun toMutable (Lcom/android/tools/smali/dexlib2/iface/value/TypeEncodedValue;)Lapp/revanced/patcher/util/proxy/mutableTypes/encodedValue/MutableTypeEncodedValue;
}
public final class app/revanced/patcher/util/smali/ExternalLabel {
public fun <init> (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/util/smali/ExternalLabel;
public static synthetic fun copy$default (Lapp/revanced/patcher/util/smali/ExternalLabel;Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;ILjava/lang/Object;)Lapp/revanced/patcher/util/smali/ExternalLabel;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class app/revanced/patcher/util/smali/InlineSmaliCompiler {
public static final field Companion Lapp/revanced/patcher/util/smali/InlineSmaliCompiler$Companion;
public fun <init> ()V
}
public final class app/revanced/patcher/util/smali/InlineSmaliCompiler$Companion {
public final fun compile (Ljava/lang/String;Ljava/lang/String;IZ)Ljava/util/List;
}
public final class app/revanced/patcher/util/smali/InlineSmaliCompilerKt {
public static final fun toInstruction (Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;
public static synthetic fun toInstruction$default (Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/Object;)Lcom/android/tools/smali/dexlib2/builder/BuilderInstruction;
public static final fun toInstructions (Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;)Ljava/util/List;
public static synthetic fun toInstructions$default (Ljava/lang/String;Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;ILjava/lang/Object;)Ljava/util/List;
}

View file

@ -1,52 +0,0 @@
dependencies {
implementation(libs.kotlinx.coroutines.core)
implementation(libs.xpp3)
implementation(libs.smali)
implementation(libs.multidexlib2)
implementation(libs.apktool.lib)
implementation(libs.kotlin.reflect)
compileOnly(libs.android)
testImplementation(project(":revanced-patch-annotation-processor"))
testImplementation(libs.kotlin.test)
}
tasks {
processResources {
expand("projectVersion" to project.version)
}
}
publishing {
publications {
create<MavenPublication>("revanced-patcher-publication") {
from(components["java"])
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"
}
}
}
}
}

View file

@ -1 +0,0 @@
rootProject.name = "revanced-patcher"

View file

@ -1,9 +0,0 @@
package app.revanced.patcher.fingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
/**
* A ReVanced fingerprint.
* Can be a [MethodFingerprint].
*/
interface Fingerprint

View file

@ -1,513 +0,0 @@
package app.revanced.patcher.fingerprint.method.impl
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.MethodFingerprintExtensions.fuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.Fingerprint
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.util.proxy.ClassProxy
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.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.StringReference
import com.android.tools.smali.dexlib2.util.MethodUtil
import java.util.*
private typealias StringMatch = MethodFingerprintResult.MethodFingerprintScanResult.StringsScanResult.StringMatch
private typealias StringsScanResult = MethodFingerprintResult.MethodFingerprintScanResult.StringsScanResult
private typealias MethodClassPair = Pair<Method, ClassDef>
/**
* A fingerprint to resolve methods.
*
* @param returnType The method's return type compared using [String.startsWith].
* @param accessFlags The method's exact access flags using values of [AccessFlags].
* @param parameters The parameters of the method. Partial matches allowed and follow the same rules as [returnType].
* @param opcodes An opcode pattern of the method's instructions. Wildcard or unknown opcodes can be specified by `null`.
* @param strings A list of the method's strings compared each using [String.contains].
* @param customFingerprint A custom condition for this fingerprint.
*/
abstract class MethodFingerprint(
internal val returnType: String? = null,
internal val accessFlags: Int? = null,
internal val parameters: Iterable<String>? = null,
internal val opcodes: Iterable<Opcode?>? = null,
internal val strings: Iterable<String>? = null,
internal val customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null
) : Fingerprint {
/**
* The result of the [MethodFingerprint].
*/
var result: MethodFingerprintResult? = null
companion object {
/**
* A list of methods and the class they were found in.
*/
private val methods = mutableListOf<MethodClassPair>()
/**
* Lookup map for methods keyed to the methods access flags, return type and parameter.
*/
private val methodSignatureLookupMap = mutableMapOf<String, MutableList<MethodClassPair>>()
/**
* Lookup map for methods keyed to the strings contained in the method.
*/
private val methodStringsLookupMap = mutableMapOf<String, MutableList<MethodClassPair>>()
/**
* Appends a string based on the parameter reference types of this method.
*/
private fun StringBuilder.appendParameters(parameters: Iterable<CharSequence>) {
// Maximum parameters to use in the signature key.
// Some apps have methods with an incredible number of parameters (over 100 parameters have been seen).
// To keep the signature map from becoming needlessly bloated,
// group together in the same map entry all methods with the same access/return and 5 or more parameters.
// The value of 5 was chosen based on local performance testing and is not set in stone.
val maxSignatureParameters = 5
// Must append a unique value before the parameters to distinguish this key includes the parameters.
// If this is not appended, then methods with no parameters
// will collide with different keys that specify access/return but omit the parameters.
append("p:")
parameters.forEachIndexed { index, parameter ->
if (index >= maxSignatureParameters) return
append(parameter.first())
}
}
/**
* Initializes lookup maps for [MethodFingerprint] resolution
* using attributes of methods such as the method signature or strings.
*
* @param context The [BytecodeContext] containing the classes to initialize the lookup maps with.
*/
internal fun initializeFingerprintResolutionLookupMaps(context: BytecodeContext) {
fun MutableMap<String, MutableList<MethodClassPair>>.add(
key: String,
methodClassPair: MethodClassPair
) {
var methodClassPairs = this[key]
methodClassPairs ?: run {
methodClassPairs = LinkedList<MethodClassPair>().also { this[key] = it }
}
methodClassPairs!!.add(methodClassPair)
}
if (methods.isNotEmpty()) clearFingerprintResolutionLookupMaps()
context.classes.forEach { classDef ->
classDef.methods.forEach { method ->
val methodClassPair = method to classDef
// For fingerprints with no access or return type specified.
methods += methodClassPair
val accessFlagsReturnKey = method.accessFlags.toString() + method.returnType.first()
// Add <access><returnType> as the key.
methodSignatureLookupMap.add(accessFlagsReturnKey, methodClassPair)
// Add <access><returnType>[parameters] as the key.
methodSignatureLookupMap.add(
buildString {
append(accessFlagsReturnKey)
appendParameters(method.parameterTypes)
},
methodClassPair
)
// Add strings contained in the method as the key.
method.implementation?.instructions?.forEach instructions@{ instruction ->
if (instruction.opcode != Opcode.CONST_STRING && instruction.opcode != Opcode.CONST_STRING_JUMBO)
return@instructions
val string = ((instruction as ReferenceInstruction).reference as StringReference).string
methodStringsLookupMap.add(string, methodClassPair)
}
// In the future, the class type could be added to the lookup map.
// This would require MethodFingerprint to be changed to include the class type.
}
}
}
/**
* Clears the internal lookup maps created in [initializeFingerprintResolutionLookupMaps]
*/
internal fun clearFingerprintResolutionLookupMaps() {
methods.clear()
methodSignatureLookupMap.clear()
methodStringsLookupMap.clear()
}
/**
* Resolve a list of [MethodFingerprint] using the lookup map built by [initializeFingerprintResolutionLookupMaps].
*
* [MethodFingerprint] resolution is fast, but if many are present they can consume a noticeable
* amount of time because they are resolved in sequence.
*
* For apps with many fingerprints, resolving performance can be improved by:
* - Slowest: Specify [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.
*/
internal fun Set<MethodFingerprint>.resolveUsingLookupMap(context: BytecodeContext) {
if (methods.isEmpty()) throw PatchException("lookup map not initialized")
forEach { fingerprint ->
fingerprint.resolveUsingLookupMap(context)
}
}
/**
* Resolve a [MethodFingerprint] using the lookup map built by [initializeFingerprintResolutionLookupMaps].
*
* [MethodFingerprint] resolution is fast, but if many are present they can consume a noticeable
* amount of time because they are resolved in sequence.
*
* For apps with many fingerprints, resolving performance can be improved by:
* - Slowest: Specify [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.
*/
internal fun MethodFingerprint.resolveUsingLookupMap(context: BytecodeContext): Boolean {
/**
* Lookup [MethodClassPair]s that match the methods strings present in a [MethodFingerprint].
*
* @return A list of [MethodClassPair]s that match the methods strings present in a [MethodFingerprint].
*/
fun MethodFingerprint.methodStringsLookup(): List<MethodClassPair>? {
strings?.forEach {
val methods = methodStringsLookupMap[it]
if (methods != null) return methods
}
return null
}
/**
* Lookup [MethodClassPair]s that match the method signature present in a [MethodFingerprint].
*
* @return A list of [MethodClassPair]s that match the method signature present in a [MethodFingerprint].
*/
fun MethodFingerprint.methodSignatureLookup(): List<MethodClassPair> {
if (accessFlags == null) return methods
var returnTypeValue = returnType
if (returnTypeValue == null) {
if (AccessFlags.CONSTRUCTOR.isSet(accessFlags)) {
// Constructors always have void return type
returnTypeValue = "V"
} else {
return methods
}
}
val key = buildString {
append(accessFlags)
append(returnTypeValue.first())
if (parameters != null) appendParameters(parameters)
}
return methodSignatureLookupMap[key] ?: return emptyList()
}
/**
* Resolve a [MethodFingerprint] using a list of [MethodClassPair].
*
* @return True if the resolution was successful, false otherwise.
*/
fun MethodFingerprint.resolveUsingMethodClassPair(classMethods: Iterable<MethodClassPair>): Boolean {
classMethods.forEach { classAndMethod ->
if (resolve(context, classAndMethod.first, classAndMethod.second)) return true
}
return false
}
val methodsWithSameStrings = methodStringsLookup()
if (methodsWithSameStrings != null) if (resolveUsingMethodClassPair(methodsWithSameStrings)) return true
// No strings declared or none matched (partial matches are allowed).
// Use signature matching.
return resolveUsingMethodClassPair(methodSignatureLookup())
}
/**
* Resolve a list of [MethodFingerprint] against a list of [ClassDef].
*
* @param classes The classes on which to resolve the [MethodFingerprint] in.
* @param context The [BytecodeContext] to host proxies.
* @return True if the resolution was successful, false otherwise.
*/
fun Iterable<MethodFingerprint>.resolve(context: BytecodeContext, classes: Iterable<ClassDef>) {
for (fingerprint in this) // For each fingerprint...
classes@ for (classDef in classes) // ...search through all classes for the MethodFingerprint
if (fingerprint.resolve(context, classDef))
break@classes // ...if the resolution succeeded, continue with the next MethodFingerprint.
}
/**
* Resolve a [MethodFingerprint] against a [ClassDef].
*
* @param forClass The class on which to resolve the [MethodFingerprint] in.
* @param context The [BytecodeContext] to host proxies.
* @return True if the resolution was successful, false otherwise.
*/
fun MethodFingerprint.resolve(context: BytecodeContext, forClass: ClassDef): Boolean {
for (method in forClass.methods)
if (this.resolve(context, method, forClass))
return true
return false
}
/**
* Resolve a [MethodFingerprint] against a [Method].
*
* @param method The class on which to resolve the [MethodFingerprint] in.
* @param forClass The class on which to resolve the [MethodFingerprint].
* @param context The [BytecodeContext] to host proxies.
* @return True if the resolution was successful or if the fingerprint is already resolved, false otherwise.
*/
fun MethodFingerprint.resolve(context: BytecodeContext, method: Method, forClass: ClassDef): Boolean {
val methodFingerprint = this
if (methodFingerprint.result != null) return true
if (methodFingerprint.returnType != null && !method.returnType.startsWith(methodFingerprint.returnType))
return false
if (methodFingerprint.accessFlags != null && methodFingerprint.accessFlags != method.accessFlags)
return false
fun parametersEqual(
parameters1: Iterable<CharSequence>, parameters2: Iterable<CharSequence>
): Boolean {
if (parameters1.count() != parameters2.count()) return false
val iterator1 = parameters1.iterator()
parameters2.forEach {
if (!it.startsWith(iterator1.next())) return false
}
return true
}
if (methodFingerprint.parameters != null && !parametersEqual(
methodFingerprint.parameters, // TODO: parseParameters()
method.parameterTypes
)
) return false
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
if (methodFingerprint.customFingerprint != null && !methodFingerprint.customFingerprint!!(method, forClass))
return false
val stringsScanResult: StringsScanResult? =
if (methodFingerprint.strings != null) {
StringsScanResult(
buildList {
val implementation = method.implementation ?: return false
val stringsList = methodFingerprint.strings.toMutableList()
implementation.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(
StringMatch(
string,
instructionIndex
)
)
stringsList.removeAt(index)
}
if (stringsList.isNotEmpty()) return false
}
)
} else null
val patternScanResult = if (methodFingerprint.opcodes != null) {
method.implementation?.instructions ?: return false
fun Method.patternScan(
fingerprint: MethodFingerprint
): MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult? {
val instructions = this.implementation!!.instructions
val fingerprintFuzzyPatternScanThreshold = fingerprint.fuzzyPatternScanMethod?.threshold ?: 0
val pattern = fingerprint.opcodes!!
val instructionLength = instructions.count()
val patternLength = pattern.count()
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 = pattern.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 pattern is valid, generate warnings if fuzzyPatternScanMethod is FuzzyPatternScanMethod
val result =
MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult(
index,
index + patternIndex
)
if (fingerprint.fuzzyPatternScanMethod !is FuzzyPatternScanMethod) return result
result.warnings = result.createWarnings(pattern, instructions)
return result
}
}
return null
}
method.patternScan(methodFingerprint) ?: return false
} else null
methodFingerprint.result = MethodFingerprintResult(
method,
forClass,
MethodFingerprintResult.MethodFingerprintScanResult(
patternScanResult,
stringsScanResult
),
context
)
return true
}
private fun MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult.createWarnings(
pattern: Iterable<Opcode?>, instructions: Iterable<Instruction>
) = buildList {
for ((patternIndex, instructionIndex) in (this@createWarnings.startIndex until this@createWarnings.endIndex).withIndex()) {
val originalOpcode = instructions.elementAt(instructionIndex).opcode
val patternOpcode = pattern.elementAt(patternIndex)
if (patternOpcode == null || patternOpcode.ordinal == originalOpcode.ordinal) continue
this.add(
MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult.Warning(
originalOpcode,
patternOpcode,
instructionIndex,
patternIndex
)
)
}
}
}
}
/**
* Represents the result of a [MethodFingerprintResult].
*
* @param method The matching method.
* @param classDef The [ClassDef] that contains the matching [method].
* @param scanResult The result of scanning for the [MethodFingerprint].
* @param context The [BytecodeContext] this [MethodFingerprintResult] is attached to, to create proxies.
*/
data class MethodFingerprintResult(
val method: Method,
val classDef: ClassDef,
val scanResult: MethodFingerprintScanResult,
internal val context: BytecodeContext
) {
/**
* Returns a mutable clone of [classDef]
*
* Please note, this method allocates a [ClassProxy].
* Use [classDef] where possible.
*/
@Suppress("MemberVisibilityCanBePrivate")
val mutableClass by lazy { context.proxy(classDef).mutableClass }
/**
* Returns a mutable clone of [method]
*
* Please note, this method allocates a [ClassProxy].
* Use [method] where possible.
*/
val mutableMethod by lazy {
mutableClass.methods.first {
MethodUtil.methodSignaturesMatch(it, this.method)
}
}
/**
* The result of scanning on the [MethodFingerprint].
* @param patternScanResult The result of the pattern scan.
* @param stringsScanResult The result of the string scan.
*/
data class MethodFingerprintScanResult(
val patternScanResult: PatternScanResult?,
val stringsScanResult: StringsScanResult?
) {
/**
* The result of scanning strings on the [MethodFingerprint].
* @param matches The list of strings that were matched.
*/
data class StringsScanResult(val matches: List<StringMatch>) {
/**
* Represents a match for a string at an index.
* @param string The string that was matched.
* @param index The index of the string.
*/
data class StringMatch(val string: String, val index: Int)
}
/**
* The result of a pattern scan.
* @param startIndex The start index of the instructions where to which this pattern matches.
* @param endIndex The end index of the instructions where to which this pattern matches.
* @param warnings A list of warnings considering this [PatternScanResult].
*/
data class PatternScanResult(
val startIndex: Int,
val endIndex: Int,
var warnings: List<Warning>? = null
) {
/**
* Represents warnings of the pattern scan.
* @param correctOpcode The opcode the instruction list has.
* @param wrongOpcode The opcode the pattern list of the signature currently has.
* @param instructionIndex The index of the opcode relative to the instruction list.
* @param patternIndex The index of the opcode relative to the pattern list from the signature.
*/
data class Warning(
val correctOpcode: Opcode,
val wrongOpcode: Opcode,
val instructionIndex: Int,
val patternIndex: Int,
)
}
}
}

View file

@ -1,9 +0,0 @@
package app.revanced.patcher.logging
@Deprecated("This will be removed in a future release")
interface Logger {
fun error(msg: String) {}
fun warn(msg: String) {}
fun info(msg: String) {}
fun trace(msg: String) {}
}

View file

@ -1,6 +0,0 @@
package app.revanced.patcher.logging.impl
import app.revanced.patcher.logging.Logger
@Deprecated("This will be removed in a future release")
object NopLogger : Logger

View file

@ -1,27 +0,0 @@
package app.revanced.patcher.patch
import app.revanced.patcher.PatchClass
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
/**
* A ReVanced [Patch] that works on [BytecodeContext].
*
* @param fingerprints A list of [MethodFingerprint]s which will be resolved before the patch is executed.
* @param name The name of the patch.
* @param description The description of the patch.
* @param compatiblePackages The packages the patch is compatible with.
* @param dependencies The names of patches this patch depends on.
* @param use Weather or not the patch should be used.
* @param requiresIntegrations Weather or not the patch requires integrations.
*/
abstract class BytecodePatch(
internal val fingerprints: Set<MethodFingerprint> = emptySet(),
name: String? = null,
description: String? = null,
compatiblePackages: Set<CompatiblePackage>? = null,
dependencies: Set<PatchClass>? = null,
use: Boolean = true,
// TODO: Remove this property, once integrations are coupled with patches.
requiresIntegrations: Boolean = false,
) : Patch<BytecodeContext>(name, description, compatiblePackages, dependencies, use, requiresIntegrations)

View file

@ -1,24 +0,0 @@
package app.revanced.patcher.patch
import app.revanced.patcher.PatchClass
import app.revanced.patcher.data.ResourceContext
/**
* A ReVanced [Patch] that works on [ResourceContext].
*
* @param name The name of the patch.
* @param description The description of the patch.
* @param compatiblePackages The packages the patch is compatible with.
* @param dependencies The names of patches this patch depends on.
* @param use Weather or not the patch should be used.
* @param requiresIntegrations Weather or not the patch requires integrations.
*/
abstract class ResourcePatch(
name: String? = null,
description: String? = null,
compatiblePackages: Set<CompatiblePackage>? = null,
dependencies: Set<PatchClass>? = null,
use: Boolean = true,
// TODO: Remove this property, once integrations are coupled with patches.
requiresIntegrations: Boolean = false,
) : Patch<ResourceContext>(name, description, compatiblePackages, dependencies, use, requiresIntegrations)

View file

@ -1,40 +0,0 @@
package app.revanced.patcher.patch.options
import app.revanced.patcher.patch.Patch
import kotlin.reflect.KProperty
/**
* A [Patch] option.
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validate The function to validate values of the option.
* @param T The value type of the option.
*/
abstract class PatchOption<T>(
val key: String,
default: T?,
val title: String?,
val description: String?,
val required: Boolean,
val validate: (T?) -> Boolean
) {
/**
* The value of the [PatchOption].
*/
var value: T? = default
set(value) {
if (required && value == null) throw PatchOptionException.ValueRequiredException(this)
if (!validate(value)) throw PatchOptionException.ValueValidationException(value, this)
field = value
}
operator fun getValue(thisRef: Any?, property: KProperty<*>) = value
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
this.value = value
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing a [Boolean].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class BooleanPatchOption private constructor(
key: String,
default: Boolean?,
title: String?,
description: String?,
required: Boolean,
validator: (Boolean?) -> Boolean
) : PatchOption<Boolean>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [BooleanPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [BooleanPatchOption].
*
* @see BooleanPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.booleanPatchOption(
key: String,
default: Boolean? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Boolean?) -> Boolean = { true }
) = BooleanPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing a [Float].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class FloatPatchOption private constructor(
key: String,
default: Float?,
title: String?,
description: String?,
required: Boolean,
validator: (Float?) -> Boolean
) : PatchOption<Float>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [FloatPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [FloatPatchOption].
*
* @see FloatPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.floatPatchOption(
key: String,
default: Float? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Float?) -> Boolean = { true }
) = FloatPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing an [Integer].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class IntPatchOption private constructor(
key: String,
default: Int?,
title: String?,
description: String?,
required: Boolean,
validator: (Int?) -> Boolean
) : PatchOption<Int>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [IntPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [IntPatchOption].
*
* @see IntPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.intPatchOption(
key: String,
default: Int? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Int?) -> Boolean = { true }
) = IntPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing a [Long].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class LongPatchOption private constructor(
key: String,
default: Long?,
title: String?,
description: String?,
required: Boolean,
validator: (Long?) -> Boolean
) : PatchOption<Long>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [LongPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [LongPatchOption].
*
* @see LongPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.longPatchOption(
key: String,
default: Long? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Long?) -> Boolean = { true }
) = LongPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing a [String].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class StringPatchOption private constructor(
key: String,
default: String?,
title: String?,
description: String?,
required: Boolean,
validator: (String?) -> Boolean
) : PatchOption<String>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [StringPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [StringPatchOption].
*
* @see StringPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.stringPatchOption(
key: String,
default: String? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (String?) -> Boolean = { true }
) = StringPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types.array
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing a [Boolean] array.
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class BooleanArrayPatchOption private constructor(
key: String,
default: Array<Boolean>?,
title: String?,
description: String?,
required: Boolean,
validator: (Array<Boolean>?) -> Boolean
) : PatchOption<Array<Boolean>>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [BooleanArrayPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [BooleanArrayPatchOption].
*
* @see BooleanArrayPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.booleanArrayPatchOption(
key: String,
default: Array<Boolean>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Array<Boolean>?) -> Boolean = { true }
) = BooleanArrayPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types.array
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing a [Float] array.
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class FloatArrayPatchOption private constructor(
key: String,
default: Array<Float>?,
title: String?,
description: String?,
required: Boolean,
validator: (Array<Float>?) -> Boolean
) : PatchOption<Array<Float>>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [FloatArrayPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [FloatArrayPatchOption].
*
* @see FloatArrayPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.floatArrayPatchOption(
key: String,
default: Array<Float>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Array<Float>?) -> Boolean = { true }
) = FloatArrayPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types.array
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing an [Integer] array.
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class IntArrayPatchOption private constructor(
key: String,
default: Array<Int>?,
title: String?,
description: String?,
required: Boolean,
validator: (Array<Int>?) -> Boolean
) : PatchOption<Array<Int>>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [IntArrayPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [IntArrayPatchOption].
*
* @see IntArrayPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.intArrayPatchOption(
key: String,
default: Array<Int>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Array<Int>?) -> Boolean = { true }
) = IntArrayPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types.array
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing a [Long] array.
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class LongArrayPatchOption private constructor(
key: String,
default: Array<Long>?,
title: String?,
description: String?,
required: Boolean,
validator: (Array<Long>?) -> Boolean
) : PatchOption<Array<Long>>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [LongArrayPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [LongArrayPatchOption].
*
* @see LongArrayPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.longArrayPatchOption(
key: String,
default: Array<Long>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Array<Long>?) -> Boolean = { true }
) = LongArrayPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,48 +0,0 @@
package app.revanced.patcher.patch.options.types.array
import app.revanced.patcher.patch.Patch
import app.revanced.patcher.patch.options.PatchOption
/**
* A [PatchOption] representing a [String] array.
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
*
* @see PatchOption
*/
class StringArrayPatchOption private constructor(
key: String,
default: Array<String>?,
title: String?,
description: String?,
required: Boolean,
validator: (Array<String>?) -> Boolean
) : PatchOption<Array<String>>(key, default, title, description, required, validator) {
companion object {
/**
* Create a new [StringArrayPatchOption] and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @return The created [StringArrayPatchOption].
*
* @see StringArrayPatchOption
* @see PatchOption
*/
fun <T : Patch<*>> T.stringArrayPatchOption(
key: String,
default: Array<String>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: (Array<String>?) -> Boolean = { true }
) = StringArrayPatchOption(key, default, title, description, required, validator).also { options.register(it) }
}
}

View file

@ -1,59 +0,0 @@
package app.revanced.patcher.patch.options
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.options.types.BooleanPatchOption.Companion.booleanPatchOption
import app.revanced.patcher.patch.options.types.StringPatchOption.Companion.stringPatchOption
import app.revanced.patcher.patch.options.types.array.StringArrayPatchOption.Companion.stringArrayPatchOption
import org.junit.jupiter.api.assertDoesNotThrow
import org.junit.jupiter.api.assertThrows
import kotlin.test.Test
internal class PatchOptionsTest {
@Test
fun `should not fail because default value is unvalidated`() {
assertDoesNotThrow {
OptionsTestPatch.options["required"].value
}
}
@Test
fun `should throw due to incorrect type`() {
assertThrows<PatchOptionException.InvalidValueTypeException> {
OptionsTestPatch.options["bool"] = 0
}
}
@Test
fun `should be nullable`() {
OptionsTestPatch.options["bool"] = null
}
@Test
fun `option should not be found`() {
assertThrows<PatchOptionException.PatchOptionNotFoundException> {
OptionsTestPatch.options["this option does not exist"] = 1
}
}
@Test
fun `should be able to add options manually`() {
assertThrows<PatchOptionException.InvalidValueTypeException> {
OptionsTestPatch.options["array"] = OptionsTestPatch.stringArrayOption
}
assertDoesNotThrow {
OptionsTestPatch.options.register(OptionsTestPatch.stringArrayOption)
}
}
private object OptionsTestPatch : BytecodePatch() {
private var stringOption by stringPatchOption("string", "default")
private var booleanOption by booleanPatchOption("bool", true)
private var requiredStringOption by stringPatchOption("required", "default", required = true)
private var nullDefaultRequiredOption by stringPatchOption("null", null, required = true)
val stringArrayOption = stringArrayPatchOption("array", arrayOf("1", "2"))
override fun execute(context: BytecodeContext) {}
}
}

View file

@ -1 +1 @@
include("revanced-patch-annotation-processor", "revanced-patcher")
rootProject.name = "revanced-patcher"

View file

@ -2,8 +2,9 @@ package app.revanced.patcher
import app.revanced.patcher.PatchBundleLoader.Utils.getInstance
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolveUsingLookupMap
import app.revanced.patcher.fingerprint.LookupMap.Maps.clearLookupMaps
import app.revanced.patcher.fingerprint.LookupMap.Maps.initializeLookupMaps
import app.revanced.patcher.fingerprint.MethodFingerprint.Companion.resolveUsingLookupMap
import app.revanced.patcher.patch.*
import kotlinx.coroutines.flow.flow
import java.io.Closeable
@ -187,7 +188,7 @@ class Patcher(
if (context.bytecodeContext.integrations.merge) context.bytecodeContext.integrations.flush()
MethodFingerprint.initializeFingerprintResolutionLookupMaps(context.bytecodeContext)
initializeLookupMaps(context.bytecodeContext)
// Prevent from decoding the app manifest twice if it is not needed.
if (options.resourceDecodingMode == ResourceContext.ResourceDecodingMode.FULL)
@ -249,7 +250,7 @@ class Patcher(
}
}
override fun close() = MethodFingerprint.clearFingerprintResolutionLookupMaps()
override fun close() = clearLookupMaps()
/**
* Compile and save the patched APK file.

View file

@ -37,4 +37,5 @@ class PatcherContext internal constructor(options: PatcherOptions) {
* The [BytecodeContext] of this [PatcherContext].
* This holds the current state of the bytecode.
*/
internal val bytecodeContext = BytecodeContext(options) }
internal val bytecodeContext = BytecodeContext(options)
}

View file

@ -38,27 +38,6 @@ data class PatcherOptions(
frameworkDirectory = frameworkFileDirectory
}
/**
* Options for ReVanced [Patcher].
* @param inputFile The input file to patch.
* @param resourceCachePath The path to the directory to use for caching resources.
* @param aaptBinaryPath The path to a custom aapt binary.
* @param frameworkFileDirectory The path to the directory to cache the framework file in.
*/
@Deprecated("Use the constructor with the multithreadingDexFileWriter parameter instead")
constructor(
inputFile: File,
resourceCachePath: File = File("revanced-resource-cache"),
aaptBinaryPath: String? = null,
frameworkFileDirectory: String? = null,
) : this(
inputFile,
resourceCachePath,
aaptBinaryPath,
frameworkFileDirectory,
false,
)
fun recreateResourceCacheDirectory() = resourceCachePath.also {
if (it.exists()) {
logger.info("Deleting existing resource cache directory")

View file

@ -90,6 +90,36 @@ class BytecodeContext internal constructor(private val options: PatcherOptions)
*/
fun toMethodWalker(startMethod: Method) = MethodWalker(this, startMethod)
/**
* Compile bytecode from the [BytecodeContext].
*
* @return The compiled bytecode.
*/
override fun get(): List<PatcherResult.PatchedDexFile> {
logger.info("Compiling patched dex files")
val patchedDexFileResults = options.resourceCachePath.resolve("dex").also {
it.deleteRecursively() // Make sure the directory is empty.
it.mkdirs()
}.apply {
MultiDexIO.writeDexFile(
true,
if (options.multithreadingDexFileWriter) -1 else 1,
this,
BasicDexFileNamer(),
object : DexFile {
override fun getClasses() = this@BytecodeContext.classes.also(ProxyClassList::replaceClasses)
override fun getOpcodes() = this@BytecodeContext.opcodes
},
DexIO.DEFAULT_MAX_DEX_POOL_SIZE
) { _, entryName, _ -> logger.info("Compiled $entryName") }
}.listFiles(FileFilter { it.isFile })!!.map { PatcherResult.PatchedDexFile(it.name, it.inputStream()) }
System.gc()
return patchedDexFileResults
}
/**
* The integrations of a [PatcherContext].
*/
@ -135,32 +165,4 @@ class BytecodeContext internal constructor(private val options: PatcherOptions)
clear()
}
}
/**
* Compile bytecode from the [BytecodeContext].
*
* @return The compiled bytecode.
*/
override fun get(): List<PatcherResult.PatchedDexFile> {
logger.info("Compiling patched dex files")
val patchedDexFileResults = options.resourceCachePath.resolve("dex").also {
it.deleteRecursively() // Make sure the directory is empty.
it.mkdirs()
}.apply {
MultiDexIO.writeDexFile(
true,
if (options.multithreadingDexFileWriter) -1 else 1,
this,
BasicDexFileNamer(),
object : DexFile {
override fun getClasses() = this@BytecodeContext.classes.also(ProxyClassList::replaceClasses)
override fun getOpcodes() = this@BytecodeContext.opcodes
},
DexIO.DEFAULT_MAX_DEX_POOL_SIZE
) { _, entryName, _ -> logger.info("Compiled $entryName") }
}.listFiles(FileFilter { it.isFile })!!.map { PatcherResult.PatchedDexFile(it.name, it.inputStream()) }
return patchedDexFileResults
}
}

View file

@ -1,8 +1,8 @@
package app.revanced.patcher.extensions
import app.revanced.patcher.extensions.AnnotationExtensions.findAnnotationRecursively
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.MethodFingerprint
object MethodFingerprintExtensions {
// TODO: Make this a property.

View file

@ -0,0 +1,125 @@
package app.revanced.patcher.fingerprint
import app.revanced.patcher.data.BytecodeContext
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 java.util.*
internal typealias MethodClassPair = Pair<Method, ClassDef>
/**
* Lookup map for methods.
*/
internal class LookupMap : MutableMap<String, LookupMap.MethodClassList> by mutableMapOf() {
/**
* Adds a [MethodClassPair] to the list associated with the given key.
* If the key does not exist, a new list is created and the [MethodClassPair] is added to it.
*/
fun add(
key: String,
methodClassPair: MethodClassPair
) {
getOrPut(key) { MethodClassList() }.add(methodClassPair)
}
/**
* List of methods and the class they are a member of.
*/
internal class MethodClassList : LinkedList<MethodClassPair>()
companion object Maps {
/**
* A list of methods and the class they are a member of.
*/
internal val methods = MethodClassList()
/**
* Lookup map for methods keyed to the methods access flags, return type and parameter.
*/
internal val methodSignatureLookupMap = LookupMap()
/**
* Lookup map for methods associated by strings referenced in the method.
*/
internal val methodStringsLookupMap = LookupMap()
/**
* Initializes lookup maps for [MethodFingerprint] resolution
* using attributes of methods such as the method signature or strings.
*
* @param context The [BytecodeContext] containing the classes to initialize the lookup maps with.
*/
internal fun initializeLookupMaps(context: BytecodeContext) {
if (methods.isNotEmpty()) clearLookupMaps()
context.classes.forEach { classDef ->
classDef.methods.forEach { method ->
val methodClassPair = method to classDef
// For fingerprints with no access or return type specified.
methods += methodClassPair
val accessFlagsReturnKey = method.accessFlags.toString() + method.returnType.first()
// Add <access><returnType> as the key.
methodSignatureLookupMap.add(accessFlagsReturnKey, methodClassPair)
// Add <access><returnType>[parameters] as the key.
methodSignatureLookupMap.add(
buildString {
append(accessFlagsReturnKey)
appendParameters(method.parameterTypes)
},
methodClassPair
)
// Add strings contained in the method as the key.
method.implementation?.instructions?.forEach instructions@{ instruction ->
if (instruction.opcode != Opcode.CONST_STRING && instruction.opcode != Opcode.CONST_STRING_JUMBO)
return@instructions
val string = ((instruction as ReferenceInstruction).reference as StringReference).string
methodStringsLookupMap.add(string, methodClassPair)
}
// In the future, the class type could be added to the lookup map.
// This would require MethodFingerprint to be changed to include the class type.
}
}
}
/**
* Clears the internal lookup maps created in [initializeLookupMaps]
*/
internal fun clearLookupMaps() {
methods.clear()
methodSignatureLookupMap.clear()
methodStringsLookupMap.clear()
}
/**
* Appends a string based on the parameter reference types of this method.
*/
internal fun StringBuilder.appendParameters(parameters: Iterable<CharSequence>) {
// Maximum parameters to use in the signature key.
// Some apps have methods with an incredible number of parameters (over 100 parameters have been seen).
// To keep the signature map from becoming needlessly bloated,
// group together in the same map entry all methods with the same access/return and 5 or more parameters.
// The value of 5 was chosen based on local performance testing and is not set in stone.
val maxSignatureParameters = 5
// Must append a unique value before the parameters to distinguish this key includes the parameters.
// If this is not appended, then methods with no parameters
// will collide with different keys that specify access/return but omit the parameters.
append("p:")
parameters.forEachIndexed { index, parameter ->
if (index >= maxSignatureParameters) return
append(parameter.first())
}
}
}
}

View file

@ -0,0 +1,320 @@
package app.revanced.patcher.fingerprint
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.MethodFingerprintExtensions.fuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.LookupMap.Maps.appendParameters
import app.revanced.patcher.fingerprint.LookupMap.Maps.initializeLookupMaps
import app.revanced.patcher.fingerprint.LookupMap.Maps.methodSignatureLookupMap
import app.revanced.patcher.fingerprint.LookupMap.Maps.methodStringsLookupMap
import app.revanced.patcher.fingerprint.LookupMap.Maps.methods
import app.revanced.patcher.fingerprint.MethodFingerprintResult.MethodFingerprintScanResult.StringsScanResult
import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod
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.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.StringReference
/**
* A fingerprint to resolve methods.
*
* @param returnType The method's return type compared using [String.startsWith].
* @param accessFlags The method's exact access flags using values of [AccessFlags].
* @param parameters The parameters of the method. Partial matches allowed and follow the same rules as [returnType].
* @param opcodes An opcode pattern of the method's instructions. Wildcard or unknown opcodes can be specified by `null`.
* @param strings A list of the method's strings compared each using [String.contains].
* @param customFingerprint A custom condition for this fingerprint.
*/
abstract class MethodFingerprint(
internal val returnType: String? = null,
internal val accessFlags: Int? = null,
internal val parameters: Iterable<String>? = null,
internal val opcodes: Iterable<Opcode?>? = null,
internal val strings: Iterable<String>? = null,
internal val customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null
) {
/**
* The result of the [MethodFingerprint].
*/
var result: MethodFingerprintResult? = null
private set
/**
* Resolve a [MethodFingerprint] using the lookup map built by [initializeLookupMaps].
*
* [MethodFingerprint] resolution is fast, but if many are present they can consume a noticeable
* amount of time because they are resolved in sequence.
*
* For apps with many fingerprints, resolving performance can be improved by:
* - Slowest: Specify [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.
*/
internal fun resolveUsingLookupMap(context: BytecodeContext): Boolean {
/**
* Lookup [MethodClassPair]s that match the methods strings present in a [MethodFingerprint].
*
* @return A list of [MethodClassPair]s that match the methods strings present in a [MethodFingerprint].
*/
fun MethodFingerprint.methodStringsLookup(): LookupMap.MethodClassList? {
strings?.forEach {
val methods = methodStringsLookupMap[it]
if (methods != null) return methods
}
return null
}
/**
* Lookup [MethodClassPair]s that match the method signature present in a [MethodFingerprint].
*
* @return A list of [MethodClassPair]s that match the method signature present in a [MethodFingerprint].
*/
fun MethodFingerprint.methodSignatureLookup(): LookupMap.MethodClassList {
if (accessFlags == null) return methods
var returnTypeValue = returnType
if (returnTypeValue == null) {
if (AccessFlags.CONSTRUCTOR.isSet(accessFlags)) {
// Constructors always have void return type
returnTypeValue = "V"
} else {
return methods
}
}
val key = buildString {
append(accessFlags)
append(returnTypeValue.first())
if (parameters != null) appendParameters(parameters)
}
return methodSignatureLookupMap[key] ?: return LookupMap.MethodClassList()
}
/**
* Resolve a [MethodFingerprint] using a list of [MethodClassPair].
*
* @return True if the resolution was successful, false otherwise.
*/
fun MethodFingerprint.resolveUsingMethodClassPair(methodClasses: LookupMap.MethodClassList): Boolean {
methodClasses.forEach { classAndMethod ->
if (resolve(context, classAndMethod.first, classAndMethod.second)) return true
}
return false
}
val methodsWithSameStrings = methodStringsLookup()
if (methodsWithSameStrings != null) if (resolveUsingMethodClassPair(methodsWithSameStrings)) return true
// No strings declared or none matched (partial matches are allowed).
// Use signature matching.
return resolveUsingMethodClassPair(methodSignatureLookup())
}
/**
* Resolve a [MethodFingerprint] against a [ClassDef].
*
* @param forClass The class on which to resolve the [MethodFingerprint] in.
* @param context The [BytecodeContext] to host proxies.
* @return True if the resolution was successful, false otherwise.
*/
fun resolve(context: BytecodeContext, forClass: ClassDef): Boolean {
for (method in forClass.methods)
if (resolve(context, method, forClass))
return true
return false
}
/**
* Resolve a [MethodFingerprint] against a [Method].
*
* @param method The class on which to resolve the [MethodFingerprint] in.
* @param forClass The class on which to resolve the [MethodFingerprint].
* @param context The [BytecodeContext] to host proxies.
* @return True if the resolution was successful or if the fingerprint is already resolved, false otherwise.
*/
fun resolve(context: BytecodeContext, method: Method, forClass: ClassDef): Boolean {
val methodFingerprint = this
if (methodFingerprint.result != null) return true
if (methodFingerprint.returnType != null && !method.returnType.startsWith(methodFingerprint.returnType))
return false
if (methodFingerprint.accessFlags != null && methodFingerprint.accessFlags != method.accessFlags)
return false
fun parametersEqual(
parameters1: Iterable<CharSequence>, parameters2: Iterable<CharSequence>
): Boolean {
if (parameters1.count() != parameters2.count()) return false
val iterator1 = parameters1.iterator()
parameters2.forEach {
if (!it.startsWith(iterator1.next())) return false
}
return true
}
if (methodFingerprint.parameters != null && !parametersEqual(
methodFingerprint.parameters, // TODO: parseParameters()
method.parameterTypes
)
) return false
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
if (methodFingerprint.customFingerprint != null && !methodFingerprint.customFingerprint!!(method, forClass))
return false
val stringsScanResult: StringsScanResult? =
if (methodFingerprint.strings != null) {
StringsScanResult(
buildList {
val implementation = method.implementation ?: return false
val stringsList = methodFingerprint.strings.toMutableList()
implementation.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(StringsScanResult.StringMatch(string, instructionIndex))
stringsList.removeAt(index)
}
if (stringsList.isNotEmpty()) return false
}
)
} else null
val patternScanResult = if (methodFingerprint.opcodes != null) {
method.implementation?.instructions ?: return false
fun MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult.newWarnings(
pattern: Iterable<Opcode?>, instructions: Iterable<Instruction>
) = buildList {
for ((patternIndex, instructionIndex) in (this@newWarnings.startIndex until this@newWarnings.endIndex).withIndex()) {
val originalOpcode = instructions.elementAt(instructionIndex).opcode
val patternOpcode = pattern.elementAt(patternIndex)
if (patternOpcode == null || patternOpcode.ordinal == originalOpcode.ordinal) continue
this.add(
MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult.Warning(
originalOpcode,
patternOpcode,
instructionIndex,
patternIndex
)
)
}
}
fun Method.patternScan(
fingerprint: MethodFingerprint
): MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult? {
val instructions = this.implementation!!.instructions
val fingerprintFuzzyPatternScanThreshold = fingerprint.fuzzyPatternScanMethod?.threshold ?: 0
val pattern = fingerprint.opcodes!!
val instructionLength = instructions.count()
val patternLength = pattern.count()
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 = pattern.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 pattern is valid, generate warnings if fuzzyPatternScanMethod is FuzzyPatternScanMethod
val result =
MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult(
index,
index + patternIndex
)
if (fingerprint.fuzzyPatternScanMethod !is FuzzyPatternScanMethod) return result
result.warnings = result.newWarnings(pattern, instructions)
return result
}
}
return null
}
method.patternScan(methodFingerprint) ?: return false
} else null
methodFingerprint.result = MethodFingerprintResult(
method,
forClass,
MethodFingerprintResult.MethodFingerprintScanResult(
patternScanResult,
stringsScanResult
),
context
)
return true
}
companion object {
/**
* Resolve a list of [MethodFingerprint] using the lookup map built by [initializeLookupMaps].
*
* [MethodFingerprint] resolution is fast, but if many are present they can consume a noticeable
* amount of time because they are resolved in sequence.
*
* For apps with many fingerprints, resolving performance can be improved by:
* - Slowest: Specify [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.
*/
internal fun Set<MethodFingerprint>.resolveUsingLookupMap(context: BytecodeContext) {
if (methods.isEmpty()) throw PatchException("lookup map not initialized")
forEach { fingerprint ->
fingerprint.resolveUsingLookupMap(context)
}
}
/**
* Resolve a list of [MethodFingerprint] against a list of [ClassDef].
*
* @param classes The classes on which to resolve the [MethodFingerprint] in.
* @param context The [BytecodeContext] to host proxies.
* @return True if the resolution was successful, false otherwise.
*/
fun Iterable<MethodFingerprint>.resolve(context: BytecodeContext, classes: Iterable<ClassDef>) =
forEach { fingerprint ->
for (classDef in classes) {
if (fingerprint.resolve(context, classDef)) break
}
}
}
}

View file

@ -0,0 +1,94 @@
package app.revanced.patcher.fingerprint
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.util.proxy.ClassProxy
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.util.MethodUtil
/**
* Represents the result of a [MethodFingerprintResult].
*
* @param method The matching method.
* @param classDef The [ClassDef] that contains the matching [method].
* @param scanResult The result of scanning for the [MethodFingerprint].
* @param context The [BytecodeContext] this [MethodFingerprintResult] is attached to, to create proxies.
*/
@Suppress("MemberVisibilityCanBePrivate")
class MethodFingerprintResult(
val method: Method,
val classDef: ClassDef,
val scanResult: MethodFingerprintScanResult,
internal val context: BytecodeContext
) {
/**
* Returns a mutable clone of [classDef]
*
* Please note, this method allocates a [ClassProxy].
* Use [classDef] where possible.
*/
@Suppress("MemberVisibilityCanBePrivate")
val mutableClass by lazy { context.proxy(classDef).mutableClass }
/**
* Returns a mutable clone of [method]
*
* Please note, this method allocates a [ClassProxy].
* Use [method] where possible.
*/
val mutableMethod by lazy {
mutableClass.methods.first {
MethodUtil.methodSignaturesMatch(it, this.method)
}
}
/**
* The result of scanning on the [MethodFingerprint].
* @param patternScanResult The result of the pattern scan.
* @param stringsScanResult The result of the string scan.
*/
class MethodFingerprintScanResult(
val patternScanResult: PatternScanResult?,
val stringsScanResult: StringsScanResult?
) {
/**
* The result of scanning strings on the [MethodFingerprint].
* @param matches The list of strings that were matched.
*/
class StringsScanResult(val matches: List<StringMatch>) {
/**
* Represents a match for a string at an index.
* @param string The string that was matched.
* @param index The index of the string.
*/
class StringMatch(val string: String, val index: Int)
}
/**
* The result of a pattern scan.
* @param startIndex The start index of the instructions where to which this pattern matches.
* @param endIndex The end index of the instructions where to which this pattern matches.
* @param warnings A list of warnings considering this [PatternScanResult].
*/
class PatternScanResult(
val startIndex: Int,
val endIndex: Int,
var warnings: List<Warning>? = null
) {
/**
* Represents warnings of the pattern scan.
* @param correctOpcode The opcode the instruction list has.
* @param wrongOpcode The opcode the pattern list of the signature currently has.
* @param instructionIndex The index of the opcode relative to the instruction list.
* @param patternIndex The index of the opcode relative to the pattern list from the signature.
*/
class Warning(
val correctOpcode: Opcode,
val wrongOpcode: Opcode,
val instructionIndex: Int,
val patternIndex: Int,
)
}
}
}

View file

@ -1,6 +1,6 @@
package app.revanced.patcher.fingerprint.method.annotation
package app.revanced.patcher.fingerprint.annotation
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.MethodFingerprint
/**
* Annotations to scan a pattern [MethodFingerprint] with fuzzy algorithm.

View file

@ -0,0 +1,13 @@
package app.revanced.patcher.patch
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.fingerprint.MethodFingerprint
/**
* A ReVanced [Patch] that works on [BytecodeContext].
*
* @param fingerprints A list of [MethodFingerprint]s which will be resolved before the patch is executed.
*/
abstract class BytecodePatch(
internal val fingerprints : Set<MethodFingerprint> = emptySet(),
) : Patch<BytecodeContext>()

View file

@ -7,35 +7,72 @@ import app.revanced.patcher.Patcher
import app.revanced.patcher.data.Context
import app.revanced.patcher.patch.options.PatchOptions
import java.io.Closeable
import kotlin.reflect.full.findAnnotation
/**
* A ReVanced patch.
*
* If an implementation of [Patch] also implements [Closeable]
* it will be closed in reverse execution order of patches executed by ReVanced [Patcher].
*
* @param name The name of the patch.
* @param description The description of the patch.
* @param compatiblePackages The packages the patch is compatible with.
* @param dependencies The names of patches this patch depends on.
* @param use Weather or not the patch should be used.
* @param requiresIntegrations Weather or not the patch requires integrations.
* @param T The [Context] type this patch will work on.
*/
sealed class Patch<out T : Context<*>>(
val name: String? = null,
val description: String? = null,
val compatiblePackages: Set<CompatiblePackage>? = null,
val dependencies: Set<PatchClass>? = null,
val use: Boolean = true,
sealed class Patch<out T : Context<*>> {
/**
* The name of the patch.
*/
var name: String? = null
private set
/**
* The description of the patch.
*/
var description: String? = null
private set
/**
* The packages the patch is compatible with.
*/
var compatiblePackages: Set<CompatiblePackage>? = null
private set
/**
* Other patches this patch depends on.
*/
var dependencies: Set<PatchClass>? = null
private set
/**
* Weather or not the patch should be used.
*/
var use = true
private set
// TODO: Remove this property, once integrations are coupled with patches.
val requiresIntegrations: Boolean = false,
) {
/**
* Weather or not the patch requires integrations.
*/
var requiresIntegrations = false
private set
/**
* The options of the patch associated by the options key.
*/
val options = PatchOptions()
init {
this::class.findAnnotation<app.revanced.patcher.patch.annotation.Patch>()?.let { annotation ->
name = annotation.name.ifEmpty { null }
description = annotation.description.ifEmpty { null }
compatiblePackages = annotation.compatiblePackages
.map { CompatiblePackage(it.name, it.versions.toSet().ifEmpty { null }) }
.toSet().ifEmpty { null }
dependencies = annotation.dependencies.toSet().ifEmpty { null }
use = annotation.use
requiresIntegrations = annotation.requiresIntegrations
}
}
/**
* The execution function of the patch.
*
@ -67,5 +104,4 @@ sealed class Patch<out T : Context<*>>(
val name: String,
val versions: Set<String>? = null,
)
}
}

View file

@ -0,0 +1,8 @@
package app.revanced.patcher.patch
import app.revanced.patcher.data.ResourceContext
/**
* A ReVanced [Patch] that works on [ResourceContext].
*/
abstract class ResourcePatch : Patch<ResourceContext>()

View file

@ -13,7 +13,6 @@ import kotlin.reflect.KClass
* @param use Whether this patch should be used.
* @param requiresIntegrations Whether this patch requires integrations.
*/
@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.CLASS)
@Inherited
annotation class Patch(

View file

@ -0,0 +1,342 @@
package app.revanced.patcher.patch.options
import app.revanced.patcher.patch.Patch
import kotlin.reflect.KProperty
/**
* A [Patch] option.
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values identified by their string representation.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
* @param T The value type of the option.
*/
@Suppress("MemberVisibilityCanBePrivate", "unused")
open class PatchOption<T>(
val key: String,
val default: T?,
val values: Map<String, T?>?,
val title: String?,
val description: String?,
val required: Boolean,
val validator: PatchOption<T>.(T?) -> Boolean
) {
/**
* The value of the [PatchOption].
*/
var value: T?
/**
* Set the value of the [PatchOption].
*
* @param value The value to set.
*
* @throws PatchOptionException.ValueRequiredException If the value is required but null.
* @throws PatchOptionException.ValueValidationException If the value is invalid.
*/
set(value) {
assertRequiredButNotNull(value)
assertValid(value)
uncheckedValue = value
}
/**
* Get the value of the [PatchOption].
*
* @return The value.
*
* @throws PatchOptionException.ValueRequiredException If the value is required but null.
* @throws PatchOptionException.ValueValidationException If the value is invalid.
*/
get() {
assertRequiredButNotNull(uncheckedValue)
assertValid(uncheckedValue)
return uncheckedValue
}
// The unchecked value is used to allow setting the value without validation.
private var uncheckedValue = default
/**
* Reset the [PatchOption] to its default value.
* Override this method if you need to mutate the value instead of replacing it.
*/
open fun reset() {
uncheckedValue = default
}
private fun assertRequiredButNotNull(value: T?) {
if (required && value == null) throw PatchOptionException.ValueRequiredException(this)
}
private fun assertValid(value: T?) {
if (!validator(value)) throw PatchOptionException.ValueValidationException(value, this)
}
override fun toString() = value.toString()
operator fun getValue(thisRef: Any?, property: KProperty<*>) = value
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
this.value = value
}
@Suppress("unused")
companion object PatchExtensions {
/**
* Create a new [PatchOption] with a string value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.stringPatchOption(
key: String,
default: String? = null,
values: Map<String, String?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<String>.(String?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with an integer value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.intPatchOption(
key: String,
default: Int? = null,
values: Map<String, Int?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Int?>.(Int?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with a boolean value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.booleanPatchOption(
key: String,
default: Boolean? = null,
values: Map<String, Boolean?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Boolean?>.(Boolean?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with a float value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.floatPatchOption(
key: String,
default: Float? = null,
values: Map<String, Float?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Float?>.(Float?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with a long value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.longPatchOption(
key: String,
default: Long? = null,
values: Map<String, Long?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Long?>.(Long?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with a string array value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.stringArrayPatchOption(
key: String,
default: Array<String>? = null,
values: Map<String, Array<String>?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<String>?>.(Array<String>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with an integer array value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.intArrayPatchOption(
key: String,
default: Array<Int>? = null,
values: Map<String, Array<Int>?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<Int>?>.(Array<Int>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with a boolean array value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.booleanArrayPatchOption(
key: String,
default: Array<Boolean>? = null,
values: Map<String, Array<Boolean>?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<Boolean>?>.(Array<Boolean>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with a float array value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.floatArrayPatchOption(
key: String,
default: Array<Float>? = null,
values: Map<String, Array<Float>?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<Float>?>.(Array<Float>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
/**
* Create a new [PatchOption] with a long array value and add it to the current [Patch].
*
* @param key The identifier.
* @param default The default value.
* @param values The set of guaranteed valid values.
* @param title The title.
* @param description A description.
* @param required Whether the option is required.
* @param validator The function to validate the option value.
*
* @return The created [PatchOption].
*
* @see PatchOption
*/
fun <P : Patch<*>> P.longArrayPatchOption(
key: String,
default: Array<Long>? = null,
values: Map<String, Array<Long>?>? = null,
title: String? = null,
description: String? = null,
required: Boolean = false,
validator: PatchOption<Array<Long>?>.(Array<Long>?) -> Boolean = { true }
) = PatchOption(key, default, values, title, description, required, validator).also { registerOption(it) }
private fun <P : Patch<*>> P.registerOption(option: PatchOption<*>) = option.also { options.register(it) }
}
}

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