diff --git a/src/main/kotlin/app/revanced/patcher/fingerprint/method/impl/MethodFingerprint.kt b/src/main/kotlin/app/revanced/patcher/fingerprint/method/impl/MethodFingerprint.kt index f11d8d1..a470a33 100644 --- a/src/main/kotlin/app/revanced/patcher/fingerprint/method/impl/MethodFingerprint.kt +++ b/src/main/kotlin/app/revanced/patcher/fingerprint/method/impl/MethodFingerprint.kt @@ -37,15 +37,65 @@ abstract class MethodFingerprint( * Represents the result of a [MethodFingerprintUtils]. * @param method The matching method. * @param classDef The [ClassDef] that contains the matching [method]. - * @param patternScanResult Opcodes pattern scan result. + * @param scanResult The result of scanning for the [MethodFingerprint]. * @param data The [BytecodeData] this [MethodFingerprintResult] is attached to, to create proxies. */ data class MethodFingerprintResult( val method: Method, val classDef: ClassDef, - val patternScanResult: PatternScanResult?, + val scanResult: MethodFingerprintScanResult, internal val data: BytecodeData ) { + + /** + * 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){ + /** + * 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? = 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, + ) + } + } + /** * Returns a mutable clone of [classDef] * @@ -65,30 +115,4 @@ data class MethodFingerprintResult( it.softCompareTo(this.method) } } -} - -/** - * 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? = 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, - ) } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patcher/fingerprint/method/utils/MethodFingerprintUtils.kt b/src/main/kotlin/app/revanced/patcher/fingerprint/method/utils/MethodFingerprintUtils.kt index 5e1aaa5..333f257 100644 --- a/src/main/kotlin/app/revanced/patcher/fingerprint/method/utils/MethodFingerprintUtils.kt +++ b/src/main/kotlin/app/revanced/patcher/fingerprint/method/utils/MethodFingerprintUtils.kt @@ -7,14 +7,12 @@ import app.revanced.patcher.extensions.parametersEqual import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult -import app.revanced.patcher.fingerprint.method.impl.PatternScanResult import org.jf.dexlib2.Opcode import org.jf.dexlib2.iface.ClassDef import org.jf.dexlib2.iface.Method import org.jf.dexlib2.iface.instruction.Instruction import org.jf.dexlib2.iface.instruction.ReferenceInstruction import org.jf.dexlib2.iface.reference.StringReference - /** * Utility class for [MethodFingerprint] */ @@ -73,21 +71,32 @@ object MethodFingerprintUtils { if (methodFingerprint.customFingerprint != null && !methodFingerprint.customFingerprint!!(context)) return false - if (methodFingerprint.strings != null) { - val implementation = context.implementation ?: return false + val stringsScanResult: StringsScanResult? = + if (methodFingerprint.strings != null) { + StringsScanResult(buildList { + val implementation = context.implementation ?: return false - val stringsList = methodFingerprint.strings.toMutableList() + val stringsList = methodFingerprint.strings.toMutableList() - implementation.instructions.forEach { instruction -> - if (instruction.opcode.ordinal != Opcode.CONST_STRING.ordinal) return@forEach + implementation.instructions.forEach { instruction -> + if (instruction.opcode.ordinal != Opcode.CONST_STRING.ordinal) return@forEach - val string = ((instruction as ReferenceInstruction).reference as StringReference).string - val index = stringsList.indexOfFirst { it == string } - if (index != -1) stringsList.removeAt(index) - } + val string = ((instruction as ReferenceInstruction).reference as StringReference).string + val index = stringsList.indexOfFirst { it == string } + if (index == -1) return@forEach - if (stringsList.isNotEmpty()) return false - } + add( + StringMatch( + string, + index + ) + ) + stringsList.removeAt(index) + } + + if (stringsList.isNotEmpty()) return false + }) + } else null val patternScanResult = if (methodFingerprint.opcodes != null) { context.implementation?.instructions ?: return false @@ -95,14 +104,22 @@ object MethodFingerprintUtils { context.patternScan(methodFingerprint) ?: return false } else null - methodFingerprint.result = MethodFingerprintResult(context, classDef, patternScanResult, forData) + methodFingerprint.result = MethodFingerprintResult( + context, + classDef, + MethodFingerprintResult.MethodFingerprintScanResult( + patternScanResult, + stringsScanResult + ), + forData + ) return true } private fun Method.patternScan( fingerprint: MethodFingerprint - ): PatternScanResult? { + ): MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult? { val instructions = this.implementation!!.instructions val fingerprintFuzzyPatternScanThreshold = fingerprint.fuzzyScanThreshold @@ -131,7 +148,8 @@ object MethodFingerprintUtils { continue } // the pattern is valid, generate warnings if fuzzyPatternScanMethod is FuzzyPatternScanMethod - val result = PatternScanResult(index, index + patternIndex) + val result = + MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult(index, index + patternIndex) if (fingerprint.fuzzyPatternScanMethod !is FuzzyPatternScanMethod) return result result.warnings = result.createWarnings(pattern, instructions) @@ -143,7 +161,10 @@ object MethodFingerprintUtils { } } -private fun PatternScanResult.createWarnings( +private typealias StringsScanResult = MethodFingerprintResult.MethodFingerprintScanResult.StringsScanResult +private typealias StringMatch = MethodFingerprintResult.MethodFingerprintScanResult.StringsScanResult.StringMatch + +private fun MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult.createWarnings( pattern: Iterable, instructions: Iterable ) = buildList { for ((patternIndex, instructionIndex) in (this@createWarnings.startIndex until this@createWarnings.endIndex).withIndex()) { @@ -152,7 +173,14 @@ private fun PatternScanResult.createWarnings( if (patternOpcode == null || patternOpcode.ordinal == originalOpcode.ordinal) continue - this.add(PatternScanResult.Warning(originalOpcode, patternOpcode, instructionIndex, patternIndex)) + this.add( + MethodFingerprintResult.MethodFingerprintScanResult.PatternScanResult.Warning( + originalOpcode, + patternOpcode, + instructionIndex, + patternIndex + ) + ) } }