Skip to content

Commit a160101

Browse files
Allow using a fingerprint result inside another fingerprint
1 parent d02aad0 commit a160101

File tree

3 files changed

+54
-51
lines changed

3 files changed

+54
-51
lines changed

api/revanced-patcher.api

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ public final class app/revanced/patcher/FieldFilter : app/revanced/patcher/Opcod
88
public fun <init> ()V
99
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;I)V
1010
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
11-
public fun <init> (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Ljava/util/List;I)V
12-
public synthetic fun <init> (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Ljava/util/List;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
13-
public final fun getDefiningClass ()Lkotlin/jvm/functions/Function0;
14-
public final fun getName ()Lkotlin/jvm/functions/Function0;
15-
public final fun getType ()Lkotlin/jvm/functions/Function0;
11+
public fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ljava/util/List;I)V
12+
public synthetic fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ljava/util/List;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
13+
public final fun getDefiningClass ()Lkotlin/jvm/functions/Function1;
14+
public final fun getName ()Lkotlin/jvm/functions/Function1;
15+
public final fun getType ()Lkotlin/jvm/functions/Function1;
1616
public fun matches (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Z
1717
}
1818

@@ -131,12 +131,12 @@ public final class app/revanced/patcher/MethodFilter : app/revanced/patcher/Opco
131131
public fun <init> ()V
132132
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/util/List;I)V
133133
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Ljava/lang/String;Ljava/util/List;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
134-
public fun <init> (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Ljava/util/List;I)V
135-
public synthetic fun <init> (Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;Ljava/util/List;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
136-
public final fun getDefiningClass ()Lkotlin/jvm/functions/Function0;
137-
public final fun getMethodName ()Lkotlin/jvm/functions/Function0;
138-
public final fun getParameters ()Lkotlin/jvm/functions/Function0;
139-
public final fun getReturnType ()Lkotlin/jvm/functions/Function0;
134+
public fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ljava/util/List;I)V
135+
public synthetic fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ljava/util/List;IILkotlin/jvm/internal/DefaultConstructorMarker;)V
136+
public final fun getDefiningClass ()Lkotlin/jvm/functions/Function1;
137+
public final fun getMethodName ()Lkotlin/jvm/functions/Function1;
138+
public final fun getParameters ()Lkotlin/jvm/functions/Function1;
139+
public final fun getReturnType ()Lkotlin/jvm/functions/Function1;
140140
public fun matches (Lapp/revanced/patcher/patch/BytecodePatchContext;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Z
141141
}
142142

src/main/kotlin/app/revanced/patcher/Fingerprint.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ internal fun parametersStartsWith(
5151
* @param custom A custom condition for this fingerprint.
5252
*/
5353
class Fingerprint internal constructor(
54-
internal val name: String?,
54+
internal val name: String,
5555
internal val accessFlags: Int?,
5656
internal val returnType: String?,
5757
internal val parameters: List<String>?,
@@ -61,7 +61,7 @@ class Fingerprint internal constructor(
6161
) {
6262
@Suppress("ktlint:standard:backing-property-naming")
6363
// Backing field needed for lazy initialization.
64-
internal var _matchOrNull: Match? = null
64+
private var _matchOrNull: Match? = null
6565

6666
/**
6767
* The match for this [Fingerprint]. Null if unmatched.
@@ -221,7 +221,7 @@ class Fingerprint internal constructor(
221221

222222
while (subIndex <= maxIndex) {
223223
val instruction = instructions[subIndex]
224-
if (filter.matches(method, instruction, subIndex)) {
224+
if (filter.matches(this@BytecodePatchContext, method, instruction, subIndex)) {
225225
if (filterIndex == 0) {
226226
firstFilterIndex = subIndex
227227
}
@@ -271,7 +271,7 @@ class Fingerprint internal constructor(
271271

272272
private val exception get() = PatchException("Failed to match the fingerprint: $this")
273273

274-
override fun toString() = javaClass.name + "." + name
274+
override fun toString() = name
275275

276276
/**
277277
* The match for this [Fingerprint].

src/main/kotlin/app/revanced/patcher/InstructionFilter.kt

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ abstract class InstructionFilter(
2323
val maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS
2424
) {
2525

26-
context(BytecodePatchContext)
2726
abstract fun matches(
27+
context: BytecodePatchContext,
2828
method: Method,
2929
instruction: Instruction,
3030
methodIndex: Int
@@ -46,13 +46,13 @@ class AnyFilter(
4646
maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS,
4747
) : InstructionFilter(maxInstructionsBefore) {
4848

49-
context(BytecodePatchContext)
5049
override fun matches(
50+
context: BytecodePatchContext,
5151
method: Method,
5252
instruction: Instruction,
5353
methodIndex: Int
5454
): Boolean {
55-
return filters.any { matches(method, instruction, methodIndex) }
55+
return filters.any { matches(context, method, instruction, methodIndex) }
5656
}
5757
}
5858

@@ -64,8 +64,8 @@ class OpcodeFilter(
6464
maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS,
6565
) : InstructionFilter(maxInstructionsBefore) {
6666

67-
context(BytecodePatchContext)
6867
override fun matches(
68+
context: BytecodePatchContext,
6969
method: Method,
7070
instruction: Instruction,
7171
methodIndex: Int
@@ -114,8 +114,8 @@ open class OpcodesFilter(
114114
maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS
115115
) : this(if (opcodes == null) null else EnumSet.copyOf(opcodes), maxInstructionsBefore)
116116

117-
context(BytecodePatchContext)
118117
override fun matches(
118+
context: BytecodePatchContext,
119119
method: Method,
120120
instruction: Instruction,
121121
methodIndex: Int
@@ -151,13 +151,13 @@ class LiteralFilter(
151151
maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS,
152152
) : this({ literal.toRawBits() }, opcodes, maxInstructionsBefore)
153153

154-
context(BytecodePatchContext)
155154
override fun matches(
155+
context: BytecodePatchContext,
156156
method: Method,
157157
instruction: Instruction,
158158
methodIndex: Int
159159
): Boolean {
160-
if (!super.matches(method, instruction, methodIndex)) {
160+
if (!super.matches(context, method, instruction, methodIndex)) {
161161
return false
162162
}
163163

@@ -172,20 +172,20 @@ class MethodFilter(
172172
* For calls to a method in the same class, use 'this' as the defining class.
173173
* Note: 'this' does not work for methods declared only in a superclass.
174174
*/
175-
val definingClass: (() -> String)? = null,
175+
val definingClass: ((BytecodePatchContext) -> String)? = null,
176176
/**
177177
* Method name. Must be exact match of the method name.
178178
*/
179-
val methodName: (() -> String)? = null,
179+
val methodName: ((BytecodePatchContext) -> String)? = null,
180180
/**
181181
* Parameters of the method call. Each parameter matches
182182
* using startsWith() and semantics are the same as [Fingerprint].
183183
*/
184-
val parameters: (() -> List<String>)? = null,
184+
val parameters: ((BytecodePatchContext) -> List<String>)? = null,
185185
/**
186186
* Return type. Matches using startsWith()
187187
*/
188-
val returnType: (() -> String)? = null,
188+
val returnType: ((BytecodePatchContext) -> String)? = null,
189189
/**
190190
* Opcode types to match. By default this matches any method call opcode:
191191
* <code>Opcode.INVOKE_*</code>.
@@ -227,25 +227,25 @@ class MethodFilter(
227227
maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS,
228228
) : this(
229229
if (definingClass != null) {
230-
{ definingClass } as (() -> String)
230+
{ context: BytecodePatchContext -> definingClass } as ((BytecodePatchContext) -> String)
231231
} else null, if (methodName != null) {
232-
({ methodName })
232+
{ methodName }
233233
} else null, if (parameters != null) {
234-
({ parameters })
234+
{ parameters }
235235
} else null, if (returnType != null) {
236-
({ returnType })
236+
{ returnType }
237237
} else null,
238238
opcodes,
239239
maxInstructionsBefore
240240
)
241241

242-
context(BytecodePatchContext)
243242
override fun matches(
243+
context: BytecodePatchContext,
244244
method: Method,
245245
instruction: Instruction,
246246
methodIndex: Int
247247
): Boolean {
248-
if (!super.matches(method, instruction, methodIndex)) {
248+
if (!super.matches(context, method, instruction, methodIndex)) {
249249
return false
250250
}
251251

@@ -254,7 +254,7 @@ class MethodFilter(
254254

255255
if (definingClass != null) {
256256
val referenceClass = reference.definingClass
257-
val definingClass = definingClass()
257+
val definingClass = definingClass(context)
258258
if (!referenceClass.endsWith(definingClass)) {
259259
// Check if 'this' defining class is used.
260260
// Would be nice if this also checked all super classes,
@@ -265,13 +265,13 @@ class MethodFilter(
265265
} // else, the method call is for 'this' class.
266266
}
267267
}
268-
if (methodName != null && reference.name != methodName()) {
268+
if (methodName != null && reference.name != methodName(context)) {
269269
return false
270270
}
271-
if (returnType != null && !reference.returnType.startsWith(returnType())) {
271+
if (returnType != null && !reference.returnType.startsWith(returnType(context))) {
272272
return false
273273
}
274-
if (parameters != null && !parametersStartsWith(reference.parameterTypes, parameters())) {
274+
if (parameters != null && !parametersStartsWith(reference.parameterTypes, parameters(context))) {
275275
return false
276276
}
277277

@@ -286,15 +286,16 @@ class FieldFilter(
286286
* For calls to a method in the same class, use 'this' as the defining class.
287287
* Note: 'this' does not work for fields found in superclasses.
288288
*/
289-
val definingClass: (() -> String)? = null,
289+
290+
val definingClass: ((BytecodePatchContext) -> String)? = null,
290291
/**
291292
* Name of the field. Must be a full match of the field name.
292293
*/
293-
val name: (() -> String)? = null,
294+
val name: ((BytecodePatchContext) -> String)? = null,
294295
/**
295296
* Class type of field. Partial matches using startsWith() is allowed.
296297
*/
297-
val type: (() -> String)? = null,
298+
val type: ((BytecodePatchContext) -> String)? = null,
298299
opcodes: List<Opcode>? = null,
299300
maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS,
300301
) : OpcodesFilter(opcodes, maxInstructionsBefore) {
@@ -320,23 +321,25 @@ class FieldFilter(
320321
maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS,
321322
) : this(
322323
if (definingClass != null) {
323-
{ definingClass } as (() -> String)
324-
} else null, if (name != null) {
325-
({ name })
326-
} else null, if (type != null) {
327-
({ type })
324+
{ context: BytecodePatchContext -> definingClass } as ((BytecodePatchContext) -> String)
325+
} else null,
326+
if (name != null) {
327+
{ name }
328+
} else null,
329+
if (type != null) {
330+
{ type }
328331
} else null,
329332
opcodes,
330333
maxInstructionsBefore
331334
)
332335

333-
context(BytecodePatchContext)
334336
override fun matches(
337+
context: BytecodePatchContext,
335338
method: Method,
336339
instruction: Instruction,
337340
methodIndex: Int
338341
): Boolean {
339-
if (!super.matches(method, instruction, methodIndex)) {
342+
if (!super.matches(context, method, instruction, methodIndex)) {
340343
return false
341344
}
342345

@@ -345,18 +348,18 @@ class FieldFilter(
345348

346349
if (definingClass != null) {
347350
val referenceClass = reference.definingClass
348-
val definingClass = definingClass()
351+
val definingClass = definingClass(context)
349352

350353
if (!referenceClass.endsWith(definingClass)) {
351354
if (definingClass != "this" || referenceClass != method.definingClass) {
352355
return false
353356
} // else, the method call is for 'this' class.
354357
}
355358
}
356-
if (name != null && reference.name != name()) {
359+
if (name != null && reference.name != name(context)) {
357360
return false
358361
}
359-
if (type != null && !reference.type.startsWith(type())) {
362+
if (type != null && !reference.type.startsWith(type(context))) {
360363
return false
361364
}
362365

@@ -372,14 +375,14 @@ class LastInstructionFilter(
372375
maxInstructionsBefore: Int = METHOD_MAX_INSTRUCTIONS,
373376
) : InstructionFilter(maxInstructionsBefore) {
374377

375-
context(BytecodePatchContext)
376378
override fun matches(
379+
context: BytecodePatchContext,
377380
method: Method,
378381
instruction: Instruction,
379382
methodIndex: Int
380383
): Boolean {
381384
return methodIndex == method.instructions.count() - 1 && filter.matches(
382-
method, instruction, methodIndex
385+
context, method, instruction, methodIndex
383386
)
384387
}
385388
}

0 commit comments

Comments
 (0)