Convert typed Object & Array types to Object types

Commit name is a bit superfluous, but it means that types such as "Ljava/lang/String;" get converted to "Ljava/lang/Object;". This is so we don't need to know the mappings, which are random in YT's code.

This is done in MethodResolver's "convertObject" and "convertObjects" for arrays.

Also changed ExtraTypes.ArrayAny to Object instead of String, that was a mistake. (which caused the test to pass at first)
This commit is contained in:
Lucaskyy 2022-03-19 22:34:41 +01:00
parent f9327a2043
commit e5f9a42ee6
No known key found for this signature in database
GPG key ID: 1530BFF96D1EEB89
5 changed files with 49 additions and 16 deletions

View file

@ -4,6 +4,7 @@ import mu.KotlinLogging
import net.revanced.patcher.cache.PatchData
import net.revanced.patcher.cache.ScanData
import net.revanced.patcher.signature.Signature
import net.revanced.patcher.util.ExtraTypes
import org.objectweb.asm.Type
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.InsnList
@ -51,16 +52,32 @@ internal class MethodResolver(private val classList: List<ClassNode>, private va
}
private fun cmp(method: MethodNode, signature: Signature): Pair<Boolean, ScanResult?> {
if (signature.returns != Type.getReturnType(method.desc)) {
logger.debug { "Comparing sig ${signature.name}: invalid return type:\nexpected ${signature.returns},\ngot ${Type.getReturnType(method.desc)}" }
val returns = Type.getReturnType(method.desc).convertObject()
if (signature.returns != returns) {
logger.debug {
"""
Comparing sig ${signature.name}: invalid return type:
expected ${signature.returns}},
got $returns
""".trimIndent()
}
return false to null
}
if (signature.accessors != method.access) {
logger.debug { "Comparing sig ${signature.name}: invalid accessors:\nexpected ${signature.accessors},\ngot ${method.access}" }
return false to null
}
if (!signature.parameters.contentEquals(Type.getArgumentTypes(method.desc))) {
logger.debug { "Comparing sig ${signature.name}: invalid parameter types:\nexpected ${signature.parameters},\ngot ${Type.getArgumentTypes(method.desc)}" }
val parameters = Type.getArgumentTypes(method.desc).convertObjects()
if (!signature.parameters.contentEquals(parameters)) {
logger.debug {
"""
Comparing sig ${signature.name}: invalid parameter types:
expected ${signature.parameters.joinToString()}},
got ${parameters.joinToString()}
""".trimIndent()
}
return false to null
}
@ -96,3 +113,15 @@ private fun InsnList.scanFor(pattern: Array<Int>): ScanResult {
return ScanResult(false)
}
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()
}

View file

@ -1,5 +0,0 @@
package net.revanced.patcher.util
object ASMWriter {
}

View file

@ -7,6 +7,6 @@ object ExtraTypes {
* Any object type.
* Should be used instead of types such as: "Ljava/lang/String;"
*/
val Any = Type.getType(Object::class.java)
val ArrayAny = Type.getType(Array<String>::class.java)
val Any: Type = Type.getType(Object::class.java)
val ArrayAny: Type = Type.getType(Array<Any>::class.java)
}

View file

@ -0,0 +1,9 @@
package net.revanced.patcher.writer
import org.objectweb.asm.tree.InsnList
object ASMWriter {
fun InsnList.testingWow() {
TODO()
}
}

View file

@ -4,6 +4,7 @@ import net.revanced.patcher.patch.Patch
import net.revanced.patcher.patch.PatchResultSuccess
import net.revanced.patcher.signature.Signature
import net.revanced.patcher.util.ExtraTypes
import net.revanced.patcher.writer.ASMWriter.testingWow
import org.junit.jupiter.api.Test
import org.objectweb.asm.Opcodes.*
import org.objectweb.asm.Type
@ -11,12 +12,10 @@ import org.objectweb.asm.Type
internal class PatcherTest {
private val testSigs: Array<Signature> = arrayOf(
Signature(
"testMethod",
"mainMethod",
Type.VOID_TYPE,
ACC_PUBLIC or ACC_STATIC,
arrayOf(
ExtraTypes.ArrayAny,
),
arrayOf(ExtraTypes.ArrayAny),
arrayOf(
GETSTATIC,
LDC,
@ -32,7 +31,8 @@ internal class PatcherTest {
patcher.addPatches(
Patch ("TestPatch") {
patcher.cache.methods["testMethod"]
val main = patcher.cache.methods["mainMethod"]
//main.method.instructions!!.testingWow()
PatchResultSuccess()
}
)