diff --git a/asm/src/main/java/dev/openrs2/asm/Transformer.java b/asm/src/main/java/dev/openrs2/asm/Transformer.java index 82b89a85bc..4a8909e55a 100644 --- a/asm/src/main/java/dev/openrs2/asm/Transformer.java +++ b/asm/src/main/java/dev/openrs2/asm/Transformer.java @@ -1,5 +1,6 @@ package dev.openrs2.asm; +import dev.openrs2.asm.classpath.ClassPath; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldNode; @@ -7,29 +8,31 @@ import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.analysis.AnalyzerException; public abstract class Transformer { - public void transform(Library library) throws AnalyzerException { - preTransform(library); + public void transform(ClassPath classPath) throws AnalyzerException { + preTransform(classPath); - for (var clazz : library) { - transformClass(clazz); + for (var library : classPath.getLibraries()) { + for (var clazz : library) { + transformClass(clazz); - for (var field : clazz.fields) { - transformField(clazz, field); - } + for (var field : clazz.fields) { + transformField(clazz, field); + } - for (var method : clazz.methods) { - transformMethod(clazz, method); + for (var method : clazz.methods) { + transformMethod(clazz, method); - if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) == 0) { - transformCode(clazz, method); + if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) == 0) { + transformCode(clazz, method); + } } } } - postTransform(library); + postTransform(classPath); } - public void preTransform(Library library) throws AnalyzerException { + public void preTransform(ClassPath classPath) throws AnalyzerException { /* empty */ } @@ -49,7 +52,7 @@ public abstract class Transformer { /* empty */ } - public void postTransform(Library library) throws AnalyzerException { + public void postTransform(ClassPath classPath) throws AnalyzerException { /* empty */ } } diff --git a/asm/src/main/java/dev/openrs2/asm/classpath/ClassPath.java b/asm/src/main/java/dev/openrs2/asm/classpath/ClassPath.java index ef0ca450a9..0d4af6625a 100644 --- a/asm/src/main/java/dev/openrs2/asm/classpath/ClassPath.java +++ b/asm/src/main/java/dev/openrs2/asm/classpath/ClassPath.java @@ -13,6 +13,7 @@ import dev.openrs2.asm.MemberDesc; import dev.openrs2.asm.MemberRef; import dev.openrs2.util.collect.DisjointSet; import dev.openrs2.util.collect.ForestDisjointSet; +import org.objectweb.asm.tree.ClassNode; public final class ClassPath { private final ClassLoader runtime; @@ -25,6 +26,10 @@ public final class ClassPath { this.libraries = libraries; } + public List getLibraries() { + return libraries; + } + public List getLibraryClasses() { var classes = new ArrayList(); @@ -75,6 +80,16 @@ public final class ClassPath { return metadata; } + public ClassNode getNode(String name) { + for (var library : libraries) { + var clazz = library.get(name); + if (clazz != null) { + return clazz; + } + } + return null; + } + public DisjointSet createInheritedFieldSets() { var disjointSet = new ForestDisjointSet(); var ancestorCache = new HashMap>(); diff --git a/deob/src/main/java/dev/openrs2/deob/Deobfuscator.java b/deob/src/main/java/dev/openrs2/deob/Deobfuscator.java index 2d68cb914a..89bb391d27 100644 --- a/deob/src/main/java/dev/openrs2/deob/Deobfuscator.java +++ b/deob/src/main/java/dev/openrs2/deob/Deobfuscator.java @@ -5,7 +5,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; -import java.util.Map; import dev.openrs2.asm.Library; import dev.openrs2.asm.Transformer; @@ -67,27 +66,6 @@ public final class Deobfuscator { logger.info("Moving signed classes from loader_gl to runescape_gl"); var glSignedClasses = SignedClassSet.create(glLoader, glClient); - /* deobfuscate */ - var allLibraries = Map.of( - "unpacker", unpacker, - "unpacker_gl", glUnpacker, - "loader", loader, - "loader_gl", glLoader, - "jaggl", gl, - "runescape", client, - "runescape_gl", glClient, - "runescape_unsigned", unsignedClient - ); - - for (var entry : allLibraries.entrySet()) { - logger.info("Transforming library {}", entry.getKey()); - - for (var transformer : TRANSFORMERS) { - logger.info("Running transformer {}", transformer.getClass().getSimpleName()); - transformer.transform(entry.getValue()); - } - } - /* move unpack class out of the loader (so the unpacker and loader can both depend on it) */ logger.info("Moving unpack from loader to unpack"); var unpack = new Library(); @@ -113,45 +91,54 @@ public final class Deobfuscator { ClassNamePrefixer.addPrefix(unpacker, "unpacker_"); ClassNamePrefixer.addPrefix(glUnpacker, "unpacker_"); - /* remap all class, method and field names */ - logger.info("Creating remappers"); + /* bundle libraries together into a common classpath */ var runtime = ClassLoader.getPlatformClassLoader(); + var classPath = new ClassPath(runtime, List.of(), List.of(client, loader, signLink, unpack, unpacker)); + var glClassPath = new ClassPath(runtime, List.of(gl), List.of(glClient, glLoader, glSignLink, glUnpack, glUnpacker)); + var unsignedClassPath = new ClassPath(runtime, List.of(), List.of(unsignedClient)); - var libraries = List.of(client, loader, signLink, unpack, unpacker); - var remapper = TypedRemapper.create(new ClassPath(runtime, List.of(), libraries)); + /* deobfuscate */ + logger.info("Transforming client"); + for (var transformer : TRANSFORMERS) { + logger.info("Running transformer {}", transformer.getClass().getSimpleName()); + transformer.transform(classPath); + } + + logger.info("Transforming client_gl"); + for (var transformer : TRANSFORMERS) { + logger.info("Running transformer {}", transformer.getClass().getSimpleName()); + transformer.transform(glClassPath); + } - var glLibraries = List.of(glClient, glLoader, glSignLink, glUnpack, glUnpacker); - var glRemapper = TypedRemapper.create(new ClassPath(runtime, List.of(gl), glLibraries)); + logger.info("Transforming client_unsigned"); + for (var transformer : TRANSFORMERS) { + logger.info("Running transformer {}", transformer.getClass().getSimpleName()); + transformer.transform(unsignedClassPath); + } - var unsignedRemapper = TypedRemapper.create(new ClassPath(runtime, List.of(), List.of(unsignedClient))); + /* remap all class, method and field names */ + logger.info("Creating remappers"); + var remapper = TypedRemapper.create(classPath); + var glRemapper = TypedRemapper.create(glClassPath); + var unsignedRemapper = TypedRemapper.create(unsignedClassPath); /* transform Class.forName() calls */ logger.info("Transforming Class.forName() calls"); Transformer transformer = new ClassForNameTransformer(remapper); - for (var library : libraries) { - transformer.transform(library); - } + transformer.transform(classPath); transformer = new ClassForNameTransformer(glRemapper); - for (var library : glLibraries) { - transformer.transform(library); - } + transformer.transform(glClassPath); transformer = new ClassForNameTransformer(unsignedRemapper); - transformer.transform(unsignedClient); + transformer.transform(unsignedClassPath); /* add @OriginalName annotations */ logger.info("Annotating classes and members with original names"); transformer = new OriginalNameTransformer(); - for (var library : libraries) { - transformer.transform(library); - } - - for (var library : glLibraries) { - transformer.transform(library); - } - - transformer.transform(unsignedClient); + transformer.transform(classPath); + transformer.transform(glClassPath); + transformer.transform(unsignedClassPath); /* write output jars */ logger.info("Writing output jars"); diff --git a/deob/src/main/java/dev/openrs2/deob/remap/ClassNamePrefixer.java b/deob/src/main/java/dev/openrs2/deob/remap/ClassNamePrefixer.java index 9d56218b0c..5d6f4d436e 100644 --- a/deob/src/main/java/dev/openrs2/deob/remap/ClassNamePrefixer.java +++ b/deob/src/main/java/dev/openrs2/deob/remap/ClassNamePrefixer.java @@ -4,6 +4,7 @@ import java.util.HashMap; import dev.openrs2.asm.Library; import dev.openrs2.deob.transform.ClassForNameTransformer; +import org.objectweb.asm.Opcodes; import org.objectweb.asm.commons.ClassRemapper; import org.objectweb.asm.commons.SimpleRemapper; import org.objectweb.asm.tree.ClassNode; @@ -22,7 +23,13 @@ public final class ClassNamePrefixer { var remapper = new SimpleRemapper(mapping); var transformer = new ClassForNameTransformer(remapper); - transformer.transform(library); + for (var clazz : library) { + for (var method : clazz.methods) { + if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) == 0) { + transformer.transformCode(clazz, method); + } + } + } for (var name : mapping.keySet()) { var in = library.remove(name); diff --git a/deob/src/main/java/dev/openrs2/deob/transform/BitShiftTransformer.java b/deob/src/main/java/dev/openrs2/deob/transform/BitShiftTransformer.java index 60146f0bbb..ce0364dcc1 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/BitShiftTransformer.java +++ b/deob/src/main/java/dev/openrs2/deob/transform/BitShiftTransformer.java @@ -4,8 +4,8 @@ import java.util.Set; import dev.openrs2.asm.InsnMatcher; import dev.openrs2.asm.InsnNodeUtils; -import dev.openrs2.asm.Library; import dev.openrs2.asm.Transformer; +import dev.openrs2.asm.classpath.ClassPath; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; @@ -21,7 +21,7 @@ public final class BitShiftTransformer extends Transformer { private int simplified; @Override - public void preTransform(Library library) { + public void preTransform(ClassPath classPath) { simplified = 0; } @@ -42,7 +42,7 @@ public final class BitShiftTransformer extends Transformer { } @Override - public void postTransform(Library library) { + public void postTransform(ClassPath classPath) { logger.info("Simplified {} bit shifts", simplified); } } diff --git a/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.java b/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.java index 619bfba06f..d03546b8eb 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.java +++ b/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.java @@ -6,9 +6,9 @@ import java.util.Map; import java.util.Set; import dev.openrs2.asm.InsnMatcher; -import dev.openrs2.asm.Library; import dev.openrs2.asm.MemberRef; import dev.openrs2.asm.Transformer; +import dev.openrs2.asm.classpath.ClassPath; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; @@ -26,22 +26,24 @@ public final class CounterTransformer extends Transformer { private final Set counters = new HashSet<>(); @Override - public void preTransform(Library library) { + public void preTransform(ClassPath classPath) { counters.clear(); var references = new HashMap(); var resets = new HashMap(); var increments = new HashMap(); - for (var clazz : library) { - for (var method : clazz.methods) { - if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) == 0) { - findCounters(method, references, resets, increments); + for (var library : classPath.getLibraries()) { + for (var clazz : library) { + for (var method : clazz.methods) { + if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) == 0) { + findCounters(method, references, resets, increments); + } } } } - deleteCounters(library, references, resets, increments); + deleteCounters(classPath, references, resets, increments); } private void findCounters(MethodNode method, Map references, Map resets, Map increments) { @@ -68,7 +70,7 @@ public final class CounterTransformer extends Transformer { }); } - private void deleteCounters(Library library, Map references, Map resets, Map increments) { + private void deleteCounters(ClassPath classPath, Map references, Map resets, Map increments) { for (Map.Entry entry : references.entrySet()) { var counter = entry.getKey(); @@ -84,7 +86,7 @@ public final class CounterTransformer extends Transformer { continue; } - ClassNode owner = library.get(counter.getOwner()); + ClassNode owner = classPath.getNode(counter.getOwner()); owner.fields.removeIf(f -> f.name.equals(counter.getName()) && f.desc.equals(counter.getDesc())); counters.add(counter); @@ -112,7 +114,7 @@ public final class CounterTransformer extends Transformer { } @Override - public void postTransform(Library library) { + public void postTransform(ClassPath classPath) { logger.info("Removed {} counters", counters.size()); } } diff --git a/deob/src/main/java/dev/openrs2/deob/transform/ExceptionTracingTransformer.java b/deob/src/main/java/dev/openrs2/deob/transform/ExceptionTracingTransformer.java index 5b285258de..b265c0eb50 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/ExceptionTracingTransformer.java +++ b/deob/src/main/java/dev/openrs2/deob/transform/ExceptionTracingTransformer.java @@ -2,8 +2,8 @@ package dev.openrs2.deob.transform; import dev.openrs2.asm.InsnMatcher; import dev.openrs2.asm.InsnNodeUtils; -import dev.openrs2.asm.Library; import dev.openrs2.asm.Transformer; +import dev.openrs2.asm.classpath.ClassPath; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodNode; import org.slf4j.Logger; @@ -17,7 +17,7 @@ public final class ExceptionTracingTransformer extends Transformer { private int tracingTryCatches; @Override - public void preTransform(Library library) { + public void preTransform(ClassPath classPath) { tracingTryCatches = 0; } @@ -39,7 +39,7 @@ public final class ExceptionTracingTransformer extends Transformer { } @Override - public void postTransform(Library library) { + public void postTransform(ClassPath classPath) { logger.info("Removed {} tracing try/catch blocks", tracingTryCatches); } } diff --git a/deob/src/main/java/dev/openrs2/deob/transform/OpaquePredicateTransformer.java b/deob/src/main/java/dev/openrs2/deob/transform/OpaquePredicateTransformer.java index 186c700ff0..ee293d98e1 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/OpaquePredicateTransformer.java +++ b/deob/src/main/java/dev/openrs2/deob/transform/OpaquePredicateTransformer.java @@ -8,6 +8,7 @@ import dev.openrs2.asm.InsnMatcher; import dev.openrs2.asm.Library; import dev.openrs2.asm.MemberRef; import dev.openrs2.asm.Transformer; +import dev.openrs2.asm.classpath.ClassPath; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; @@ -29,15 +30,17 @@ public final class OpaquePredicateTransformer extends Transformer { private int opaquePredicates, stores; @Override - public void preTransform(Library library) { + public void preTransform(ClassPath classPath) { flowObstructors.clear(); opaquePredicates = 0; stores = 0; - for (var clazz : library) { - for (var method : clazz.methods) { - if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) == 0) { - findFlowObstructors(library, method); + for (var library : classPath.getLibraries()) { + for (var clazz : library) { + for (var method : clazz.methods) { + if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) == 0) { + findFlowObstructors(library, method); + } } } } @@ -113,7 +116,7 @@ public final class OpaquePredicateTransformer extends Transformer { } @Override - public void postTransform(Library library) { + public void postTransform(ClassPath classPath) { logger.info("Removed {} opaque predicates and {} redundant stores", opaquePredicates, stores); } }