From 6425990b232aab0b5cea4417f5aaf4ab50676987 Mon Sep 17 00:00:00 2001 From: Graham Date: Mon, 23 Dec 2019 15:45:28 +0000 Subject: [PATCH] Convert SignedClassUtils to Kotlin --- .../dev/openrs2/deob/SignedClassUtils.java | 108 ------------------ .../java/dev/openrs2/deob/SignedClassUtils.kt | 94 +++++++++++++++ 2 files changed, 94 insertions(+), 108 deletions(-) delete mode 100644 deob/src/main/java/dev/openrs2/deob/SignedClassUtils.java create mode 100644 deob/src/main/java/dev/openrs2/deob/SignedClassUtils.kt diff --git a/deob/src/main/java/dev/openrs2/deob/SignedClassUtils.java b/deob/src/main/java/dev/openrs2/deob/SignedClassUtils.java deleted file mode 100644 index c714baf9b7..0000000000 --- a/deob/src/main/java/dev/openrs2/deob/SignedClassUtils.java +++ /dev/null @@ -1,108 +0,0 @@ -package dev.openrs2.deob; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -import com.google.common.collect.Sets; -import dev.openrs2.asm.InsnMatcher; -import dev.openrs2.asm.classpath.Library; -import org.objectweb.asm.Type; -import org.objectweb.asm.commons.ClassRemapper; -import org.objectweb.asm.commons.SimpleRemapper; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.LdcInsnNode; -import org.objectweb.asm.tree.MethodNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class SignedClassUtils { - private static final Logger logger = LoggerFactory.getLogger(SignedClassUtils.class); - - private static final InsnMatcher LOAD_SIGNED_CLASS_MATCHER = InsnMatcher.compile("LDC INVOKESTATIC ASTORE ALOAD GETFIELD ALOAD INVOKEVIRTUAL ALOAD INVOKEVIRTUAL POP"); - - public static void move(Library loader, Library client, Library signLink) { - /* find signed classes */ - var signedClasses = findSignedClasses(loader); - logger.info("Identified signed classes {}", signedClasses); - - var dependencies = findDependencies(loader, signedClasses); - logger.info("Identified signed class dependencies {}", dependencies); - - /* rename dependencies of signed classes so they don't clash with client classes */ - var mapping = new HashMap(); - for (var dependency : dependencies) { - mapping.put(dependency, "loader_" + dependency); - } - var remapper = new SimpleRemapper(mapping); - - /* delete original signed classes (these have no dependencies) */ - for (var name : signedClasses) { - client.remove(name); - } - - /* move loader signed classes to signlink */ - for (var name : Sets.union(signedClasses, dependencies)) { - var in = loader.remove(name); - - var out = new ClassNode(); - in.accept(new ClassRemapper(out, remapper)); - - signLink.add(out); - } - } - - private static Set findSignedClasses(Library loader) { - var clazz = loader.get("loader"); - if (clazz == null) { - throw new IllegalArgumentException("Failed to find loader class"); - } - - for (var method : clazz.methods) { - if (method.name.equals("run") && method.desc.equals("()V")) { - return findSignedClasses(method); - } - } - - throw new IllegalArgumentException("Failed to find loader.run() method"); - } - - private static Set findSignedClasses(MethodNode method) { - var classes = new HashSet(); - - LOAD_SIGNED_CLASS_MATCHER.match(method).forEach(match -> { - var ldc = (LdcInsnNode) match.get(0); - if (ldc.cst instanceof String && !ldc.cst.equals("unpack")) { - classes.add((String) ldc.cst); - } - }); - - return classes; - } - - private static Set findDependencies(Library loader, Set signedClasses) { - var dependencies = new HashSet(); - - for (var signedClass : signedClasses) { - var clazz = loader.get(signedClass); - - for (var field : clazz.fields) { - var type = Type.getType(field.desc); - if (type.getSort() != Type.OBJECT) { - continue; - } - - var name = type.getClassName(); - if (loader.contains(name) && !signedClasses.contains(name)) { - dependencies.add(name); - } - } - } - - return dependencies; - } - - private SignedClassUtils() { - /* empty */ - } -} diff --git a/deob/src/main/java/dev/openrs2/deob/SignedClassUtils.kt b/deob/src/main/java/dev/openrs2/deob/SignedClassUtils.kt new file mode 100644 index 0000000000..6d29983073 --- /dev/null +++ b/deob/src/main/java/dev/openrs2/deob/SignedClassUtils.kt @@ -0,0 +1,94 @@ +package dev.openrs2.deob + +import com.github.michaelbull.logging.InlineLogger +import dev.openrs2.asm.InsnMatcher +import dev.openrs2.asm.classpath.Library +import org.objectweb.asm.Type +import org.objectweb.asm.commons.ClassRemapper +import org.objectweb.asm.commons.SimpleRemapper +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.LdcInsnNode +import org.objectweb.asm.tree.MethodNode + +object SignedClassUtils { + private val logger = InlineLogger() + private val LOAD_SIGNED_CLASS_MATCHER = + InsnMatcher.compile("LDC INVOKESTATIC ASTORE ALOAD GETFIELD ALOAD INVOKEVIRTUAL ALOAD INVOKEVIRTUAL POP") + + @JvmStatic + fun move(loader: Library, client: Library, signLink: Library) { + // find signed classes + val signedClasses = findSignedClasses(loader) + logger.info { "Identified signed classes $signedClasses" } + + val dependencies = findDependencies(loader, signedClasses) + logger.info { "Identified signed class dependencies $dependencies" } + + // rename dependencies of signed classes so they don't clash with client classes + val mapping = mutableMapOf() + for (dependency in dependencies) { + mapping[dependency] = "loader_$dependency" + } + val remapper = SimpleRemapper(mapping) + + // delete original signed classes (these have no dependencies) + for (name in signedClasses) { + client.remove(name) + } + + // move loader signed classes to signlink + for (name in signedClasses.union(dependencies)) { + val `in` = loader.remove(name) + + val out = ClassNode() + `in`.accept(ClassRemapper(out, remapper)) + + signLink.add(out) + } + } + + private fun findSignedClasses(loader: Library): Set { + val clazz = loader["loader"] ?: throw IllegalArgumentException("Failed to find loader class") + + val method = clazz.methods.find { it.name == "run" && it.desc == "()V" } + ?: throw IllegalArgumentException("Failed to find loader.run() method") + + return findSignedClasses(method) + } + + private fun findSignedClasses(method: MethodNode): Set { + val classes = mutableSetOf() + + LOAD_SIGNED_CLASS_MATCHER.match(method).forEach { + val ldc = it[0] as LdcInsnNode + val cst = ldc.cst + if (cst is String && cst != "unpack") { + classes.add(cst) + } + } + + return classes + } + + private fun findDependencies(loader: Library, signedClasses: Set): Set { + val dependencies = mutableSetOf() + + for (signedClass in signedClasses) { + val clazz = loader[signedClass] + + for (field in clazz.fields) { + val type = Type.getType(field.desc) + if (type.sort != Type.OBJECT) { + continue + } + + val name = type.className + if (loader.contains(name) && !signedClasses.contains(name)) { + dependencies.add(name) + } + } + } + + return dependencies + } +}