mirror of
https://github.com/ReVanced/revanced-patcher.git
synced 2024-11-10 09:08:04 +01:00
fix: reaching all constructors not possible
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
ac36d19693
commit
37fa9949ec
4 changed files with 46 additions and 22 deletions
|
@ -5,8 +5,10 @@ import org.jf.dexlib2.AccessFlags
|
||||||
import org.jf.dexlib2.builder.BuilderInstruction
|
import org.jf.dexlib2.builder.BuilderInstruction
|
||||||
import org.jf.dexlib2.builder.MutableMethodImplementation
|
import org.jf.dexlib2.builder.MutableMethodImplementation
|
||||||
import org.jf.dexlib2.iface.Method
|
import org.jf.dexlib2.iface.Method
|
||||||
|
import org.jf.dexlib2.iface.reference.MethodReference
|
||||||
import org.jf.dexlib2.immutable.ImmutableMethod
|
import org.jf.dexlib2.immutable.ImmutableMethod
|
||||||
import org.jf.dexlib2.immutable.ImmutableMethodImplementation
|
import org.jf.dexlib2.immutable.ImmutableMethodImplementation
|
||||||
|
import org.jf.dexlib2.util.MethodUtil
|
||||||
|
|
||||||
infix fun AccessFlags.or(other: AccessFlags) = this.value or other.value
|
infix fun AccessFlags.or(other: AccessFlags) = this.value or other.value
|
||||||
infix fun Int.or(other: AccessFlags) = this or other.value
|
infix fun Int.or(other: AccessFlags) = this or other.value
|
||||||
|
@ -23,7 +25,7 @@ fun MutableMethodImplementation.addInstructions(index: Int, instructions: List<B
|
||||||
* This may be a positive or negative number.
|
* This may be a positive or negative number.
|
||||||
* @return The **immutable** cloned method. Call [toMutable] or [cloneMutable] to get a **mutable** copy.
|
* @return The **immutable** cloned method. Call [toMutable] or [cloneMutable] to get a **mutable** copy.
|
||||||
*/
|
*/
|
||||||
fun Method.clone(
|
internal fun Method.clone(
|
||||||
registerCount: Int = 0,
|
registerCount: Int = 0,
|
||||||
): ImmutableMethod {
|
): ImmutableMethod {
|
||||||
val clonedImplementation = implementation?.let {
|
val clonedImplementation = implementation?.let {
|
||||||
|
@ -52,6 +54,28 @@ fun Method.clone(
|
||||||
* This may be a positive or negative number.
|
* This may be a positive or negative number.
|
||||||
* @return The **mutable** cloned method. Call [clone] to get an **immutable** copy.
|
* @return The **mutable** cloned method. Call [clone] to get an **immutable** copy.
|
||||||
*/
|
*/
|
||||||
fun Method.cloneMutable(
|
internal fun Method.cloneMutable(
|
||||||
registerCount: Int = 0,
|
registerCount: Int = 0,
|
||||||
) = clone(registerCount).toMutable()
|
) = clone(registerCount).toMutable()
|
||||||
|
|
||||||
|
internal fun Method.softCompareTo(
|
||||||
|
otherMethod: MethodReference
|
||||||
|
): Boolean {
|
||||||
|
if (MethodUtil.isConstructor(this) && !parametersEqual(this.parameterTypes, otherMethod.parameterTypes))
|
||||||
|
return false
|
||||||
|
return this.name == otherMethod.name
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: also check the order of parameters as different order equals different method overload
|
||||||
|
internal fun parametersEqual(
|
||||||
|
parameters1: Iterable<CharSequence>,
|
||||||
|
parameters2: Iterable<CharSequence>
|
||||||
|
): Boolean {
|
||||||
|
return parameters1.count() == parameters2.count() && parameters1.all { parameter ->
|
||||||
|
parameters2.any {
|
||||||
|
it.startsWith(
|
||||||
|
parameter
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package app.revanced.patcher.methodWalker
|
||||||
|
|
||||||
import app.revanced.patcher.MethodNotFoundException
|
import app.revanced.patcher.MethodNotFoundException
|
||||||
import app.revanced.patcher.PatcherData
|
import app.revanced.patcher.PatcherData
|
||||||
|
import app.revanced.patcher.extensions.softCompareTo
|
||||||
import app.revanced.patcher.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.proxy.mutableTypes.MutableMethod
|
||||||
import org.jf.dexlib2.Format
|
import org.jf.dexlib2.Format
|
||||||
import org.jf.dexlib2.iface.Method
|
import org.jf.dexlib2.iface.Method
|
||||||
|
@ -38,13 +39,17 @@ class MethodWalker internal constructor(
|
||||||
|
|
||||||
Preconditions.checkFormat(instruction.opcode, Format.Format35c)
|
Preconditions.checkFormat(instruction.opcode, Format.Format35c)
|
||||||
|
|
||||||
val newMethodRef = (instruction as Instruction35c).reference as MethodReference
|
val newMethod = (instruction as Instruction35c).reference as MethodReference
|
||||||
val proxy = patcherData.findClass(newMethodRef.definingClass)!!
|
val proxy = patcherData.findClass(newMethod.definingClass)!!
|
||||||
|
|
||||||
val methods = if (walkMutable) proxy.resolve().methods else proxy.immutableClass.methods
|
val methods = if (walkMutable) proxy.resolve().methods else proxy.immutableClass.methods
|
||||||
currentMethod = methods.first { it.name == newMethodRef.name }
|
currentMethod = methods.first { it ->
|
||||||
|
return@first it.softCompareTo(newMethod)
|
||||||
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
throw MethodNotFoundException("This method can not be walked at offset $offset inside the method ${currentMethod.name}")
|
throw MethodNotFoundException("This method can not be walked at offset $offset inside the method ${currentMethod.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package app.revanced.patcher.signature
|
package app.revanced.patcher.signature
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.softCompareTo
|
||||||
import app.revanced.patcher.proxy.ClassProxy
|
import app.revanced.patcher.proxy.ClassProxy
|
||||||
import app.revanced.patcher.signature.resolver.SignatureResolver
|
import app.revanced.patcher.signature.resolver.SignatureResolver
|
||||||
import org.jf.dexlib2.iface.Method
|
import org.jf.dexlib2.iface.Method
|
||||||
|
@ -7,33 +8,33 @@ import org.jf.dexlib2.iface.Method
|
||||||
/**
|
/**
|
||||||
* Represents the result of a [SignatureResolver].
|
* Represents the result of a [SignatureResolver].
|
||||||
* @param definingClassProxy The [ClassProxy] that the matching method was found in.
|
* @param definingClassProxy The [ClassProxy] that the matching method was found in.
|
||||||
* @param resolvedMethodName The name of the actual matching method.
|
* @param resolvedMethod The actual matching method.
|
||||||
* @param scanData Opcodes pattern scan result.
|
* @param scanData Opcodes pattern scan result.
|
||||||
*/
|
*/
|
||||||
data class SignatureResolverResult(
|
data class SignatureResolverResult(
|
||||||
val definingClassProxy: ClassProxy,
|
val definingClassProxy: ClassProxy,
|
||||||
val scanData: PatternScanResult,
|
val scanData: PatternScanResult,
|
||||||
private val resolvedMethodName: String,
|
private val resolvedMethod: Method,
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Returns the **mutable** method by the [resolvedMethodName] from the [definingClassProxy].
|
* Returns the **mutable** method by the [resolvedMethod] from the [definingClassProxy].
|
||||||
*
|
*
|
||||||
* Please note, this method allocates a [ClassProxy].
|
* Please note, this method allocates a [ClassProxy].
|
||||||
* Use [immutableMethod] where possible.
|
* Use [immutableMethod] where possible.
|
||||||
*/
|
*/
|
||||||
val method
|
val method
|
||||||
get() = definingClassProxy.resolve().methods.first {
|
get() = definingClassProxy.resolve().methods.first {
|
||||||
it.name == resolvedMethodName
|
it.softCompareTo(resolvedMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the **immutable** method by the [resolvedMethodName] from the [definingClassProxy].
|
* Returns the **immutable** method by the [resolvedMethod] from the [definingClassProxy].
|
||||||
*
|
*
|
||||||
* If you need to modify the method, use [method] instead.
|
* If you need to modify the method, use [method] instead.
|
||||||
*/
|
*/
|
||||||
val immutableMethod: Method
|
val immutableMethod: Method
|
||||||
get() = definingClassProxy.immutableClass.methods.first {
|
get() = definingClassProxy.immutableClass.methods.first {
|
||||||
it.name == resolvedMethodName
|
it.softCompareTo(resolvedMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findParentMethod(signature: MethodSignature): SignatureResolverResult? {
|
fun findParentMethod(signature: MethodSignature): SignatureResolverResult? {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package app.revanced.patcher.signature.resolver
|
package app.revanced.patcher.signature.resolver
|
||||||
|
|
||||||
import app.revanced.patcher.PatcherData
|
import app.revanced.patcher.PatcherData
|
||||||
|
import app.revanced.patcher.extensions.parametersEqual
|
||||||
import app.revanced.patcher.proxy
|
import app.revanced.patcher.proxy
|
||||||
import app.revanced.patcher.proxy.ClassProxy
|
import app.revanced.patcher.proxy.ClassProxy
|
||||||
import app.revanced.patcher.signature.MethodSignature
|
import app.revanced.patcher.signature.MethodSignature
|
||||||
|
@ -29,7 +30,7 @@ internal class SignatureResolver(
|
||||||
signature.result = SignatureResolverResult(
|
signature.result = SignatureResolverResult(
|
||||||
classProxy,
|
classProxy,
|
||||||
patternScanData,
|
patternScanData,
|
||||||
method.name,
|
method,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +45,7 @@ internal class SignatureResolver(
|
||||||
return SignatureResolverResult(
|
return SignatureResolverResult(
|
||||||
classProxy,
|
classProxy,
|
||||||
result,
|
result,
|
||||||
method.name,
|
method,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
@ -67,7 +68,7 @@ internal class SignatureResolver(
|
||||||
}
|
}
|
||||||
|
|
||||||
signature.methodParameters?.let {
|
signature.methodParameters?.let {
|
||||||
if (compareParameterTypes(signature.methodParameters, method.parameterTypes)) {
|
if (!parametersEqual(signature.methodParameters, method.parameterTypes)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,13 +138,6 @@ internal class SignatureResolver(
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compareParameterTypes(
|
|
||||||
signature: Iterable<String>,
|
|
||||||
original: MutableList<out CharSequence>
|
|
||||||
): Boolean {
|
|
||||||
return signature.count() != original.size || !(signature.all { a -> original.any { it.startsWith(a) } })
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateWarnings(
|
private fun generateWarnings(
|
||||||
signature: MethodSignature,
|
signature: MethodSignature,
|
||||||
instructions: Iterable<Instruction>,
|
instructions: Iterable<Instruction>,
|
||||||
|
|
Loading…
Reference in a new issue