From 2367ba7ae46f6869d58362f0cb7e863ee0e224c7 Mon Sep 17 00:00:00 2001 From: Graham Date: Mon, 29 Jul 2019 21:01:04 +0100 Subject: [PATCH] Preserve original class and member names with @OriginalName --- .../java/dev/openrs2/asm/Transformer.java | 17 ++++- deob/pom.xml | 5 ++ .../java/dev/openrs2/deob/Deobfuscator.java | 26 ++++++-- .../transform/ClassForNameTransformer.java | 2 +- .../transform/OpaquePredicateTransformer.java | 2 +- .../transform/OriginalNameTransformer.java | 63 +++++++++++++++++++ 6 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 deob/src/main/java/dev/openrs2/deob/transform/OriginalNameTransformer.java diff --git a/asm/src/main/java/dev/openrs2/asm/Transformer.java b/asm/src/main/java/dev/openrs2/asm/Transformer.java index 177a8123..18106c3f 100644 --- a/asm/src/main/java/dev/openrs2/asm/Transformer.java +++ b/asm/src/main/java/dev/openrs2/asm/Transformer.java @@ -2,6 +2,7 @@ package dev.openrs2.asm; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.MethodNode; public abstract class Transformer { @@ -11,9 +12,15 @@ public abstract class Transformer { for (var clazz : library) { transformClass(clazz); + for (var field : clazz.fields) { + transformField(clazz, field); + } + for (var method : clazz.methods) { + transformMethod(clazz, method); + if ((method.access & (Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT)) == 0) { - transformMethod(clazz, method); + transformCode(clazz, method); } } } @@ -29,10 +36,18 @@ public abstract class Transformer { /* empty */ } + public void transformField(ClassNode clazz, FieldNode field) { + /* empty */ + } + public void transformMethod(ClassNode clazz, MethodNode method) { /* empty */ } + public void transformCode(ClassNode clazz, MethodNode method) { + /* empty */ + } + public void postTransform(Library library) { /* empty */ } diff --git a/deob/pom.xml b/deob/pom.xml index 97f2c811..0ceac8af 100644 --- a/deob/pom.xml +++ b/deob/pom.xml @@ -19,6 +19,11 @@ openrs2-asm ${project.version} + + dev.openrs2 + openrs2-deob-annotations + ${project.version} + ch.qos.logback logback-classic diff --git a/deob/src/main/java/dev/openrs2/deob/Deobfuscator.java b/deob/src/main/java/dev/openrs2/deob/Deobfuscator.java index 4606bb04..c29bfc07 100644 --- a/deob/src/main/java/dev/openrs2/deob/Deobfuscator.java +++ b/deob/src/main/java/dev/openrs2/deob/Deobfuscator.java @@ -15,6 +15,7 @@ import dev.openrs2.deob.path.ClassPath; import dev.openrs2.deob.path.TypedRemapper; import dev.openrs2.deob.transform.ClassForNameTransformer; import dev.openrs2.deob.transform.OpaquePredicateTransformer; +import dev.openrs2.deob.transform.OriginalNameTransformer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -118,18 +119,33 @@ public final class Deobfuscator { /* transform Class.forName() calls */ logger.info("Transforming Class.forName() calls"); - var transformer = new ClassForNameTransformer(remapper); + Transformer transformer = new ClassForNameTransformer(remapper); for (var library : libraries) { transformer.transform(library); } - var glTransformer = new ClassForNameTransformer(glRemapper); + transformer = new ClassForNameTransformer(glRemapper); for (var library : glLibraries) { - glTransformer.transform(library); + transformer.transform(library); + } + + transformer = new ClassForNameTransformer(unsignedRemapper); + transformer.transform(unsignedClient); + + /* add @OriginalName annotations */ + logger.info("Annotating classes and members with original names"); + transformer = new OriginalNameTransformer(remapper); + for (var library : libraries) { + transformer.transform(library); + } + + transformer = new OriginalNameTransformer(glRemapper); + for (var library : glLibraries) { + transformer.transform(library); } - var unsignedTransformer = new ClassForNameTransformer(unsignedRemapper); - unsignedTransformer.transform(unsignedClient); + transformer = new OriginalNameTransformer(unsignedRemapper); + transformer.transform(unsignedClient); /* write output jars */ logger.info("Writing output jars"); diff --git a/deob/src/main/java/dev/openrs2/deob/transform/ClassForNameTransformer.java b/deob/src/main/java/dev/openrs2/deob/transform/ClassForNameTransformer.java index b0ede053..01ab20d6 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/ClassForNameTransformer.java +++ b/deob/src/main/java/dev/openrs2/deob/transform/ClassForNameTransformer.java @@ -33,7 +33,7 @@ public final class ClassForNameTransformer extends Transformer { } @Override - public void transformMethod(ClassNode clazz, MethodNode method) { + public void transformCode(ClassNode clazz, MethodNode method) { INVOKE_MATCHER.match(method).filter(ClassForNameTransformer::isClassForName).forEach(match -> { var ldc = (LdcInsnNode) match.get(0); ldc.cst = remapper.map((String) ldc.cst); 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 378e800f..186c700f 100644 --- a/deob/src/main/java/dev/openrs2/deob/transform/OpaquePredicateTransformer.java +++ b/deob/src/main/java/dev/openrs2/deob/transform/OpaquePredicateTransformer.java @@ -88,7 +88,7 @@ public final class OpaquePredicateTransformer extends Transformer { } @Override - public void transformMethod(ClassNode clazz, MethodNode method) { + public void transformCode(ClassNode clazz, MethodNode method) { /* find and fix opaque predicates */ OPAQUE_PREDICATE_MATCHER.match(method).filter(match -> isOpaquePredicate(method, match)).forEach(match -> { var branch = (JumpInsnNode) match.get(1); diff --git a/deob/src/main/java/dev/openrs2/deob/transform/OriginalNameTransformer.java b/deob/src/main/java/dev/openrs2/deob/transform/OriginalNameTransformer.java new file mode 100644 index 00000000..13058220 --- /dev/null +++ b/deob/src/main/java/dev/openrs2/deob/transform/OriginalNameTransformer.java @@ -0,0 +1,63 @@ +package dev.openrs2.deob.transform; + +import java.util.ArrayList; +import java.util.List; + +import dev.openrs2.asm.Transformer; +import dev.openrs2.deob.annotations.OriginalName; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.Remapper; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodNode; + +public final class OriginalNameTransformer extends Transformer { + private static AnnotationNode createOriginalNameAnnotation(String name) { + var annotation = new AnnotationNode(Type.getDescriptor(OriginalName.class)); + annotation.values = List.of("value", name); + return annotation; + } + + private final Remapper remapper; + + public OriginalNameTransformer(Remapper remapper) { + this.remapper = remapper; + } + + @Override + public void transformClass(ClassNode clazz) { + if (clazz.name.equals(remapper.map(clazz.name))) { + return; + } + + if (clazz.invisibleAnnotations == null) { + clazz.invisibleAnnotations = new ArrayList<>(); + } + clazz.invisibleAnnotations.add(createOriginalNameAnnotation(clazz.name)); + } + + @Override + public void transformField(ClassNode clazz, FieldNode field) { + if (field.name.equals(remapper.mapFieldName(clazz.name, field.name, field.desc))) { + return; + } + + if (field.invisibleAnnotations == null) { + field.invisibleAnnotations = new ArrayList<>(); + } + field.invisibleAnnotations.add(createOriginalNameAnnotation(field.name)); + } + + @Override + public void transformMethod(ClassNode clazz, MethodNode method) { + if (method.name.equals(remapper.mapMethodName(clazz.name, method.name, method.desc))) { + return; + } + + if (method.invisibleAnnotations == null) { + method.invisibleAnnotations = new ArrayList<>(); + } + method.invisibleAnnotations.add(createOriginalNameAnnotation(method.name)); + } +}