From afe27b960bca3123354dae58f2c4fc945dd5d920 Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Sat, 17 Jan 2026 18:11:32 +0100 Subject: [PATCH] add unordered/string matcher --- patcher/api/android/patcher.api | 126 ++++-- patcher/api/jvm/patcher.api | 126 ++++-- .../kotlin/app/revanced/patcher/Matching.kt | 375 ++++++++++++------ .../app/revanced/patcher/MatchingTest.kt | 83 +++- 4 files changed, 498 insertions(+), 212 deletions(-) diff --git a/patcher/api/android/patcher.api b/patcher/api/android/patcher.api index 6409275..0eeb45f 100644 --- a/patcher/api/android/patcher.api +++ b/patcher/api/android/patcher.api @@ -172,6 +172,47 @@ public final class app/revanced/patcher/IndexedMatcher : app/revanced/patcher/Ma public fun removeAt (I)Lkotlin/jvm/functions/Function4; } +public final class app/revanced/patcher/InstructionMatchingFunctions { + public static final field INSTANCE Lapp/revanced/patcher/InstructionMatchingFunctions; + public final fun field (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun field (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun field$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun field$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun instruction (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun instruction$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun invoke (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun invoke (Lcom/android/tools/smali/dexlib2/Opcode;)Lkotlin/jvm/functions/Function4; + public final fun invoke (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun invoke (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public static synthetic fun invoke$default (Lapp/revanced/patcher/InstructionMatchingFunctions;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun invoke$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun invoke$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun literal (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun literal (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun literal$default (Lapp/revanced/patcher/InstructionMatchingFunctions;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun literal$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun method (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun method (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun method$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun method$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun reference (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public static synthetic fun reference$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun registers (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public final fun registers ([ILkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public static synthetic fun registers$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun registers$default (Lapp/revanced/patcher/InstructionMatchingFunctions;[ILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun string (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun string (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun string (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun string$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun string$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun string$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun type (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun type (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun type$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun type$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; +} + public final class app/revanced/patcher/IterableClassDefClassDefMatching { public static final field INSTANCE Lapp/revanced/patcher/IterableClassDefClassDefMatching; public final fun firstClassDef (Ljava/lang/Iterable;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; @@ -238,7 +279,7 @@ public final class app/revanced/patcher/IterableMethodMethodMatching { } public final class app/revanced/patcher/Match { - public fun (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/util/List;)V + public fun (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/util/List;Ljava/util/Map;)V public final fun getClassDef ()Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public final fun getClassDefOrNull ()Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public final fun getContext ()Lapp/revanced/patcher/patch/BytecodePatchContext; @@ -249,6 +290,7 @@ public final class app/revanced/patcher/Match { public final fun getIndices ()Ljava/util/List; public final fun getMethod ()Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public final fun getMethodOrNull ()Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getStringIndices ()Ljava/util/Map; } public final class app/revanced/patcher/MatchBuilder { @@ -262,6 +304,7 @@ public final class app/revanced/patcher/MatchBuilder { public final fun getIndices ()Ljava/util/List; public final fun getMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public final fun getMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getStringIndices ()Ljava/util/Map; public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; } @@ -339,11 +382,7 @@ public final class app/revanced/patcher/MatchingKt { public static final fun definingClass (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V public static final fun definingClass (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static synthetic fun definingClass$default (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V - public static final fun field (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun field (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun field$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun field$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun firstMethodComposite ([Ljava/lang/String;Lkotlin/jvm/functions/Function5;)Lapp/revanced/patcher/MatchBuilder; + public static final fun firstMethodComposite ([Ljava/lang/String;Lkotlin/jvm/functions/Function6;)Lapp/revanced/patcher/MatchBuilder; public static final fun getClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public static final fun getClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public static final fun getImmutableClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; @@ -351,29 +390,14 @@ public final class app/revanced/patcher/MatchingKt { public static final fun implementation (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z public static final fun indexedMatcher (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/IndexedMatcher; public static final fun indexedMatcher ([Lkotlin/jvm/functions/Function4;)Lapp/revanced/patcher/IndexedMatcher; - public static final fun instruction (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun instruction$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; public static final fun instructions (Lapp/revanced/patcher/IndexedMatcher;Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static final fun instructions (Lapp/revanced/patcher/IndexedMatcher;Lapp/revanced/patcher/MutablePredicateList;[Lkotlin/jvm/functions/Function4;)V public static final fun instructions (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static final fun instructions (Lapp/revanced/patcher/MutablePredicateList;[Lkotlin/jvm/functions/Function4;)V - public static final fun invoke (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun invoke (Lcom/android/tools/smali/dexlib2/Opcode;)Lkotlin/jvm/functions/Function4; - public static final fun invoke (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static final fun invoke (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static synthetic fun invoke$default (JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun invoke$default (Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun invoke$default (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun literal (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun literal (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun literal$default (JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun literal$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; public static final fun matchIndexed (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;[Lkotlin/jvm/functions/Function4;)Z public static final fun matchIndexed (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z - public static final fun method (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun method (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun method$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun method$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static final fun matchUnordered (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;[Lkotlin/jvm/functions/Function1;)Z + public static final fun matchUnordered (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z public static final fun name (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V public static final fun name (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static synthetic fun name$default (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V @@ -381,28 +405,21 @@ public final class app/revanced/patcher/MatchingKt { public static final fun noneOf ([Lkotlin/jvm/functions/Function4;)Lkotlin/jvm/functions/Function4; public static final fun parameterTypes (Lapp/revanced/patcher/MutablePredicateList;[Ljava/lang/String;)V public static final fun predicate (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V - public static final fun reference (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static synthetic fun reference$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun registers (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static final fun registers ([ILkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static synthetic fun registers$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun registers$default ([ILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; public static final fun rememberDeclarativePredicate (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z public static final fun rememberMatchIndexed (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z + public static final fun rememberMatchUnordered (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z public static final fun returnType (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V public static final fun returnType (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static synthetic fun returnType$default (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V - public static final fun string (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun string (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun string (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun string$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun string$default (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun string$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun type (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun type (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun type$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun type$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun unaryPlus (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/jvm/functions/Function4;)Z + public static final fun strings (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V + public static final fun strings (Lapp/revanced/patcher/MutablePredicateList;[Ljava/lang/String;)V + public static final fun strings (Lapp/revanced/patcher/MutablePredicateList;[Lkotlin/jvm/functions/Function1;)V + public static final fun strings (Lapp/revanced/patcher/UnorderedMatcher;Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V + public static final fun strings (Lapp/revanced/patcher/UnorderedMatcher;Lapp/revanced/patcher/MutablePredicateList;[Lkotlin/jvm/functions/Function1;)V + public static final fun strings (Ljava/util/List;Lapp/revanced/patcher/UnorderedMatcher;Lapp/revanced/patcher/MutablePredicateList;[Ljava/lang/String;)V + public static final fun unaryPlus (Lapp/revanced/patcher/Matcher;Ljava/lang/Object;)Z + public static final fun unorderedMatcher (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/UnorderedMatcher; + public static final fun unorderedMatcher ([Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/UnorderedMatcher; } public final class app/revanced/patcher/MutablePredicateList : java/util/List, kotlin/jvm/internal/markers/KMutableList { @@ -484,6 +501,35 @@ public final class app/revanced/patcher/PredicateContext : java/util/Map, kotlin public final fun values ()Ljava/util/Collection; } +public final class app/revanced/patcher/StringMatchingFunctions { + public static final field INSTANCE Lapp/revanced/patcher/StringMatchingFunctions; + public final fun invoke (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function1; + public final fun invoke (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function1; + public static synthetic fun invoke$default (Lapp/revanced/patcher/StringMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function1; + public static synthetic fun invoke$default (Lapp/revanced/patcher/StringMatchingFunctions;Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function1; + public final fun string (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function1; + public final fun string (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function1; + public final fun string (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; + public static synthetic fun string$default (Lapp/revanced/patcher/StringMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function1; + public static synthetic fun string$default (Lapp/revanced/patcher/StringMatchingFunctions;Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function1; +} + +public final class app/revanced/patcher/UnorderedMatcher : app/revanced/patcher/Matcher { + public fun ()V + public final fun contains (Ljava/lang/Object;)Z + public fun contains (Lkotlin/jvm/functions/Function1;)Z + public final fun getIndices ()Ljava/util/Map; + public final fun indexOf (Ljava/lang/Object;)I + public fun indexOf (Lkotlin/jvm/functions/Function1;)I + public fun invoke (Ljava/lang/Iterable;)Z + public final fun lastIndexOf (Ljava/lang/Object;)I + public fun lastIndexOf (Lkotlin/jvm/functions/Function1;)I + public final fun remove (I)Lkotlin/jvm/functions/Function1; + public final fun remove (Ljava/lang/Object;)Z + public fun remove (Lkotlin/jvm/functions/Function1;)Z + public fun removeAt (I)Lkotlin/jvm/functions/Function1; +} + public final class app/revanced/patcher/extensions/ExternalLabel { public fun (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)V public final fun copy (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lapp/revanced/patcher/extensions/ExternalLabel; diff --git a/patcher/api/jvm/patcher.api b/patcher/api/jvm/patcher.api index ee11471..0ab10b7 100644 --- a/patcher/api/jvm/patcher.api +++ b/patcher/api/jvm/patcher.api @@ -172,6 +172,47 @@ public final class app/revanced/patcher/IndexedMatcher : app/revanced/patcher/Ma public fun removeAt (I)Lkotlin/jvm/functions/Function4; } +public final class app/revanced/patcher/InstructionMatchingFunctions { + public static final field INSTANCE Lapp/revanced/patcher/InstructionMatchingFunctions; + public final fun field (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun field (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun field$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun field$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun instruction (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun instruction$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun invoke (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun invoke (Lcom/android/tools/smali/dexlib2/Opcode;)Lkotlin/jvm/functions/Function4; + public final fun invoke (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun invoke (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public static synthetic fun invoke$default (Lapp/revanced/patcher/InstructionMatchingFunctions;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun invoke$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun invoke$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun literal (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun literal (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun literal$default (Lapp/revanced/patcher/InstructionMatchingFunctions;JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun literal$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun method (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun method (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun method$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun method$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun reference (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public static synthetic fun reference$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun registers (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public final fun registers ([ILkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public static synthetic fun registers$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun registers$default (Lapp/revanced/patcher/InstructionMatchingFunctions;[ILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun string (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun string (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun string (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun string$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun string$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun string$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public final fun type (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; + public final fun type (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; + public static synthetic fun type$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static synthetic fun type$default (Lapp/revanced/patcher/InstructionMatchingFunctions;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; +} + public final class app/revanced/patcher/IterableClassDefClassDefMatching { public static final field INSTANCE Lapp/revanced/patcher/IterableClassDefClassDefMatching; public final fun firstClassDef (Ljava/lang/Iterable;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; @@ -238,7 +279,7 @@ public final class app/revanced/patcher/IterableMethodMethodMatching { } public final class app/revanced/patcher/Match { - public fun (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/util/List;)V + public fun (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/util/List;Ljava/util/Map;)V public final fun getClassDef ()Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public final fun getClassDefOrNull ()Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public final fun getContext ()Lapp/revanced/patcher/patch/BytecodePatchContext; @@ -249,6 +290,7 @@ public final class app/revanced/patcher/Match { public final fun getIndices ()Ljava/util/List; public final fun getMethod ()Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public final fun getMethodOrNull ()Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getStringIndices ()Ljava/util/Map; } public final class app/revanced/patcher/MatchBuilder { @@ -262,6 +304,7 @@ public final class app/revanced/patcher/MatchBuilder { public final fun getIndices ()Ljava/util/List; public final fun getMethod (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; public final fun getMethodOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;)Lcom/android/tools/smali/dexlib2/mutable/MutableMethod; + public final fun getStringIndices ()Ljava/util/Map; public final fun match (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/ClassDef;)Lapp/revanced/patcher/Match; } @@ -339,11 +382,7 @@ public final class app/revanced/patcher/MatchingKt { public static final fun definingClass (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V public static final fun definingClass (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static synthetic fun definingClass$default (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V - public static final fun field (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun field (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun field$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun field$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun firstMethodComposite ([Ljava/lang/String;Lkotlin/jvm/functions/Function5;)Lapp/revanced/patcher/MatchBuilder; + public static final fun firstMethodComposite ([Ljava/lang/String;Lkotlin/jvm/functions/Function6;)Lapp/revanced/patcher/MatchBuilder; public static final fun getClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public static final fun getClassDefOrNull (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lcom/android/tools/smali/dexlib2/mutable/MutableClassDef; public static final fun getImmutableClassDef (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;)Lcom/android/tools/smali/dexlib2/iface/ClassDef; @@ -351,29 +390,14 @@ public final class app/revanced/patcher/MatchingKt { public static final fun implementation (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)Z public static final fun indexedMatcher (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/IndexedMatcher; public static final fun indexedMatcher ([Lkotlin/jvm/functions/Function4;)Lapp/revanced/patcher/IndexedMatcher; - public static final fun instruction (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun instruction$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; public static final fun instructions (Lapp/revanced/patcher/IndexedMatcher;Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static final fun instructions (Lapp/revanced/patcher/IndexedMatcher;Lapp/revanced/patcher/MutablePredicateList;[Lkotlin/jvm/functions/Function4;)V public static final fun instructions (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static final fun instructions (Lapp/revanced/patcher/MutablePredicateList;[Lkotlin/jvm/functions/Function4;)V - public static final fun invoke (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun invoke (Lcom/android/tools/smali/dexlib2/Opcode;)Lkotlin/jvm/functions/Function4; - public static final fun invoke (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static final fun invoke (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static synthetic fun invoke$default (JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun invoke$default (Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun invoke$default (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun literal (JLkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun literal (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun literal$default (JLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun literal$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; public static final fun matchIndexed (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;[Lkotlin/jvm/functions/Function4;)Z public static final fun matchIndexed (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z - public static final fun method (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun method (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun method$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun method$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; + public static final fun matchUnordered (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;[Lkotlin/jvm/functions/Function1;)Z + public static final fun matchUnordered (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z public static final fun name (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V public static final fun name (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static synthetic fun name$default (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V @@ -381,28 +405,21 @@ public final class app/revanced/patcher/MatchingKt { public static final fun noneOf ([Lkotlin/jvm/functions/Function4;)Lkotlin/jvm/functions/Function4; public static final fun parameterTypes (Lapp/revanced/patcher/MutablePredicateList;[Ljava/lang/String;)V public static final fun predicate (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V - public static final fun reference (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static synthetic fun reference$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun registers (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static final fun registers ([ILkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static synthetic fun registers$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun registers$default ([ILkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; public static final fun rememberDeclarativePredicate (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z public static final fun rememberMatchIndexed (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z + public static final fun rememberMatchUnordered (Lapp/revanced/patcher/PredicateContext;Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)Z public static final fun returnType (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V public static final fun returnType (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V public static synthetic fun returnType$default (Lapp/revanced/patcher/MutablePredicateList;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V - public static final fun string (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun string (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun string (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun string$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun string$default (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun string$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun type (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function4; - public static final fun type (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function4; - public static synthetic fun type$default (Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static synthetic fun type$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/jvm/functions/Function4; - public static final fun unaryPlus (Lapp/revanced/patcher/IndexedMatcher;Lkotlin/jvm/functions/Function4;)Z + public static final fun strings (Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V + public static final fun strings (Lapp/revanced/patcher/MutablePredicateList;[Ljava/lang/String;)V + public static final fun strings (Lapp/revanced/patcher/MutablePredicateList;[Lkotlin/jvm/functions/Function1;)V + public static final fun strings (Lapp/revanced/patcher/UnorderedMatcher;Lapp/revanced/patcher/MutablePredicateList;Lkotlin/jvm/functions/Function1;)V + public static final fun strings (Lapp/revanced/patcher/UnorderedMatcher;Lapp/revanced/patcher/MutablePredicateList;[Lkotlin/jvm/functions/Function1;)V + public static final fun strings (Ljava/util/List;Lapp/revanced/patcher/UnorderedMatcher;Lapp/revanced/patcher/MutablePredicateList;[Ljava/lang/String;)V + public static final fun unaryPlus (Lapp/revanced/patcher/Matcher;Ljava/lang/Object;)Z + public static final fun unorderedMatcher (Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/UnorderedMatcher; + public static final fun unorderedMatcher ([Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/UnorderedMatcher; } public final class app/revanced/patcher/MutablePredicateList : java/util/List, kotlin/jvm/internal/markers/KMutableList { @@ -484,6 +501,35 @@ public final class app/revanced/patcher/PredicateContext : java/util/Map, kotlin public final fun values ()Ljava/util/Collection; } +public final class app/revanced/patcher/StringMatchingFunctions { + public static final field INSTANCE Lapp/revanced/patcher/StringMatchingFunctions; + public final fun invoke (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function1; + public final fun invoke (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function1; + public static synthetic fun invoke$default (Lapp/revanced/patcher/StringMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function1; + public static synthetic fun invoke$default (Lapp/revanced/patcher/StringMatchingFunctions;Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function1; + public final fun string (Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function1; + public final fun string (Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)Lkotlin/jvm/functions/Function1; + public final fun string (Lkotlin/jvm/functions/Function1;)Lkotlin/jvm/functions/Function1; + public static synthetic fun string$default (Lapp/revanced/patcher/StringMatchingFunctions;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function1; + public static synthetic fun string$default (Lapp/revanced/patcher/StringMatchingFunctions;Ljava/util/List;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlin/jvm/functions/Function1; +} + +public final class app/revanced/patcher/UnorderedMatcher : app/revanced/patcher/Matcher { + public fun ()V + public final fun contains (Ljava/lang/Object;)Z + public fun contains (Lkotlin/jvm/functions/Function1;)Z + public final fun getIndices ()Ljava/util/Map; + public final fun indexOf (Ljava/lang/Object;)I + public fun indexOf (Lkotlin/jvm/functions/Function1;)I + public fun invoke (Ljava/lang/Iterable;)Z + public final fun lastIndexOf (Ljava/lang/Object;)I + public fun lastIndexOf (Lkotlin/jvm/functions/Function1;)I + public final fun remove (I)Lkotlin/jvm/functions/Function1; + public final fun remove (Ljava/lang/Object;)Z + public fun remove (Lkotlin/jvm/functions/Function1;)Z + public fun removeAt (I)Lkotlin/jvm/functions/Function1; +} + public final class app/revanced/patcher/extensions/ExternalLabel { public fun (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)V public final fun copy (Ljava/lang/String;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;)Lapp/revanced/patcher/extensions/ExternalLabel; diff --git a/patcher/src/commonMain/kotlin/app/revanced/patcher/Matching.kt b/patcher/src/commonMain/kotlin/app/revanced/patcher/Matching.kt index 579810a..f451674 100644 --- a/patcher/src/commonMain/kotlin/app/revanced/patcher/Matching.kt +++ b/patcher/src/commonMain/kotlin/app/revanced/patcher/Matching.kt @@ -91,14 +91,14 @@ typealias DeclarativePredicate = context(PredicateContext) MutablePredicateLi typealias BytecodePatchContextDeclarativePredicate = context(BytecodePatchContext, PredicateContext) MutablePredicateList.() -> Unit fun T.declarativePredicate(build: Function>) = - context(MutablePredicateList().apply(build)) { - all(this) + with(MutablePredicateList().apply(build)) { + all(this@declarativePredicate) } context(context: PredicateContext) fun T.rememberDeclarativePredicate(key: Any, block: Function>) = - context(context.remember(key) { MutablePredicateList().apply(block) }) { - all(this) + with(context.remember(key) { MutablePredicateList().apply(block) }) { + all(this@rememberDeclarativePredicate) } context(_: PredicateContext) @@ -299,25 +299,21 @@ object ClassDefMethodMatching { ) = requireNotNull(firstMutableMethodOrNull(strings = strings, predicate)) fun ClassDef.firstMethodDeclarativelyOrNull( - vararg strings: String, - predicate: DeclarativePredicate + vararg strings: String, predicate: DeclarativePredicate ) = methods.firstMethodDeclarativelyOrNull(strings = strings, predicate) fun ClassDef.firstMethodDeclaratively( - vararg strings: String, - predicate: DeclarativePredicate + vararg strings: String, predicate: DeclarativePredicate ) = requireNotNull(firstMethodDeclarativelyOrNull(strings = strings, predicate)) context(_: BytecodePatchContext) fun ClassDef.firstMutableMethodDeclarativelyOrNull( - vararg strings: String, - predicate: DeclarativePredicate + vararg strings: String, predicate: DeclarativePredicate ) = methods.firstMutableMethodDeclarativelyOrNull(strings = strings, predicate) context(_: BytecodePatchContext) fun ClassDef.firstMutableMethodDeclaratively( - vararg strings: String, - predicate: DeclarativePredicate + vararg strings: String, predicate: DeclarativePredicate ) = requireNotNull(firstMutableMethodDeclarativelyOrNull(strings = strings, predicate)) } @@ -397,6 +393,9 @@ object BytecodePatchContextMethodMatching { ): Method? = withPredicateContext { if (strings.isEmpty()) return context.classDefs.firstMethodOrNull(predicate) + // TODO: Get rid of duplicates, but this isn't needed for functionality. Perhaps worse performance-wise? + val strings = strings.toSet() + val methodsWithStrings = strings.mapNotNull { context.classDefs.methodsByString[it] } if (methodsWithStrings.size != strings.size) return null @@ -578,9 +577,56 @@ class PredicateContext internal constructor() : MutableMap by mutable private inline fun withPredicateContext(block: PredicateContext.() -> T) = PredicateContext().block() -// region Matcher +typealias UnorderedMatcherPredicate = T.() -> U? -// region IndexedMatcher +fun unorderedMatcher(vararg predicates: UnorderedMatcherPredicate) = + UnorderedMatcher().apply { predicates.forEach { +it } } + +fun unorderedMatcher(build: Function>) = UnorderedMatcher().apply(build) + +fun Iterable.matchUnordered(build: Function>) = + unorderedMatcher(build)(this) + +context(_: PredicateContext) +fun Iterable.matchUnordered( + key: Any, vararg predicates: T.() -> U? +) = UnorderedMatcher()(key, this) { predicates.forEach { +it } } + +context(_: PredicateContext) +fun Iterable.rememberMatchUnordered(key: Any, build: Function>) = + unorderedMatcher(predicates = emptyArray())(key, this, build) + +class UnorderedMatcher : Matcher>() { + val indices: Map + field = mutableMapOf() + + override fun invoke(haystack: Iterable): Boolean { + indices.clear() + + val totalNeeded = size + if (totalNeeded == 0) return true + + val matchedPredicates = BooleanArray(totalNeeded) + var matchCount = 0 + + haystack.forEachIndexed { index, element -> + for (i in 0 until totalNeeded) { + if (matchedPredicates[i]) continue + + val result = this[i](element) ?: continue + + indices += result to index + matchedPredicates[i] = true + + if (++matchCount == totalNeeded) return true else break + } + } + + return false + } +} + +typealias IndexedMatcherPredicate = T.(lastMatchedIndex: Int, currentIndex: Int, setNextIndex: (Int?) -> Unit) -> Boolean fun indexedMatcher(vararg items: IndexedMatcherPredicate) = IndexedMatcher().apply { items.forEach { +it } @@ -608,7 +654,11 @@ fun at( fun at(index: Int = 0, predicate: Predicate) = at(index) { _, _, _ -> predicate() } fun at(predicate: IndexedMatcherPredicate): IndexedMatcherPredicate = - at(0) { lastMatchedIndex, currentIndex, setNextIndex -> predicate(lastMatchedIndex, currentIndex, setNextIndex) } + at(0) { lastMatchedIndex, currentIndex, setNextIndex -> + predicate( + lastMatchedIndex, currentIndex, setNextIndex + ) + } fun at(predicate: Predicate) = at { _, _, _ -> predicate() } @@ -630,13 +680,13 @@ fun after( fun after(range: IntRange = 1..1, predicate: Predicate) = after(range) { _, _, _ -> predicate() } -fun after(predicate: IndexedMatcherPredicate) = after(1..1) { lastMatchedIndex, currentIndex, setNextIndex -> - predicate(lastMatchedIndex, currentIndex, setNextIndex) -} +fun after(predicate: IndexedMatcherPredicate) = + after(1..1) { lastMatchedIndex, currentIndex, setNextIndex -> + predicate(lastMatchedIndex, currentIndex, setNextIndex) + } fun after(predicate: Predicate) = after { _, _, _ -> predicate() } - fun anyOf( vararg predicates: IndexedMatcherPredicate ): IndexedMatcherPredicate = { currentIndex, lastMatchedIndex, setNextIndex -> @@ -655,11 +705,6 @@ fun noneOf( predicates.none { predicate -> predicate(currentIndex, lastMatchedIndex, setNextIndex) } } -context(matcher: IndexedMatcher) -operator fun IndexedMatcherPredicate.unaryPlus() = matcher.add(this) - -typealias IndexedMatcherPredicate = T.(lastMatchedIndex: Int, currentIndex: Int, setNextIndex: (Int?) -> Unit) -> Boolean - class IndexedMatcher : Matcher>() { val indices: List field = mutableListOf() @@ -738,7 +783,10 @@ class IndexedMatcher : Matcher>() { } } -// endregion +// region Matcher + +context(matcher: M) +operator fun > U.unaryPlus() = matcher.add(this) context(context: PredicateContext) inline operator fun > M.invoke( @@ -754,34 +802,31 @@ abstract class Matcher : MutableList by mutableListOf() { // endregion Matcher -context(list: MutablePredicateList) -fun allOf(block: Function>) { +// region MutablePredicateList extensions + + +fun MutablePredicateList.allOf(block: Function>) { val child = MutablePredicateList().apply(block) - list.add { child.all { it() } } + add { child.all { it() } } } -context(list: MutablePredicateList) -fun anyOf(block: Function>) { +fun MutablePredicateList.anyOf(block: Function>) { val child = MutablePredicateList().apply(block) - list.add { child.any { it() } } + add { child.any { it() } } } -context(list: MutablePredicateList) -fun noneOf(block: Function>) { +fun MutablePredicateList.noneOf(block: Function>) { val child = MutablePredicateList().apply(block) - list.add { child.none { it() } } + add { child.none { it() } } } -context(list: MutablePredicateList) -fun predicate(block: Predicate) { - list.add(block) +fun MutablePredicateList.predicate(block: Predicate) { + add(block) } -context(list: MutablePredicateList) -fun all(target: T): Boolean = list.all { target.it() } +fun MutablePredicateList.all(target: T): Boolean = all { target.it() } -context(list: MutablePredicateList) -fun any(target: T): Boolean = list.any { target.it() } +fun MutablePredicateList.any(target: T): Boolean = any { target.it() } fun MutablePredicateList.accessFlags(vararg flags: AccessFlags) = predicate { accessFlags(flags = flags) } @@ -814,10 +859,56 @@ fun MutablePredicateList.parameterTypes(vararg parameterTypePrefixes: St .all { (a, b) -> a.startsWith(b) } } -fun MutablePredicateList.instructions( - build: IndexedMatcher.() -> Unit +fun MutablePredicateList.strings( + build: Function> ) { - val match = indexedMatcher() + val match = unorderedMatcher(build) + + predicate { implementation { match(instructions) } } +} + +context(matcher: UnorderedMatcher) +fun MutablePredicateList.strings( + build: Function> +) { + matcher.build() + + predicate { implementation { matcher(instructions) } } +} + +fun MutablePredicateList.strings( + vararg predicates: UnorderedMatcherPredicate +) = strings { predicates.forEach { +it } } + +context(matcher: UnorderedMatcher) +fun MutablePredicateList.strings( + vararg predicates: UnorderedMatcherPredicate +) = strings { predicates.forEach { +it } } + +private fun Array.toUnorderedMatcherPredicate() = map { string -> + fun Instruction.(): String? { return string.takeIf { this.string == it } } +}.toTypedArray() + +fun MutablePredicateList.strings( + vararg strings: String +) = strings(predicates = strings.toUnorderedMatcherPredicate()) + +context( + stringsList: MutableList, + matcher: UnorderedMatcher) +fun MutablePredicateList.strings( + vararg strings: String +) { + stringsList += strings + + strings(predicates = strings.toUnorderedMatcherPredicate()) +} + +fun MutablePredicateList.instructions( + build: Function> +) { + val match = indexedMatcher(build) + predicate { implementation { match(instructions) } } } @@ -829,9 +920,10 @@ fun MutablePredicateList.instructions( context(matcher: IndexedMatcher) fun MutablePredicateList.instructions( - build: IndexedMatcher.() -> Unit + build: Function> ) { matcher.build() + predicate { implementation { matcher(instructions) } } } @@ -844,98 +936,127 @@ fun MutablePredicateList.custom(block: Predicate) { predicate { block() } } -inline fun `is`( - crossinline predicate: Predicate = { true } -): IndexedMatcherPredicate = { _, _, _ -> (this as? T)?.predicate() == true } +object InstructionMatchingFunctions { + inline fun `is`( + crossinline predicate: Predicate = { true } + ): IndexedMatcherPredicate = { _, _, _ -> (this as? T)?.predicate() == true } -fun instruction(predicate: Predicate = { true }): IndexedMatcherPredicate = - { _, _, _ -> predicate() } + fun instruction(predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> predicate() } -fun registers(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> - when (this) { - is RegisterRangeInstruction -> IntArray(registerCount) { startRegister + it }.predicate() + fun registers(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> + when (this) { + is RegisterRangeInstruction -> IntArray(registerCount) { startRegister + it }.predicate() - is FiveRegisterInstruction -> intArrayOf(registerC, registerD, registerE, registerF, registerG).predicate() + is FiveRegisterInstruction -> intArrayOf(registerC, registerD, registerE, registerF, registerG).predicate() - is ThreeRegisterInstruction -> intArrayOf(registerA, registerB, registerC).predicate() + is ThreeRegisterInstruction -> intArrayOf(registerA, registerB, registerC).predicate() - is TwoRegisterInstruction -> intArrayOf(registerA, registerB).predicate() + is TwoRegisterInstruction -> intArrayOf(registerA, registerB).predicate() - is OneRegisterInstruction -> intArrayOf(registerA).predicate() + is OneRegisterInstruction -> intArrayOf(registerA).predicate() - else -> false + else -> false + } } -} -fun registers( - vararg registers: Int, compare: IntArray.(registers: IntArray) -> Boolean = { registers -> - this.size >= registers.size && registers.indices.all { this[it] == registers[it] } + fun registers( + vararg registers: Int, compare: IntArray.(registers: IntArray) -> Boolean = { registers -> + this.size >= registers.size && registers.indices.all { this[it] == registers[it] } + } + ) = registers({ compare(registers) }) + + fun literal(predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> wideLiteral?.predicate() == true } + + fun literal(literal: Long, compare: Long.(Long) -> Boolean = Long::equals) = literal { compare(literal) } + + operator fun Long.invoke(compare: Long.(Long) -> Boolean = Long::equals) = literal(this, compare) + + inline fun reference( + crossinline predicate: Predicate = { true } + ): IndexedMatcherPredicate = { _, _, _ -> + (reference as? T)?.predicate() == true } -) = registers({ compare(registers) }) -fun literal(predicate: Predicate = { true }): IndexedMatcherPredicate = - { _, _, _ -> wideLiteral?.predicate() == true } + fun reference( + reference: String, compare: String.(String) -> Boolean = String::equals + ): IndexedMatcherPredicate = { _, _, _ -> this.reference?.toString()?.compare(reference) == true } -fun literal(literal: Long, compare: Long.(Long) -> Boolean = Long::equals) = literal { compare(literal) } + fun field(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> + fieldReference?.predicate() == true + } -operator fun Long.invoke(compare: Long.(Long) -> Boolean = Long::equals) = literal(this, compare) + fun field(name: String, compare: String.(String) -> Boolean = String::equals) = field { this.name.compare(name) } -inline fun reference( - crossinline predicate: Predicate = { true } -): IndexedMatcherPredicate = { _, _, _ -> - (reference as? T)?.predicate() == true + fun type(predicate: Predicate = { true }): IndexedMatcherPredicate = + { _, _, _ -> type?.predicate() == true } + + fun type(type: String, compare: String.(type: String) -> Boolean = String::equals) = type { compare(type) } + + fun method(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> + methodReference?.predicate() == true + } + + fun method(name: String, compare: String.(String) -> Boolean = String::equals) = method { this.name.compare(name) } + + fun string(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> + string?.predicate() == true + } + + context(stringsList: MutableList) + fun string( + string: String, + compare: String.(String) -> Boolean = String::equals + ): IndexedMatcherPredicate { + if (compare == String::equals) stringsList += string + + return string { compare(string) } + } + + fun string(string: String, compare: String.(String) -> Boolean = String::equals) = string { compare(string) } + + operator fun String.invoke(compare: String.(String) -> Boolean = String::equals) = string(this, compare) + + context(stringsList: MutableList) + operator fun String.invoke(compare: String.(String) -> Boolean = String::equals) = string(this, compare) + + operator fun Opcode.invoke(): IndexedMatcherPredicate = { _, _, _ -> opcode == this@invoke } } -fun reference( - reference: String, compare: String.(String) -> Boolean = String::equals -): IndexedMatcherPredicate = { _, _, _ -> this.reference?.toString()?.compare(reference) == true } +object StringMatchingFunctions { + operator fun String.invoke( + compare: String.(String) -> Boolean = String::equals + ): UnorderedMatcherPredicate = { + this@invoke.takeIf { string?.compare(it) == true } + } -fun field(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> - fieldReference?.predicate() == true + context(stringsList: MutableList) + operator fun String.invoke( + compare: String.(String) -> Boolean = String::equals + ): UnorderedMatcherPredicate { + if (compare == String::equals) stringsList += this + + return { this@invoke.takeIf { string?.compare(it) == true } } + } + + fun string(predicate: UnorderedMatcherPredicate) = predicate + + context(stringsList: MutableList) + fun string(string: String, compare: String.(String) -> Boolean = String::equals) = string(compare) + + fun string(string: String, compare: String.(String) -> Boolean = String::equals) = string(compare) } -fun field(name: String, compare: String.(String) -> Boolean = String::equals) = field { this.name.compare(name) } - -fun type(predicate: Predicate = { true }): IndexedMatcherPredicate = - { _, _, _ -> type?.predicate() == true } - -fun type(type: String, compare: String.(type: String) -> Boolean = String::equals) = type { compare(type) } - -fun method(predicate: Predicate = { true }): IndexedMatcherPredicate = { _, _, _ -> - methodReference?.predicate() == true -} - -fun method(name: String, compare: String.(String) -> Boolean = String::equals) = method { this.name.compare(name) } - -fun string(compare: Predicate = { true }): IndexedMatcherPredicate = predicate@{ _, _, _ -> - this@predicate.string?.compare() == true -} - -context(stringsList: MutableList) -fun string( - string: String, compare: String.(String) -> Boolean = String::equals -): IndexedMatcherPredicate { - if (compare == String::equals) stringsList += string - - return string { compare(string) } -} - -fun string(string: String, compare: String.(String) -> Boolean = String::equals) = string { compare(string) } - -operator fun String.invoke(compare: Predicate = { true }): IndexedMatcherPredicate = - { _, _, _ -> string?.compare() == true } - -context(stringsList: MutableList) -operator fun String.invoke(compare: String.(String) -> Boolean = String::equals): IndexedMatcherPredicate { - if (compare == String::equals) stringsList += this - - return invoke(compare) -} - -operator fun Opcode.invoke(): IndexedMatcherPredicate = { _, _, _ -> opcode == this@invoke } - -typealias BuildCompositeDeclarativePredicate = context(BytecodePatchContext, PredicateContext, IndexedMatcher, MutableList) -MutablePredicateList.() -> Unit +typealias BuildCompositeDeclarativePredicate = + context( + BytecodePatchContext, + PredicateContext, + IndexedMatcher, + UnorderedMatcher, + MutableList + ) + MutablePredicateList.() -> Unit fun firstMethodComposite( vararg strings: String, build: BuildCompositeDeclarativePredicate @@ -943,19 +1064,21 @@ fun firstMethodComposite( class MatchBuilder private constructor( private val strings: MutableList, - indexedMatcher: IndexedMatcher, + indexedMatcher: IndexedMatcher = indexedMatcher(), + stringMatcher: UnorderedMatcher = unorderedMatcher(), build: BuildCompositeDeclarativePredicate, ) { internal constructor( vararg strings: String, build: BuildCompositeDeclarativePredicate - ) : this(strings = mutableListOf(elements = strings), indexedMatcher(), build) + ) : this(strings = mutableListOf(elements = strings), build = build) private val predicate: BytecodePatchContextDeclarativePredicate = { - context(strings, indexedMatcher) { build() } + context(strings, indexedMatcher, stringMatcher) { build() } } val indices = indexedMatcher.indices + val stringIndices = stringMatcher.indices private val BytecodePatchContext.cachedImmutableMethodOrNull by gettingFirstMethodDeclarativelyOrNull( strings = strings.toTypedArray(), predicate @@ -1001,12 +1124,18 @@ class MatchBuilder private constructor( context(context: BytecodePatchContext) fun match(classDef: ClassDef) = Match( - context, classDef.firstMethodDeclarativelyOrNull { predicate() }, indices.toList() + context, + classDef.firstMethodDeclarativelyOrNull { predicate() }, + indices, + stringIndices ) } class Match( - val context: BytecodePatchContext, val immutableMethodOrNull: Method?, val indices: List + val context: BytecodePatchContext, + val immutableMethodOrNull: Method?, + val indices: List, + val stringIndices: Map, ) { val immutableMethod by lazy { requireNotNull(immutableMethodOrNull) } diff --git a/patcher/src/jvmTest/kotlin/app/revanced/patcher/MatchingTest.kt b/patcher/src/jvmTest/kotlin/app/revanced/patcher/MatchingTest.kt index f2b9131..d872898 100644 --- a/patcher/src/jvmTest/kotlin/app/revanced/patcher/MatchingTest.kt +++ b/patcher/src/jvmTest/kotlin/app/revanced/patcher/MatchingTest.kt @@ -2,18 +2,23 @@ package app.revanced.patcher import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMethod import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMethodDeclarativelyOrNull +import app.revanced.patcher.InstructionMatchingFunctions.invoke +import app.revanced.patcher.InstructionMatchingFunctions.`is` +import app.revanced.patcher.InstructionMatchingFunctions.registers +import app.revanced.patcher.InstructionMatchingFunctions.string +import app.revanced.patcher.InstructionMatchingFunctions.type import app.revanced.patcher.patch.bytecodePatch import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22t -import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.assertDoesNotThrow import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse -import kotlin.test.assertNotNull +import kotlin.test.assertTrue @TestInstance(TestInstance.Lifecycle.PER_CLASS) class MatchingTest : PatcherTestBase() { @@ -28,6 +33,9 @@ class MatchingTest : PatcherTestBase() { if (fail) returnType("doesnt exist") + strings("This is a test.") + strings(StringMatchingFunctions.string("Hello", String::startsWith)) + instructions( at(Opcode.CONST_STRING()), `is`(), @@ -40,11 +48,29 @@ class MatchingTest : PatcherTestBase() { } with(bytecodePatchContext) { - assertNotNull(firstMethodComposite().methodOrNull) { "Expected to find a method" } - Assertions.assertNull(firstMethodComposite(fail = true).immutableMethodOrNull) { "Expected to not find a method" } - Assertions.assertNotNull( - firstMethodComposite().match(classDefs.first()).methodOrNull - ) { "Expected to find a method matching in a specific class" } + val match = firstMethodComposite() + assertNotNull( + match.methodOrNull, + "Expected to find a method" + ) + assertEquals( + 4, match.indices[3], + "Expected to find the string instruction at index 5" + ) + assertEquals( + 0, match.stringIndices["Hello"], + "Expected to find 'Hello' at index 0" + ) + + assertNull( + firstMethodComposite(fail = true).immutableMethodOrNull, + "Expected to not find a method" + ) + + assertNotNull( + firstMethodComposite().match(classDefs.first()).methodOrNull, + "Expected to find a method matching in a specific class" + ) } } @@ -77,7 +103,46 @@ class MatchingTest : PatcherTestBase() { } @Test - fun `matcher finds indices correctly`() { + fun `unordered matcher works correctly`() { + val strings = listOf("apple", "banana", "cherry", "date", "elderberry") + val matcher = unorderedMatcher() + + matcher.apply { + add { "an".takeIf { contains(it) } } + add { "apple".takeIf { equals(it) } } + add { "elder".takeIf { startsWith(it) } } + } + assertTrue( + matcher(strings), + "Should match correctly" + ) + assertEquals( + matcher.indices["an"], 1, + "Should find 'banana' at index 1" + ) + assertEquals( + matcher.indices["apple"], 0, + "Should find 'apple' at index 0" + ) + assertEquals( + matcher.indices["elder"], 4, + "Should find 'elderberry' at index 4" + ) + matcher.clear() + + matcher.apply { + add { "xyz".takeIf { contains(it) } } + add { "apple".takeIf { equals(it) } } + add { "elder".takeIf { startsWith(it) } } + } + assertFalse( + matcher(strings), + "Should not match" + ) + } + + @Test + fun `indexed matcher finds indices correctly`() { val iterable = (1..10).toList() val matcher = indexedMatcher()