mirror of
https://github.com/revanced/revanced-patcher.git
synced 2025-05-03 14:14:26 +02:00
refactor: Improve SignatureResolver
This commit is contained in:
parent
2777117da2
commit
a16c8cabf2
@ -1,7 +0,0 @@
|
|||||||
package app.revanced.patcher.resolver
|
|
||||||
|
|
||||||
internal data class PatternScanData(
|
|
||||||
val found: Boolean,
|
|
||||||
val startIndex: Int? = 0,
|
|
||||||
val endIndex: Int? = 0
|
|
||||||
)
|
|
@ -8,6 +8,7 @@ import app.revanced.patcher.signature.SignatureResolverResult
|
|||||||
import org.jf.dexlib2.Opcode
|
import org.jf.dexlib2.Opcode
|
||||||
import org.jf.dexlib2.iface.ClassDef
|
import org.jf.dexlib2.iface.ClassDef
|
||||||
import org.jf.dexlib2.iface.Method
|
import org.jf.dexlib2.iface.Method
|
||||||
|
import org.jf.dexlib2.iface.instruction.Instruction
|
||||||
|
|
||||||
// TODO: add logger back
|
// TODO: add logger back
|
||||||
internal class SignatureResolver(
|
internal class SignatureResolver(
|
||||||
@ -24,21 +25,14 @@ internal class SignatureResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (method in classDef.methods) {
|
for (method in classDef.methods) {
|
||||||
val (isMatch, patternScanData) = compareSignatureToMethod(signature, method)
|
val patternScanData = compareSignatureToMethod(signature, method) ?: continue
|
||||||
|
|
||||||
if (!isMatch || patternScanData == null) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// create class proxy, in case a patch needs mutability
|
// create class proxy, in case a patch needs mutability
|
||||||
val classProxy = ClassProxy(classDef, index)
|
val classProxy = ClassProxy(classDef, index)
|
||||||
methodMap[signature.name] = SignatureResolverResult(
|
methodMap[signature.name] = SignatureResolverResult(
|
||||||
classProxy,
|
classProxy,
|
||||||
method.name,
|
method.name,
|
||||||
PatternScanResult(
|
patternScanData
|
||||||
patternScanData.startIndex!!,
|
|
||||||
patternScanData.endIndex!!
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,12 +50,11 @@ internal class SignatureResolver(
|
|||||||
companion object {
|
companion object {
|
||||||
fun resolveFromProxy(classProxy: ClassProxy, signature: MethodSignature): SignatureResolverResult? {
|
fun resolveFromProxy(classProxy: ClassProxy, signature: MethodSignature): SignatureResolverResult? {
|
||||||
for (method in classProxy.immutableClass.methods) {
|
for (method in classProxy.immutableClass.methods) {
|
||||||
val (r, sr) = compareSignatureToMethod(signature, method)
|
val result = compareSignatureToMethod(signature, method) ?: continue
|
||||||
if (!r || sr == null) continue
|
|
||||||
return SignatureResolverResult(
|
return SignatureResolverResult(
|
||||||
classProxy,
|
classProxy,
|
||||||
method.name,
|
method.name,
|
||||||
null
|
result
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@ -70,33 +63,29 @@ internal class SignatureResolver(
|
|||||||
private fun compareSignatureToMethod(
|
private fun compareSignatureToMethod(
|
||||||
signature: MethodSignature,
|
signature: MethodSignature,
|
||||||
method: Method
|
method: Method
|
||||||
): Pair<Boolean, PatternScanData?> {
|
): PatternScanResult? {
|
||||||
// TODO: compare as generic object if not primitive
|
|
||||||
signature.returnType?.let { _ ->
|
signature.returnType?.let { _ ->
|
||||||
if (signature.returnType != method.returnType) {
|
if (!method.returnType.startsWith(signature.returnType)) return@compareSignatureToMethod null
|
||||||
return@compareSignatureToMethod false to null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signature.accessFlags?.let { _ ->
|
signature.accessFlags?.let { _ ->
|
||||||
if (signature.accessFlags != method.accessFlags) {
|
if (signature.accessFlags != method.accessFlags) {
|
||||||
return@compareSignatureToMethod false to null
|
return@compareSignatureToMethod null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: compare as generic object if the parameter is not primitive
|
|
||||||
signature.methodParameters?.let { _ ->
|
signature.methodParameters?.let { _ ->
|
||||||
if (signature.methodParameters != method.parameters) {
|
if (signature.methodParameters.all { signatureMethodParameter ->
|
||||||
return@compareSignatureToMethod false to null
|
method.parameterTypes.any { methodParameter ->
|
||||||
|
methodParameter.startsWith(signatureMethodParameter)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
return@compareSignatureToMethod null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signature.opcodes?.let { _ ->
|
return if (signature.opcodes == null) null
|
||||||
val result = method.implementation?.instructions?.scanFor(signature.opcodes)
|
else method.implementation?.instructions?.scanFor(signature.opcodes)!!
|
||||||
return@compareSignatureToMethod if (result != null && result.found) true to result else false to null
|
|
||||||
}
|
|
||||||
|
|
||||||
return true to PatternScanData(true)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,38 +93,17 @@ internal class SignatureResolver(
|
|||||||
private operator fun ClassDef.component1() = this
|
private operator fun ClassDef.component1() = this
|
||||||
private operator fun ClassDef.component2() = this.methods
|
private operator fun ClassDef.component2() = this.methods
|
||||||
|
|
||||||
private fun <T> MutableIterable<T>.scanFor(pattern: Array<Opcode>): PatternScanData {
|
private fun MutableIterable<Instruction>.scanFor(pattern: Array<Opcode>): PatternScanResult? {
|
||||||
// TODO: create var for count?
|
// TODO: create var for count?
|
||||||
for (i in 0 until this.count()) {
|
for (instructionIndex in 0 until this.count()) {
|
||||||
var occurrence = 0
|
var patternIndex = 0
|
||||||
while (i + occurrence < this.count()) {
|
while (instructionIndex + patternIndex < this.count()) {
|
||||||
val n = this.elementAt(i + occurrence)
|
if (this.elementAt(instructionIndex + patternIndex).opcode != pattern[patternIndex]) break
|
||||||
if (!n.shouldSkip() && n != pattern[occurrence]) break
|
if (++patternIndex < pattern.size) continue
|
||||||
if (++occurrence >= pattern.size) {
|
|
||||||
val current = i + occurrence
|
return PatternScanResult(instructionIndex, instructionIndex + patternIndex)
|
||||||
return PatternScanData(true, current - pattern.size, current)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PatternScanData(false)
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: extend Opcode type, not T (requires a cast to Opcode)
|
|
||||||
private fun <T> T.shouldSkip(): Boolean {
|
|
||||||
return this == Opcode.GOTO // TODO: and: this == AbstractInsnNode.LINE
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: use this somehow to compare types as generic objects if not primitive
|
|
||||||
// private fun Type.convertObject(): Type {
|
|
||||||
// return when (this.sort) {
|
|
||||||
// Type.OBJECT -> ExtraTypes.Any
|
|
||||||
// Type.ARRAY -> ExtraTypes.ArrayAny
|
|
||||||
// else -> this
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private fun Array<Type>.convertObjects(): Array<Type> {
|
|
||||||
// return this.map { it.convertObject() }.toTypedArray()
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user