From 6bd4d80c47a383a875b73d0ea4094987ffabc1f4 Mon Sep 17 00:00:00 2001 From: Lucaskyy Date: Sat, 19 Mar 2022 21:28:50 +0100 Subject: [PATCH] Cache classes with their path & add ScanData for PatchData --- .../kotlin/net/revanced/patcher/Patcher.kt | 11 ++++++-- .../net/revanced/patcher/cache/Cache.kt | 7 +++-- .../net/revanced/patcher/cache/PatchData.kt | 8 +++++- .../patcher/resolver/MethodResolver.kt | 27 ++++++++++++------- .../net/revanced/patcher/util/ASMWriter.kt | 5 ++++ .../net/revanced/patcher/util/Jar2ASM.kt | 6 ++--- 6 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 src/main/kotlin/net/revanced/patcher/util/ASMWriter.kt diff --git a/src/main/kotlin/net/revanced/patcher/Patcher.kt b/src/main/kotlin/net/revanced/patcher/Patcher.kt index 410ef77..0e0b7fe 100644 --- a/src/main/kotlin/net/revanced/patcher/Patcher.kt +++ b/src/main/kotlin/net/revanced/patcher/Patcher.kt @@ -7,12 +7,14 @@ import net.revanced.patcher.resolver.MethodResolver import net.revanced.patcher.signature.Signature import net.revanced.patcher.util.Jar2ASM import java.io.InputStream +import java.io.OutputStream import java.util.jar.JarFile /** * The patcher. (docs WIP) * - * @param input the input stream to read from, must be a JAR file (for now) + * @param input the input stream to read from, must be a JAR + * @param signatures the signatures */ class Patcher ( input: InputStream, @@ -22,7 +24,8 @@ class Patcher ( private val patches: MutableList = mutableListOf() init { - cache.methods.putAll(MethodResolver(Jar2ASM.jar2asm(input), signatures).resolve()) + cache.classes.putAll(Jar2ASM.jar2asm(input)) + cache.methods.putAll(MethodResolver(cache.classes.values.toList(), signatures).resolve()) } fun addPatches(vararg patches: Patch) { @@ -43,4 +46,8 @@ class Patcher ( } } } + + fun save(output: OutputStream) { + + } } \ No newline at end of file diff --git a/src/main/kotlin/net/revanced/patcher/cache/Cache.kt b/src/main/kotlin/net/revanced/patcher/cache/Cache.kt index 79a9d31..fbff7f5 100644 --- a/src/main/kotlin/net/revanced/patcher/cache/Cache.kt +++ b/src/main/kotlin/net/revanced/patcher/cache/Cache.kt @@ -1,8 +1,11 @@ package net.revanced.patcher.cache -data class Cache( +import org.objectweb.asm.tree.ClassNode + +class Cache { + val classes: MutableMap = mutableMapOf() val methods: MethodMap = MethodMap() -) +} class MethodMap : LinkedHashMap() { override fun get(key: String): PatchData { diff --git a/src/main/kotlin/net/revanced/patcher/cache/PatchData.kt b/src/main/kotlin/net/revanced/patcher/cache/PatchData.kt index 556b005..68efce8 100644 --- a/src/main/kotlin/net/revanced/patcher/cache/PatchData.kt +++ b/src/main/kotlin/net/revanced/patcher/cache/PatchData.kt @@ -5,5 +5,11 @@ import org.objectweb.asm.tree.MethodNode data class PatchData( val cls: ClassNode, - val method: MethodNode + val method: MethodNode, + val sr: ScanData +) + +data class ScanData( + val startIndex: Int, + val endIndex: Int ) diff --git a/src/main/kotlin/net/revanced/patcher/resolver/MethodResolver.kt b/src/main/kotlin/net/revanced/patcher/resolver/MethodResolver.kt index bd4b225..09726be 100644 --- a/src/main/kotlin/net/revanced/patcher/resolver/MethodResolver.kt +++ b/src/main/kotlin/net/revanced/patcher/resolver/MethodResolver.kt @@ -2,6 +2,7 @@ package net.revanced.patcher.resolver import mu.KotlinLogging import net.revanced.patcher.cache.PatchData +import net.revanced.patcher.cache.ScanData import net.revanced.patcher.signature.Signature import org.objectweb.asm.Type import org.objectweb.asm.tree.ClassNode @@ -22,12 +23,21 @@ internal class MethodResolver(private val classList: List, private va continue } logger.debug { "Resolving sig ${signature.name}: ${classNode.name} / ${method.name}" } - if (!this.cmp(method, signature)) { + val (r, sr) = this.cmp(method, signature) + if (!r || sr == null) { logger.debug { "Compare result for sig ${signature.name} has failed!" } continue } logger.debug { "Method for sig ${signature.name} found!" } - patchData[signature.name] = PatchData(classNode, method) + patchData[signature.name] = PatchData( + classNode, + method, + ScanData( + // sadly we cannot create contracts for a data class, so we must assert + sr.startIndex!!, + sr.endIndex!! + ) + ) } } } @@ -40,28 +50,27 @@ internal class MethodResolver(private val classList: List, private va return patchData } - private fun cmp(method: MethodNode, signature: Signature): Boolean { + private fun cmp(method: MethodNode, signature: Signature): Pair { if (signature.returns != Type.getReturnType(method.desc)) { logger.debug { "Comparing sig ${signature.name}: invalid return type:\nexpected ${signature.returns},\ngot ${Type.getReturnType(method.desc)}" } - return false + 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 + 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)}" } - return false + return false to null } val result = method.instructions.scanFor(signature.opcodes) if (!result.found) { logger.debug { "Comparing sig ${signature.name}: invalid opcode pattern" } - return false + return false to null } - // TODO make use of the startIndex and endIndex we have from the result - return true + return true to result } } diff --git a/src/main/kotlin/net/revanced/patcher/util/ASMWriter.kt b/src/main/kotlin/net/revanced/patcher/util/ASMWriter.kt new file mode 100644 index 0000000..ea3fb89 --- /dev/null +++ b/src/main/kotlin/net/revanced/patcher/util/ASMWriter.kt @@ -0,0 +1,5 @@ +package net.revanced.patcher.util + +object ASMWriter { + +} \ No newline at end of file diff --git a/src/main/kotlin/net/revanced/patcher/util/Jar2ASM.kt b/src/main/kotlin/net/revanced/patcher/util/Jar2ASM.kt index c192384..0c10f19 100644 --- a/src/main/kotlin/net/revanced/patcher/util/Jar2ASM.kt +++ b/src/main/kotlin/net/revanced/patcher/util/Jar2ASM.kt @@ -6,15 +6,15 @@ import java.io.InputStream import java.util.jar.JarInputStream object Jar2ASM { - fun jar2asm(input: InputStream): List { - return buildList { + fun jar2asm(input: InputStream): Map { + return buildMap { val jar = JarInputStream(input) while (true) { val e = jar.nextJarEntry ?: break if (e.name.endsWith(".class")) { val classNode = ClassNode() ClassReader(jar.readAllBytes()).accept(classNode, ClassReader.EXPAND_FRAMES) - this.add(classNode) + this[e.name] = classNode } } }