From 29105c950111e68e6d9265b87d9ba6116130a2e3 Mon Sep 17 00:00:00 2001 From: Lucwousin Date: Thu, 16 Jul 2020 02:01:33 +0200 Subject: [PATCH] asm: Use a more sensible approach for annotations --- build.gradle.kts | 2 + deobfuscator/deobfuscator.gradle.kts | 4 +- .../main/java/net/runelite/asm/Annotated.java | 17 -- .../java/net/runelite/asm/Annotation.java | 195 ++++++++++++++++++ .../main/java/net/runelite/asm/ClassFile.java | 20 +- .../java/net/runelite/asm/ClassGroup.java | 2 +- .../src/main/java/net/runelite/asm/Field.java | 21 +- .../java/net/runelite/asm/Interfaces.java | 2 +- .../main/java/net/runelite/asm/Method.java | 22 +- .../runelite/asm/attributes/Annotated.java | 51 +++++ .../runelite/asm/attributes/Annotations.java | 91 -------- .../asm/attributes/annotation/Annotation.java | 99 --------- .../attributes/annotation/ArrayElement.java | 42 ---- .../asm/attributes/annotation/Element.java | 91 -------- .../attributes/annotation/SimpleElement.java | 15 -- .../net/runelite/asm/signature/Signature.java | 53 +++-- .../visitors/AnnotationElementVisitor.java | 83 -------- .../asm/visitors/ClassFieldVisitor.java | 8 +- .../asm/visitors/ClassFileVisitor.java | 7 +- .../runelite/asm/visitors/CodeVisitor.java | 8 +- .../src/main/java/net/runelite/deob/Deob.java | 3 - .../net/runelite/deob/DeobAnnotations.java | 105 ++++------ .../runelite/deob/deobfuscators/Order.java | 50 ++--- .../deobfuscators/PacketHandlerOrder.java | 16 +- .../deob/deobfuscators/RenameUnique.java | 34 +-- .../runelite/deob/deobfuscators/Renamer.java | 57 +++-- .../deobfuscators/StaticShouldBeInstance.java | 171 --------------- .../deob/deobfuscators/UnusedParameters.java | 62 +++--- .../deobfuscators/arithmetic/ModArith.java | 2 +- .../constparam/ConstantParameter.java | 26 +-- .../mapping/AnnotationIntegrityChecker.java | 81 ++------ .../mapping/AnnotationMapper.java | 44 ++-- .../mapping/StaticMethodSignatureMapper.java | 2 +- .../packetwrite/PacketWriteDeobfuscator.java | 2 +- .../deob/updater/AnnotationAdder.java | 93 +++------ .../deob/updater/AnnotationCopier.java | 51 ++--- .../deob/updater/AnnotationRenamer.java | 16 +- .../updater/mappingdumper/MappedClass.java | 5 +- .../updater/mappingdumper/MappedField.java | 4 +- .../updater/mappingdumper/MappedMethod.java | 9 +- .../net/runelite/deob/util/NameMappings.java | 8 +- .../asm/annotations/AnnotationTest.java | 25 +-- .../deobfuscators/mapping/MappingDumper.java | 20 +- .../deob/updater/AnnotationCleaner.java | 15 +- .../deob/updater/UpdateMappingsTest.java | 14 +- .../java/net/runelite/osb/HookImporter.java | 60 ++---- .../runelite/runeloader/MappingImporter.java | 50 ++--- .../net/runelite/runesuite/HookImporter.java | 36 ++-- runelite-client/runelite-client.gradle.kts | 2 +- 49 files changed, 625 insertions(+), 1271 deletions(-) delete mode 100644 deobfuscator/src/main/java/net/runelite/asm/Annotated.java create mode 100644 deobfuscator/src/main/java/net/runelite/asm/Annotation.java create mode 100644 deobfuscator/src/main/java/net/runelite/asm/attributes/Annotated.java delete mode 100644 deobfuscator/src/main/java/net/runelite/asm/attributes/Annotations.java delete mode 100644 deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/Annotation.java delete mode 100644 deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/ArrayElement.java delete mode 100644 deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/Element.java delete mode 100644 deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/SimpleElement.java delete mode 100644 deobfuscator/src/main/java/net/runelite/asm/visitors/AnnotationElementVisitor.java delete mode 100644 deobfuscator/src/main/java/net/runelite/deob/deobfuscators/StaticShouldBeInstance.java diff --git a/build.gradle.kts b/build.gradle.kts index 8de8e9feed..0c1eb010fb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -202,6 +202,8 @@ subprojects { } } } + + configurations["compileOnly"].extendsFrom(configurations["annotationProcessor"]) } application { diff --git a/deobfuscator/deobfuscator.gradle.kts b/deobfuscator/deobfuscator.gradle.kts index bf699e9d5a..8ba8ba9ca9 100644 --- a/deobfuscator/deobfuscator.gradle.kts +++ b/deobfuscator/deobfuscator.gradle.kts @@ -35,6 +35,8 @@ dependencies { deobjars(group = "net.runelite.rs", name = "vanilla", version = ProjectVersions.rsversion.toString()) deobjars(project(":runescape-client")) + annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.12") + implementation(group = "org.jetbrains", name = "annotations", version = "19.0.0") implementation(group = "org.ow2.asm", name = "asm", version = "8.0.1") implementation(group = "org.ow2.asm", name = "asm-util", version = "8.0.1") @@ -90,7 +92,7 @@ tasks { filter(ReplaceTokens::class, "tokens" to tokens) filteringCharset = "UTF-8" } - + // TODO: Enable assertions on all 3 register("Downloader.main()") { group = "gamepack" diff --git a/deobfuscator/src/main/java/net/runelite/asm/Annotated.java b/deobfuscator/src/main/java/net/runelite/asm/Annotated.java deleted file mode 100644 index 4645fa23a2..0000000000 --- a/deobfuscator/src/main/java/net/runelite/asm/Annotated.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.runelite.asm; - -import java.util.Iterator; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import org.jetbrains.annotations.NotNull; - -public interface Annotated extends Iterable -{ - Annotations getAnnotations(); - - @NotNull - default Iterator iterator() - { - return getAnnotations().iterator(); - } -} diff --git a/deobfuscator/src/main/java/net/runelite/asm/Annotation.java b/deobfuscator/src/main/java/net/runelite/asm/Annotation.java new file mode 100644 index 0000000000..1797502fbf --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/asm/Annotation.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2020, Lucas + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.asm; + +import java.util.ArrayList; +import java.util.List; +import java.util.TreeMap; +import org.jetbrains.annotations.NotNull; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Note: this class has a natural ordering that is inconsistent with equals. + */ +public class Annotation extends AnnotationVisitor implements Comparable +{ + /** + * Name:Value pairs in this annotation. Uses a tree map to make order reproducible. + * + * Data can be any of the following: + * - Primitive values + * - Strings + * - Class objects + * - Enum constants (not implemented) + * - Arrays of any of the above (use {@link ArrayList} + * - Other Annotations + */ + private final TreeMap data = new TreeMap<>(); + private final Type type; + /** + * Unused for now but here for easy implementation later if anyone wants to + */ + private final boolean visible; + + public Annotation(Type type) + { + this(type, true); + } + + public Annotation(Type type, boolean visible) + { + super(Opcodes.ASM5); + this.type = type; + this.visible = visible; + } + + public Type getType() + { + return type; + } + + public void addElement(String name, Object value) + { + if (data.put(name, value) != null) + throw new IllegalStateException("The annotation already contains a value mapped to " + name); + } + + public void addElement(Object value) + { + addElement("value", value); + } + + public void setElement(String name, Object value) + { + data.put(name, value); + } + + public void setElement(Object value) + { + setElement("value", value); + } + + public Object get(String name) + { + return data.get(name); + } + + public Object getValue() + { + return data.get("value"); + } + + public String getValueString() + { + return (String) getValue(); + } + + public int size() + { + return data.size(); + } + + @Override + public void visit(String name, Object value) + { + data.put(name, value); + } + + @Override + public AnnotationVisitor visitAnnotation(String name, String descriptor) + { + final var annotation = new Annotation(new Type(descriptor)); + data.put(name, annotation); + return annotation; + } + + @Override + public AnnotationVisitor visitArray(String name) + { + final var lst = new ArrayList<>(); + data.put(name, lst); + return new AnnotationVisitor(Opcodes.ASM5) + { + @Override + public void visit(String name, Object value) + { + lst.add(value); + } + @Override + public AnnotationVisitor visitAnnotation(String name, String descriptor) + { + Annotation annotation = new Annotation(new Type(descriptor)); + lst.add(annotation); + return annotation; + } + }; + } + + public void accept(AnnotationVisitor visitor) + { + if (visitor == null) + return; + + for (var entry : data.entrySet()) + accept(visitor, entry.getKey(), entry.getValue()); + + visitor.visitEnd(); + } + + private static void accept(AnnotationVisitor visitor, final String name, final Object value) + { + if (visitor == null) + return; + + if (value instanceof Annotation) + { + Annotation annotation = (Annotation) value; + annotation.accept(visitor.visitAnnotation(name, annotation.getType().toString())); + } + else if (value instanceof List) + { + AnnotationVisitor arr = visitor.visitArray(name); + List arrayValue = (List) value; + + for (Object o : arrayValue) + { + accept(arr, null, o); + } + + arr.visitEnd(); + } + else + { + visitor.visit(name, value); + } + } + + @Override + public int compareTo(@NotNull Annotation that) + { + return this.type.toString().compareTo(that.type.toString()); + } +} diff --git a/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java b/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java index fd2ba5a40a..9014dd73e2 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java +++ b/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java @@ -25,9 +25,12 @@ package net.runelite.asm; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; +import java.util.Map; +import java.util.TreeMap; +import lombok.Getter; +import net.runelite.asm.attributes.Annotated; import net.runelite.asm.pool.Class; import net.runelite.asm.signature.Signature; import static net.runelite.deob.DeobAnnotations.*; @@ -51,14 +54,14 @@ public class ClassFile implements Annotated, Named private final Interfaces interfaces; private final List fields = new ArrayList<>(); private final List methods = new ArrayList<>(); - private final Annotations annotations; + @Getter + private final Map annotations = new TreeMap<>(Comparator.comparing(Type::toString)); public ClassFile(ClassGroup group) { this.group = group; interfaces = new Interfaces(this); - annotations = new Annotations(); } public ClassFile() @@ -99,7 +102,7 @@ public class ClassFile implements Annotated, Named visitor.visit(version, access, name.getName(), null, super_class.getName(), ints); visitor.visitSource(source, null); - for (Annotation annotation : annotations) + for (Annotation annotation : annotations.values()) { annotation.accept(visitor.visitAnnotation(annotation.getType().toString(), true)); } @@ -170,11 +173,6 @@ public class ClassFile implements Annotated, Named methods.remove(method); } - public Annotations getAnnotations() - { - return annotations; - } - public String getName() { return name.getName(); @@ -312,7 +310,7 @@ public class ClassFile implements Annotated, Named for (Method m : methods) { if (m.isStatic() && - name.equals(getObfuscatedName(m.getAnnotations())) && + name.equals(getObfuscatedName(m)) && type.equals(getObfuscatedSignature(m))) { return m; diff --git a/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java b/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java index fabde88742..3b29c295b6 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java +++ b/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java @@ -151,7 +151,7 @@ public class ClassGroup implements Iterable { for (ClassFile cf : classes) { - if (name.equals(getObfuscatedName(cf.getAnnotations()))) + if (name.equals(getObfuscatedName(cf))) { return cf; } diff --git a/deobfuscator/src/main/java/net/runelite/asm/Field.java b/deobfuscator/src/main/java/net/runelite/asm/Field.java index 1a9fd7a776..d02f28c582 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/Field.java +++ b/deobfuscator/src/main/java/net/runelite/asm/Field.java @@ -24,8 +24,11 @@ */ package net.runelite.asm; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; +import java.util.Comparator; +import java.util.Map; +import java.util.TreeMap; +import lombok.Getter; +import net.runelite.asm.attributes.Annotated; import net.runelite.deob.DeobAnnotations; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Opcodes; @@ -43,20 +46,19 @@ public class Field implements Annotated, Named private String name; private Type type; private Object value; // ConstantValue - private final Annotations annotations; + @Getter + private final Map annotations = new TreeMap<>(Comparator.comparing(Type::toString)); public Field(ClassFile classFile, String name, Type type) { this.classFile = classFile; this.name = name; this.type = type; - - this.annotations = new Annotations(); } public void accept(FieldVisitor visitor) { - for (Annotation annotation : annotations.getAnnotations()) + for (Annotation annotation : annotations.values()) { annotation.accept(visitor.visitAnnotation(annotation.getType().toString(), true)); } @@ -150,15 +152,10 @@ public class Field implements Annotated, Named this.value = value; } - public Annotations getAnnotations() - { - return annotations; - } - public net.runelite.asm.pool.Field getPoolField() { return new net.runelite.asm.pool.Field( - new net.runelite.asm.pool.Class(classFile.getName()), + classFile.getPoolClass(), this.getName(), this.getType() ); diff --git a/deobfuscator/src/main/java/net/runelite/asm/Interfaces.java b/deobfuscator/src/main/java/net/runelite/asm/Interfaces.java index 9bc15d5100..180417b3f6 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/Interfaces.java +++ b/deobfuscator/src/main/java/net/runelite/asm/Interfaces.java @@ -98,7 +98,7 @@ public class Interfaces implements Iterable final List names = new ArrayList<>(); for (ClassFile c : getMyInterfaces()) { - String name = DeobAnnotations.getObfuscatedName(c.getAnnotations()); + String name = DeobAnnotations.getObfuscatedName(c); if (name == null) { continue; diff --git a/deobfuscator/src/main/java/net/runelite/asm/Method.java b/deobfuscator/src/main/java/net/runelite/asm/Method.java index b13e98aa3f..1637298dff 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/Method.java +++ b/deobfuscator/src/main/java/net/runelite/asm/Method.java @@ -25,11 +25,14 @@ package net.runelite.asm; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; -import net.runelite.asm.attributes.Annotations; +import java.util.Map; +import java.util.TreeMap; +import lombok.Getter; +import net.runelite.asm.attributes.Annotated; import net.runelite.asm.attributes.Code; import net.runelite.asm.attributes.Exceptions; -import net.runelite.asm.attributes.annotation.Annotation; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.LocalVariable; import net.runelite.asm.attributes.code.Parameter; @@ -55,8 +58,9 @@ public class Method implements Annotated, Named private int accessFlags; private String name; private Signature arguments; - private Exceptions exceptions; - private Annotations annotations; + private final Exceptions exceptions; + @Getter + private final Map annotations = new TreeMap<>(Comparator.comparing(Type::toString)); private List parameters; private Code code; @@ -66,7 +70,6 @@ public class Method implements Annotated, Named this.name = name; this.arguments = signature; exceptions = new Exceptions(); - annotations = new Annotations(); parameters = new ArrayList<>(); } @@ -89,7 +92,7 @@ public class Method implements Annotated, Named visitor.visitParameter(p.getName(), p.getAccess()); } - for (Annotation annotation : annotations.getAnnotations()) + for (Annotation annotation : annotations.values()) { annotation.accept(visitor.visitAnnotation(annotation.getType().toString(), true)); } @@ -277,11 +280,6 @@ public class Method implements Annotated, Named this.code = code; } - public Annotations getAnnotations() - { - return annotations; - } - @SuppressWarnings("unchecked") public List findLVTInstructionsForVariable(int index) { @@ -313,7 +311,7 @@ public class Method implements Annotated, Named public net.runelite.asm.pool.Method getPoolMethod() { return new net.runelite.asm.pool.Method( - new net.runelite.asm.pool.Class(classFile.getName()), + classFile.getPoolClass(), name, arguments ); diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/Annotated.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/Annotated.java new file mode 100644 index 0000000000..edffbfd459 --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/asm/attributes/Annotated.java @@ -0,0 +1,51 @@ +package net.runelite.asm.attributes; + +import java.util.Map; +import net.runelite.asm.Annotation; +import net.runelite.asm.Type; + +/** + * Objects implementing this only have to implement getAnnotations. + */ +public interface Annotated +{ + Map getAnnotations(); + + default Annotation findAnnotation(Type type, boolean createNew) + { + if (createNew) + return getAnnotations().computeIfAbsent(type, Annotation::new); + else + return getAnnotations().get(type); + } + + default Annotation findAnnotation(Type type) + { + return findAnnotation(type, false); + } + + default void addAnnotation(Annotation annotation) + { + if (getAnnotations().put(annotation.getType(), annotation) != null) + throw new IllegalStateException("Annotation with type " + annotation.getType() + " already exists"); + } + + default void addAnnotation(Type type) + { + if (getAnnotations().put(type, new Annotation(type)) != null) + throw new IllegalStateException("Annotation with type " + type + " already exists"); + } + + default void addAnnotation(Type type, Object val) + { + addAnnotation(type, val); + } + + default void addAnnotation(Type type, String key, Object val) + { + final var a = new Annotation(type); + a.setElement(key, val); + if (getAnnotations().put(type, a) != null) + throw new IllegalStateException("Annotation with type " + type + " already exists"); + } +} diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/Annotations.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/Annotations.java deleted file mode 100644 index 6e184a89ec..0000000000 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/Annotations.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.asm.attributes; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import net.runelite.asm.Type; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; -import net.runelite.asm.attributes.annotation.SimpleElement; -import org.jetbrains.annotations.NotNull; - -public class Annotations implements Iterable -{ - private final List annotations = new ArrayList<>(); - - public List getAnnotations() - { - return annotations; - } - - public void addAnnotation(Annotation annotation) - { - annotations.add(annotation); - } - - public void removeAnnotation(Annotation annotation) - { - annotations.remove(annotation); - } - - public void clearAnnotations() - { - annotations.clear(); - } - - public Annotation find(Type type) - { - for (Annotation a : annotations) - if (a.getType().equals(type)) - return a; - return null; - } - - public int size() - { - return annotations.size(); - } - - public Annotation addAnnotation(Type type, String name, Object value) - { - Annotation annotation = new Annotation(type); - addAnnotation(annotation); - - Element element = new SimpleElement(name, value); - annotation.addElement(element); - - return annotation; - } - - @NotNull - @Override - public Iterator iterator() - { - return this.annotations.iterator(); - } -} diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/Annotation.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/Annotation.java deleted file mode 100644 index 6f3a459eb3..0000000000 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/Annotation.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016-2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.asm.attributes.annotation; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import net.runelite.asm.Type; -import org.jetbrains.annotations.NotNull; -import org.objectweb.asm.AnnotationVisitor; - -public class Annotation extends Element> implements Iterable -{ - private final Type type; - - public Annotation(Type type) - { - this.value = new ArrayList<>(); - this.type = type; - } - - public Annotation(String name, Type type) - { - this.value = new ArrayList<>(); - this.name = name; - this.type = type; - } - - public Type getType() - { - return type; - } - - public List getElements() - { - return value; - } - - public Element getElement() - { - return value.get(0); - } - - public void addElement(Element element) - { - value.add(element); - } - - @Override - public final void setValue(List value) - { - throw new UnsupportedOperationException(); - } - - public void accept(AnnotationVisitor visitor) - { - if (visitor == null) - { - return; - } - - for (Element element : this) - { - accept(visitor, element.name, element.value); - } - - visitor.visitEnd(); - } - - @NotNull - @Override - public Iterator iterator() - { - return this.value.iterator(); - } -} diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/ArrayElement.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/ArrayElement.java deleted file mode 100644 index b7e2b7ef84..0000000000 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/ArrayElement.java +++ /dev/null @@ -1,42 +0,0 @@ -package net.runelite.asm.attributes.annotation; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; - -public class ArrayElement extends Element implements Iterable -{ - public ArrayElement(String name) - { - this.name = name; - this.value = new ArrayList<>(); - } - - @SuppressWarnings("unchecked") - public void addValue(Object value) - { - this.value.add(value); - } - - @Override - public final void setValue(List value) - { - throw new UnsupportedOperationException(); - } - - @NotNull - @Override - @SuppressWarnings("unchecked") - public Iterator iterator() - { - return this.value.iterator(); - } - - @SuppressWarnings("unchecked") - public Stream stream() - { - return this.value.stream(); - } -} diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/Element.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/Element.java deleted file mode 100644 index 10b59b5b27..0000000000 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/Element.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.asm.attributes.annotation; - -import java.util.List; -import org.objectweb.asm.AnnotationVisitor; - -public abstract class Element -{ - String name = "value"; - - T value; - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public T getValue() - { - return value; - } - - public void setValue(T value) - { - this.value = value; - } - - public String getString() - { - return value.toString(); - } - - public static void accept(AnnotationVisitor visitor, final String name, final Object value) - { - if (visitor == null) - { - return; - } - - if (value instanceof Annotation) - { - Annotation annotation = (Annotation) value; - annotation.accept(visitor.visitAnnotation(name, annotation.getType().toString())); - } - else if (value instanceof List) - { - AnnotationVisitor arr = visitor.visitArray(name); - List arrayValue = (List) value; - - for (Object o : arrayValue) - { - accept(arr, null, o); - } - - arr.visitEnd(); - } - else - { - visitor.visit(name, value); - } - } -} diff --git a/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/SimpleElement.java b/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/SimpleElement.java deleted file mode 100644 index 52e25e295c..0000000000 --- a/deobfuscator/src/main/java/net/runelite/asm/attributes/annotation/SimpleElement.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.runelite.asm.attributes.annotation; - -public class SimpleElement extends Element -{ - public SimpleElement(Object value) - { - this.value = value; - } - - public SimpleElement(String name, Object value) - { - this.name = name; - this.value = value; - } -} diff --git a/deobfuscator/src/main/java/net/runelite/asm/signature/Signature.java b/deobfuscator/src/main/java/net/runelite/asm/signature/Signature.java index 58b56deb2f..9c346dd36e 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/signature/Signature.java +++ b/deobfuscator/src/main/java/net/runelite/asm/signature/Signature.java @@ -28,20 +28,17 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Objects; -import java.util.regex.Matcher; import java.util.regex.Pattern; import net.runelite.asm.Type; public class Signature { - private static Pattern paramRetPattern = Pattern.compile("\\((.*)\\)(.*)"), - paramsPattern = Pattern.compile("(\\[*(?:B|C|Z|S|I|J|F|D|(?:L[^;]*;)))"); + private static final Pattern RLAPITORSAPI = Pattern.compile("net/runelite/(rs/)?api/(RS)?"); private final List arguments; private final Type rv; - private Signature(List arguments, Type rv) + public Signature(List arguments, Type rv) { this.arguments = new ArrayList<>(arguments); this.rv = rv; @@ -49,23 +46,12 @@ public class Signature public Signature(String str) { - Matcher m = paramRetPattern.matcher(str); - if (!m.find()) - { - throw new IllegalArgumentException("Signature has no arguments"); - } + final int rvStart = str.indexOf(')'); + if (rvStart == -1) + throw new IllegalArgumentException("Signature has no return value!"); - String args = m.group(1), ret = m.group(2); - - m = paramsPattern.matcher(args); - arguments = new ArrayList<>(); - while (m.find()) - { - String arg = m.group(1); - arguments.add(new Type(arg)); - } - - rv = new Type(ret); + rv = new Type(str.substring(rvStart + 1)); + arguments = findArgs(str, new ArrayList<>(), str.indexOf('(') + 1, rvStart); } public Signature(Signature other) @@ -74,6 +60,21 @@ public class Signature rv = other.rv; } + private static List findArgs(final String str, final List ret, final int from, final int to) + { + if (from >= to) return ret; + + int i = from; + while (str.charAt(i) == '[') ++i; + + if (str.charAt(i) == 'L') + i = str.indexOf(';', i); + + ret.add(new Type(str.substring(from, ++i))); + + return findArgs(str, ret, i, to); + } + @Override public boolean equals(Object other) { @@ -82,17 +83,13 @@ public class Signature return false; } - Signature a = (Signature) other; - return arguments.equals(a.arguments) && rv.equals(a.rv); + return this.toString().equals(other.toString()); } @Override public int hashCode() { - int hash = 5; - hash = 97 * hash + Objects.hashCode(this.arguments); - hash = 97 * hash + Objects.hashCode(this.rv); - return hash; + return this.toString().hashCode(); } @Override @@ -176,6 +173,6 @@ public class Signature public Signature rsApiToRsClient() { - return new Signature(this.toString().replaceAll("net/runelite/(rs/)?api/(RS)?", "")); + return new Signature(RLAPITORSAPI.matcher(this.toString()).replaceAll("")); } } diff --git a/deobfuscator/src/main/java/net/runelite/asm/visitors/AnnotationElementVisitor.java b/deobfuscator/src/main/java/net/runelite/asm/visitors/AnnotationElementVisitor.java deleted file mode 100644 index 7bd5811813..0000000000 --- a/deobfuscator/src/main/java/net/runelite/asm/visitors/AnnotationElementVisitor.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2016-2017, Adam - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package net.runelite.asm.visitors; - -import net.runelite.asm.Type; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.ArrayElement; -import net.runelite.asm.attributes.annotation.SimpleElement; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.Opcodes; - -public class AnnotationElementVisitor extends AnnotationVisitor -{ - private final Annotation annotation; - - AnnotationElementVisitor(Annotation annotation) - { - super(Opcodes.ASM5); - - this.annotation = annotation; - } - - @Override - public void visit(String name, Object value) - { - SimpleElement element = new SimpleElement(name, value); - annotation.addElement(element); - } - - @Override - public AnnotationVisitor visitArray(String name) - { - ArrayElement element = new ArrayElement(name); - this.annotation.addElement(element); - return new AnnotationVisitor(Opcodes.ASM5) - { - @Override - public void visit(String name, Object value) - { - element.addValue(value); - } - - @Override - public AnnotationVisitor visitAnnotation(String name, String descriptor) - { - Annotation annotation = new Annotation(name, new Type(descriptor)); - element.addValue(annotation); - return new AnnotationElementVisitor(annotation); - } - }; - } - - @Override - public AnnotationVisitor visitAnnotation(String name, String descriptor) - { - Annotation annotation = new Annotation(name, new Type(descriptor)); - this.annotation.addElement(annotation); - return new AnnotationElementVisitor(annotation); - } -} diff --git a/deobfuscator/src/main/java/net/runelite/asm/visitors/ClassFieldVisitor.java b/deobfuscator/src/main/java/net/runelite/asm/visitors/ClassFieldVisitor.java index c9012b162c..b84c4b1090 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/visitors/ClassFieldVisitor.java +++ b/deobfuscator/src/main/java/net/runelite/asm/visitors/ClassFieldVisitor.java @@ -27,7 +27,7 @@ package net.runelite.asm.visitors; import net.runelite.asm.ClassFile; import net.runelite.asm.Field; import net.runelite.asm.Type; -import net.runelite.asm.attributes.annotation.Annotation; +import net.runelite.asm.Annotation; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Attribute; import org.objectweb.asm.FieldVisitor; @@ -51,9 +51,9 @@ public class ClassFieldVisitor extends FieldVisitor @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - Annotation element = new Annotation(new Type(desc)); - this.field.getAnnotations().addAnnotation(element); - return new AnnotationElementVisitor(element); + Annotation annotation = new Annotation(new Type(desc), visible); + this.field.addAnnotation(annotation); + return annotation; } @Override diff --git a/deobfuscator/src/main/java/net/runelite/asm/visitors/ClassFileVisitor.java b/deobfuscator/src/main/java/net/runelite/asm/visitors/ClassFileVisitor.java index d96ec550b1..a7efe37fb9 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/visitors/ClassFileVisitor.java +++ b/deobfuscator/src/main/java/net/runelite/asm/visitors/ClassFileVisitor.java @@ -27,7 +27,7 @@ package net.runelite.asm.visitors; import net.runelite.asm.ClassFile; import net.runelite.asm.Type; -import net.runelite.asm.attributes.annotation.Annotation; +import net.runelite.asm.Annotation; import net.runelite.asm.signature.Signature; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassVisitor; @@ -71,9 +71,8 @@ public class ClassFileVisitor extends ClassVisitor public AnnotationVisitor visitAnnotation(String desc, boolean visible) { Annotation annotation = new Annotation(new Type(desc)); - classFile.getAnnotations().addAnnotation(annotation); - - return new AnnotationElementVisitor(annotation); + classFile.addAnnotation(annotation); + return annotation; } @Override diff --git a/deobfuscator/src/main/java/net/runelite/asm/visitors/CodeVisitor.java b/deobfuscator/src/main/java/net/runelite/asm/visitors/CodeVisitor.java index 7746cd7a7a..f4846facf2 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/visitors/CodeVisitor.java +++ b/deobfuscator/src/main/java/net/runelite/asm/visitors/CodeVisitor.java @@ -32,7 +32,7 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.Method; import net.runelite.asm.Type; import net.runelite.asm.attributes.Code; -import net.runelite.asm.attributes.annotation.Annotation; +import net.runelite.asm.Annotation; import net.runelite.asm.attributes.code.Exceptions; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.InstructionType; @@ -108,9 +108,9 @@ public class CodeVisitor extends MethodVisitor @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - Annotation element = new Annotation(new Type(desc)); - this.method.getAnnotations().addAnnotation(element); - return new AnnotationElementVisitor(element); + Annotation annotation = new Annotation(new Type(desc), visible); + this.method.addAnnotation(annotation); + return annotation; } @Override diff --git a/deobfuscator/src/main/java/net/runelite/deob/Deob.java b/deobfuscator/src/main/java/net/runelite/deob/Deob.java index 70a5ec7d88..a8e7dc3644 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/Deob.java +++ b/deobfuscator/src/main/java/net/runelite/deob/Deob.java @@ -37,7 +37,6 @@ import net.runelite.deob.deobfuscators.Lvt; import net.runelite.deob.deobfuscators.Order; import net.runelite.deob.deobfuscators.RenameUnique; import net.runelite.deob.deobfuscators.RuntimeExceptions; -import net.runelite.deob.deobfuscators.StaticShouldBeInstance; import net.runelite.deob.deobfuscators.UnreachedCode; import net.runelite.deob.deobfuscators.UnusedClass; import net.runelite.deob.deobfuscators.UnusedFields; @@ -80,8 +79,6 @@ public class Deob ClassGroup group = JarUtil.loadJar(new File(args[0])); - run(group, new StaticShouldBeInstance()); - if (args.length <= 2 || !args[2].equals("rl")) { // remove except RuntimeException diff --git a/deobfuscator/src/main/java/net/runelite/deob/DeobAnnotations.java b/deobfuscator/src/main/java/net/runelite/deob/DeobAnnotations.java index d5e83313da..77e8945f73 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/DeobAnnotations.java +++ b/deobfuscator/src/main/java/net/runelite/deob/DeobAnnotations.java @@ -24,15 +24,15 @@ */ package net.runelite.deob; -import java.util.List; +import javax.annotation.Nullable; +import net.runelite.asm.attributes.Annotated; import net.runelite.asm.ClassFile; import net.runelite.asm.Field; import net.runelite.asm.Method; import net.runelite.asm.Type; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; +import net.runelite.asm.Annotation; import net.runelite.asm.signature.Signature; +import org.jetbrains.annotations.NotNull; public class DeobAnnotations { @@ -45,94 +45,71 @@ public class DeobAnnotations public static Signature getObfuscatedSignature(Method m) { - String str = getAnnotationValue(m.getAnnotations(), OBFUSCATED_SIGNATURE); + String str = getStringValue(m, OBFUSCATED_SIGNATURE); if (str == null) - { return null; - } return new Signature(str); } public static Type getObfuscatedType(Field f) { - String str = getAnnotationValue(f.getAnnotations(), OBFUSCATED_SIGNATURE); + String str = getStringValue(f, OBFUSCATED_SIGNATURE); if (str == null) - { return null; - } return new Type(str); } - public static String getObfuscatedName(Annotations an) + @Nullable + public static String getObfuscatedName(@NotNull Annotated an) { - return getAnnotationValue(an, OBFUSCATED_NAME); + return getStringValue(an, OBFUSCATED_NAME); } - public static String getExportedName(Annotations an) + @Nullable + public static String getExportedName(@NotNull Annotated an) { - return getAnnotationValue(an, EXPORT); + return getStringValue(an, EXPORT); } - public static String getImplements(ClassFile cf) + @Nullable + public static String getImplements(@NotNull ClassFile cf) { - return getAnnotationValue(cf.getAnnotations(), IMPLEMENTS); + return getStringValue(cf, IMPLEMENTS); } - public static Number getObfuscatedGetter(Field field) + @Nullable + public static Number getObfuscatedGetter(@NotNull Field field) { - if (field == null || field.getAnnotations() == null) - { - return null; - } - - Annotation an = field.getAnnotations().find(OBFUSCATED_GETTER); - if (an == null) - { - return null; - } - - return (Number) an.getElement().getValue(); - } - - public static String getDecoder(Method method) - { - if (method == null || method.getAnnotations() == null) - { - return null; - } - - Annotation an = method.getAnnotations().find(OBFUSCATED_SIGNATURE); - if (an == null) - { - return null; - } - - List elements = an.getElements(); - if (elements == null || elements.size() < 2) - { - return null; - } - - return (String) elements.get(1).getValue(); - } - - public static String getAnnotationValue(Annotations an, Type type) - { - if (an == null) - { - return null; - } - - Annotation a = an.find(type); + final var a = field.findAnnotation(OBFUSCATED_GETTER); if (a == null) - { return null; - } - return a.getElement().getString(); + Object v = a.getValue(); + if (v == null) + return null; + + if (field.getType().equals(Type.INT)) + return (Integer) v; + else if (field.getType().equals(Type.LONG)) + return (Long) v; // very long v + throw new IllegalArgumentException("Field with getter but not a long or an int?"); + } + + @Nullable + public static String getDecoder(@NotNull Method method) + { + Annotation a = method.findAnnotation(OBFUSCATED_SIGNATURE); + return a == null ? null : (String) a.get("garbageValue"); + } + + @Nullable + public static String getStringValue(Annotated an, Type type) + { + final var a = an.findAnnotation(type); + return a == null ? null : a.getValueString(); } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/Order.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/Order.java index 093fb705c6..70573d2630 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/Order.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/Order.java @@ -24,7 +24,6 @@ */ package net.runelite.deob.deobfuscators; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,7 +31,7 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; -import net.runelite.asm.attributes.Annotations; +import net.runelite.asm.attributes.Annotated; import net.runelite.asm.execution.Execution; import net.runelite.deob.DeobAnnotations; import net.runelite.deob.Deobfuscator; @@ -64,7 +63,7 @@ public class Order implements Deobfuscator for (int i = 0; i < group.getClasses().size(); i++) { ClassFile cf = group.getClasses().get(i); - String className = DeobAnnotations.getObfuscatedName(cf.getAnnotations()); + String className = DeobAnnotations.getObfuscatedName(cf); nameIndices.put(className, i); } @@ -73,7 +72,7 @@ public class Order implements Deobfuscator for (ClassFile cf : group.getClasses()) { List m = cf.getMethods(); - Collections.sort(m, this::compareMethod); + m.sort(this::compare); sortedMethods += m.size(); @@ -81,7 +80,7 @@ public class Order implements Deobfuscator if (!cf.isEnum()) { List f = cf.getFields(); - Collections.sort(f, this::compareFields); + f.sort(this::compare); sortedFields += f.size(); } @@ -91,47 +90,27 @@ public class Order implements Deobfuscator } // static fields, member fields, clinit, init, methods, static methods - private int compareMethod(Method m1, Method m2) + private int compare(Annotated a, Annotated b) { - int i1 = getType(m1), i2 = getType(m2); + int i1 = getType(a), i2 = getType(b); if (i1 != i2) { return Integer.compare(i1, i2); } - int nameIdx1 = getNameIdx(m1.getAnnotations()); - int nameIdx2 = getNameIdx(m2.getAnnotations()); + int nameIdx1 = getNameIdx(a); + int nameIdx2 = getNameIdx(b); if (nameIdx1 != nameIdx2) { return Integer.compare(nameIdx1, nameIdx2); } - return compareOrder(m1, m2); + return compareOrder(a, b); } - private int compareFields(Field f1, Field f2) - { - int i1 = getType(f1), i2 = getType(f2); - - if (i1 != i2) - { - return Integer.compare(i1, i2); - } - - int nameIdx1 = getNameIdx(f1.getAnnotations()); - int nameIdx2 = getNameIdx(f2.getAnnotations()); - - if (nameIdx1 != nameIdx2) - { - return Integer.compare(nameIdx1, nameIdx2); - } - - return compareOrder(f1, f2); - } - - private int getNameIdx(Annotations annotations) + private int getNameIdx(Annotated annotations) { String name = DeobAnnotations.getObfuscatedName(annotations); @@ -140,6 +119,15 @@ public class Order implements Deobfuscator return nameIdx != null ? nameIdx : -1; } + private int getType(Annotated a) + { + if (a instanceof Method) + return getType((Method) a); + else if (a instanceof Field) + return getType((Field) a); + throw new RuntimeException("kys"); + } + private int getType(Method m) { if (m.getName().equals("")) diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/PacketHandlerOrder.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/PacketHandlerOrder.java index 694c59edf6..56b74051d8 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/PacketHandlerOrder.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/PacketHandlerOrder.java @@ -151,7 +151,7 @@ public class PacketHandlerOrder implements Deobfuscator // check if the invoke is on buffer/packetbuffer classes boolean matches = ii.getMethods().stream() .filter(m -> m.getDescriptor().size() == 0) - .map(method -> method.getClassFile()) + .map(Method::getClassFile) .anyMatch(cf -> cf == bf.getBuffer() || cf == bf.getPacketBuffer()); if (matches) { @@ -269,7 +269,7 @@ public class PacketHandlerOrder implements Deobfuscator logger.warn("Unable to differentiate {} from {}", p1, p2); return 0; }) - .map(s -> s.clone()) + .map(PacketHandler::clone) .collect(Collectors.toList()); assert sortedHandlers.size() == handlers.getHandlers().size(); @@ -277,7 +277,7 @@ public class PacketHandlerOrder implements Deobfuscator for (PacketHandler handler : sortedHandlers) { handler.sortedReads = new ArrayList<>(handler.reads); - Collections.sort(handler.sortedReads, (PacketRead p1, PacketRead p2) -> + handler.sortedReads.sort((PacketRead p1, PacketRead p2) -> { LVTInstruction l1 = (LVTInstruction) p1.getStore(); LVTInstruction l2 = (LVTInstruction) p2.getStore(); @@ -350,7 +350,7 @@ public class PacketHandlerOrder implements Deobfuscator // Find unique methods List methods = unsortedHandlers.stream() - .map(ph -> ph.getMethod()) + .map(PacketHandler::getMethod) .distinct() .collect(Collectors.toList()); @@ -439,10 +439,6 @@ public class PacketHandlerOrder implements Deobfuscator } List follow = follow(instructions, handler.getStart(), afterRead); - if (follow == null) - { - continue; - } for (Instruction i : follow) { @@ -559,11 +555,11 @@ public class PacketHandlerOrder implements Deobfuscator private int compareReads(List r1, List r2) { List t1 = r1.stream() - .map(pr -> pr.getType()) + .map(PacketRead::getType) .sorted(this::compareType) .collect(Collectors.toList()); List t2 = r2.stream() - .map(pr -> pr.getType()) + .map(PacketRead::getType) .sorted(this::compareType) .collect(Collectors.toList()); if (t1.size() != t2.size()) diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/RenameUnique.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/RenameUnique.java index 06c6e905ea..ad792c5570 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/RenameUnique.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/RenameUnique.java @@ -38,50 +38,33 @@ import net.runelite.deob.util.NameMappings; public class RenameUnique implements Deobfuscator { - private Renamer renamer; - private void generateClassNames(NameMappings map, ClassGroup group) { int i = 0; - for (ClassFile cf : group.getClasses()) - { - if (cf.getName().length() > Deob.OBFUSCATED_NAME_MAX_LEN) - { - continue; - } - - map.map(cf.getPoolClass(), "class" + i++); - } + if (cf.getName().length() <= Deob.OBFUSCATED_NAME_MAX_LEN) + map.map(cf.getPoolClass(), "class" + i++); + map.setClasses(i); } private void generateFieldNames(NameMappings map, ClassGroup group) { int i = 0; - for (ClassFile cf : group.getClasses()) for (Field field : cf.getFields()) - { - if (!Deob.isObfuscated(field.getName()) || field.getName().equals(DeobAnnotations.getExportedName(field.getAnnotations()))) - { - continue; - } - - map.map(field.getPoolField(), "field" + i++); - } + if (Deob.isObfuscated(field.getName()) && !field.getName().equals(DeobAnnotations.getExportedName(field))) + map.map(field.getPoolField(), "field" + i++); + map.setFields(i); } private void generateMethodNames(NameMappings map, ClassGroup group) { int i = 0; - for (ClassFile cf : group.getClasses()) for (Method method : cf.getMethods()) { - if (!Deob.isObfuscated(method.getName()) || method.getName().equals(DeobAnnotations.getExportedName(method.getAnnotations()))) - { + if (!Deob.isObfuscated(method.getName()) || method.getName().equals(DeobAnnotations.getExportedName(method))) continue; - } List virtualMethods = VirtualMethods.getVirtualMethods(method); assert !virtualMethods.isEmpty(); @@ -95,6 +78,7 @@ public class RenameUnique implements Deobfuscator for (Method m : virtualMethods) map.map(m.getPoolMethod(), name); } + map.setMethods(i); } @Override @@ -109,7 +93,7 @@ public class RenameUnique implements Deobfuscator this.generateFieldNames(mappings, group); this.generateMethodNames(mappings, group); - renamer = new Renamer(mappings); + Renamer renamer = new Renamer(mappings); renamer.run(group); } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/Renamer.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/Renamer.java index 588b840918..a3c89be27e 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/Renamer.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/Renamer.java @@ -31,9 +31,11 @@ import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Interfaces; import net.runelite.asm.Method; +import net.runelite.asm.Named; import net.runelite.asm.Type; +import net.runelite.asm.attributes.Annotated; import net.runelite.asm.attributes.Code; -import net.runelite.asm.attributes.annotation.Annotation; +import net.runelite.asm.Annotation; import net.runelite.asm.attributes.code.Exceptions; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.LocalVariable; @@ -45,6 +47,8 @@ import net.runelite.deob.Deobfuscator; import net.runelite.deob.util.NameMappings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static net.runelite.deob.DeobAnnotations.OBFUSCATED_NAME; +import static net.runelite.deob.DeobAnnotations.OBFUSCATED_SIGNATURE; public class Renamer implements Deobfuscator { @@ -135,10 +139,10 @@ public class Renamer implements Deobfuscator if (!method.getDescriptor().equals(newSignature)) { //Signature was updated. Annotate it - if (method.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE) == null) + if (method.findAnnotation(OBFUSCATED_SIGNATURE) == null) { //Signature was not previously renamed - method.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE, "signature", method.getDescriptor().toString()); + method.addAnnotation(OBFUSCATED_SIGNATURE, "signature", method.getDescriptor().toString()); } } @@ -156,10 +160,10 @@ public class Renamer implements Deobfuscator { if (field.getType().getInternalName().equals(cf.getName())) { - if (field.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE) == null) + if (field.findAnnotation(OBFUSCATED_SIGNATURE) == null) { //Signature was updated. Annotate it - field.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE, "signature", field.getType().toString()); + field.addAnnotation(OBFUSCATED_SIGNATURE, "signature", field.getType().toString()); } field.setType(Type.getType("L" + name + ";", field.getType().getDimensions())); @@ -167,10 +171,7 @@ public class Renamer implements Deobfuscator } } - if (cf.getAnnotations().find(DeobAnnotations.OBFUSCATED_NAME) == null) - { - cf.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_NAME, "value", cf.getName()); - } + addObfuscatedName(cf); group.renameClass(cf, name); } @@ -178,22 +179,13 @@ public class Renamer implements Deobfuscator private void regeneratePool(ClassGroup group) { for (ClassFile cf : group.getClasses()) - { for (Method m : cf.getMethods()) - { - Code c = m.getCode(); - if (c == null) - { - continue; - } - - c.getInstructions().regeneratePool(); - } - } + if (m.getCode() != null) + m.getCode().getInstructions() + .regeneratePool(); } @Override - @SuppressWarnings("unchecked") public void run(ClassGroup group) { group.buildClassGraph(); @@ -212,12 +204,9 @@ public class Renamer implements Deobfuscator continue; } - if (field.getAnnotations().find(DeobAnnotations.OBFUSCATED_NAME) == null) - { - field.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_NAME, "value", field.getName()); - } + addObfuscatedName(field); - assert DeobAnnotations.getExportedName(field.getAnnotations()) == null || DeobAnnotations.getExportedName(field.getAnnotations()).equals(newName) : "Tried changing field name to something other than the exported name!"; + assert DeobAnnotations.getExportedName(field) == null || DeobAnnotations.getExportedName(field).equals(newName) : "Tried changing field name to something other than the exported name!"; field.setName(newName); ++fields; @@ -233,12 +222,10 @@ public class Renamer implements Deobfuscator String[] newParams = mappings.getP(method.getPoolMethod()); // rename on obfuscated signature - Annotation an = method.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE); + Annotation an = method.findAnnotation(OBFUSCATED_SIGNATURE); if (an != null) { - Signature obfuscatedSig = new Signature(an.getElement().getString()); - Signature updatedSig = renameSignature(obfuscatedSig); - an.getElement().setValue(updatedSig.toString()); + an.setElement(renameSignature(new Signature(an.getValueString())).toString()); } if (newName == null) @@ -279,10 +266,7 @@ public class Renamer implements Deobfuscator ++parameters; } - if (m.getAnnotations().find(DeobAnnotations.OBFUSCATED_NAME) == null) - { - m.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_NAME, "value", m.getName()); - } + addObfuscatedName(m); m.setName(newName); } @@ -339,4 +323,9 @@ public class Renamer implements Deobfuscator } return builder.build(); } + + private static void addObfuscatedName(T object) + { + object.findAnnotation(OBFUSCATED_NAME, true).setElement(object.getName()); + } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/StaticShouldBeInstance.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/StaticShouldBeInstance.java deleted file mode 100644 index 1cae903698..0000000000 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/StaticShouldBeInstance.java +++ /dev/null @@ -1,171 +0,0 @@ -package net.runelite.deob.deobfuscators; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import net.runelite.asm.ClassFile; -import net.runelite.asm.ClassGroup; -import net.runelite.asm.Field; -import net.runelite.asm.Type; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.Code; -import net.runelite.asm.attributes.code.Instruction; -import net.runelite.asm.attributes.code.Instructions; -import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction; -import net.runelite.asm.attributes.code.instructions.InvokeStatic; -import net.runelite.asm.attributes.code.instructions.InvokeVirtual; -import net.runelite.asm.pool.Method; -import net.runelite.asm.signature.Signature; -import net.runelite.deob.Deobfuscator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class StaticShouldBeInstance implements Deobfuscator -{ - private static final Logger logger = LoggerFactory.getLogger(StaticShouldBeInstance.class); - private static Map methods = new HashMap<>(); - - public void run(ClassGroup group) - { - int replacedCalls = 0; - int removedInstructions = 0; - int removedMethods = 0; - int removedAnnotations = 0; - List obfuscatedMethods = new ArrayList<>(); - - for (ClassFile cf : group.getClasses()) - { - // Remove unused annotations - Annotations a = cf.getAnnotations(); - removedAnnotations += a.getAnnotations().size(); - a.clearAnnotations(); - - Type type = new Type('L' + cf.getClassName() + ';'); - obfuscatedMethods.clear(); - - for (net.runelite.asm.Method m : cf.getMethods()) - { - // Remove unused annotations - a = m.getAnnotations(); - removedAnnotations += a.size(); - a.clearAnnotations(); - - if (m.isStatic() && m.getCode() != null) - { - if (checkIfObf(m, type, cf)) - { - removedMethods++; - obfuscatedMethods.add(m); - } - } - } - - - for (net.runelite.asm.Method m : obfuscatedMethods) - { - Signature sig = m.getDescriptor(); - Signature.Builder builder = new Signature.Builder(); - builder.setReturnType(sig.getReturnValue()); - if (sig.getArguments().size() > 1) - { - builder.addArguments(sig.getArguments().subList(1, sig.getArguments().size())); - } - - Signature toFind = builder.build(); - - net.runelite.asm.Method notStatic = cf.findMethod(m.getName(), toFind); - net.runelite.asm.pool.Method oldPool = m.getPoolMethod(); - cf.removeMethod(notStatic); - - m.setDescriptor(toFind); - m.setStatic(false); - Code c = m.getCode(); - Instructions ins = c.getInstructions(); - int startLength = ins.getInstructions().size(); - ListIterator it = ins.getInstructions().listIterator(); - assert it.hasNext(); - Instruction i = it.next(); - while (!(i instanceof ReturnInstruction)) - { - it.remove(); - i = it.next(); - } - it.remove(); - net.runelite.asm.pool.Method newPool = m.getPoolMethod(); - - methods.put(oldPool, newPool); - - removedInstructions += startLength - ins.getInstructions().size(); - } - - for (Field fi : cf.getFields()) - { - a = fi.getAnnotations(); - if (a.find(new Type("Ljavax/inject/Inject;")) == null) - { - removedAnnotations += a.size(); - a.clearAnnotations(); - } - else - { - logger.info("Class {}, field {} has inject", cf.getClassName(), fi.getName()); - } - } - } - - for (ClassFile cf : group.getClasses()) - { - for (net.runelite.asm.Method m : cf.getMethods()) - { - if (m.getCode() == null) - { - continue; - } - - Instructions ins = m.getCode().getInstructions(); - List instructions = ins.getInstructions(); - for (int i1 = 0, instructionsSize = instructions.size(); i1 < instructionsSize; i1++) - { - Instruction i = instructions.get(i1); - if (!(i instanceof InvokeStatic)) - { - continue; - } - - if (methods.containsKey(((InvokeStatic) i).getMethod())) - { - InvokeVirtual invoke = new InvokeVirtual(ins, methods.get(((InvokeStatic) i).getMethod())); - ins.replace(i, invoke); - replacedCalls++; - } - } - } - } - - logger.info("Made {} methods not static, removed {} instructions, replaced {} invokes, and removed {} annotations", removedMethods, removedInstructions, replacedCalls, removedAnnotations); - } - - private static boolean checkIfObf(net.runelite.asm.Method m, Type type, ClassFile cf) - { - Signature sig = m.getDescriptor(); - if (sig.getArguments().size() < 1 || !sig.getTypeOfArg(0).equals(type)) - { - return false; - } - - Signature.Builder builder = new Signature.Builder(); - builder.setReturnType(sig.getReturnValue()); - if (sig.getArguments().size() > 1) - { - builder.addArguments(sig.getArguments().subList(1, sig.getArguments().size())); - } - - Signature toFind = builder.build(); - - net.runelite.asm.Method notStatic = cf.findMethod(m.getName(), toFind); - - return notStatic != null; - } -} diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/UnusedParameters.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/UnusedParameters.java index ed9f086bc5..2881d8414d 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/UnusedParameters.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/UnusedParameters.java @@ -97,22 +97,22 @@ public class UnusedParameters implements Deobfuscator private boolean shouldRemove(Method m, int parameter) { - Signature obSig = DeobAnnotations.getObfuscatedSignature(m); - if (obSig == null) - { + final var a = m.findAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE); + if (a == null) return false; - } + final var str = a.get("signature"); - return parameter + 1 == obSig.size(); + return parameter + 1 == new Signature((String) str).size(); } private int processUnused(Execution execution, ClassGroup group) { int count = 0; - for (List m : unused.keySet()) + for (Map.Entry, Collection> entry : unused.entrySet()) { - Collection u = unused.get(m); + List m = entry.getKey(); + Collection u = entry.getValue(); int offset = m.size() == 1 && m.get(0).isStatic() ? 0 : 1; @@ -188,7 +188,7 @@ public class UnusedParameters implements Deobfuscator } } - List l = new ArrayList<>(list); + List l = new ArrayList<>(list != null ? list : new ArrayList<>()); // i know Collections.sort(l); Collections.reverse(l); return l; @@ -218,7 +218,7 @@ public class UnusedParameters implements Deobfuscator InvokeInstruction ii = (InvokeInstruction) i; - if (!ii.getMethods().stream().anyMatch(me -> methods.contains(me))) + if (ii.getMethods().stream().noneMatch(methods::contains)) { continue; } @@ -227,20 +227,17 @@ public class UnusedParameters implements Deobfuscator Collection ics = invokes.get(i); assert ics != null; - if (ics != null) + for (InstructionContext ins : ics) { - for (InstructionContext ins : ics) + int pops = signature.size() - paramIndex - 1; // index from top of stack of parameter. 0 is the last parameter + + StackContext sctx = ins.getPops().get(pops); + if (sctx.getPushed().getInstruction().getInstructions() == null) { - int pops = signature.size() - paramIndex - 1; // index from top of stack of parameter. 0 is the last parameter - - StackContext sctx = ins.getPops().get(pops); - if (sctx.getPushed().getInstruction().getInstructions() == null) - { - continue; - } - - ins.removeStack(pops); // remove parameter from stack + continue; } + + ins.removeStack(pops); // remove parameter from stack } } } @@ -286,25 +283,20 @@ public class UnusedParameters implements Deobfuscator public void run(ClassGroup group) { int i; - int pnum = 1; - do - { - group.buildClassGraph(); - invokes.clear(); - this.buildUnused(group); + group.buildClassGraph(); - Execution execution = new Execution(group); - execution.addExecutionVisitor(ictx -> visit(ictx)); - execution.populateInitialMethods(); - execution.run(); + invokes.clear(); + this.buildUnused(group); - i = this.processUnused(execution, group); + Execution execution = new Execution(group); + execution.addExecutionVisitor(this::visit); + execution.populateInitialMethods(); + execution.run(); - count += i; - break; - } - while (i > 0); + i = this.processUnused(execution, group); + + count += i; logger.info("Removed {} unused parameters", count); } diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java index f9d99a380e..17e9b8c974 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/arithmetic/ModArith.java @@ -783,7 +783,7 @@ public class ModArith implements Deobfuscator String ename = pair.getType() == Long.class ? "longValue" : "intValue"; - f.getAnnotations().addAnnotation(DeobAnnotations.OBFUSCATED_GETTER, ename, pair.getter); + f.addAnnotation(DeobAnnotations.OBFUSCATED_GETTER, ename, pair.getter); } } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/constparam/ConstantParameter.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/constparam/ConstantParameter.java index b2a0c369b3..3e2d8d7205 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/constparam/ConstantParameter.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/constparam/ConstantParameter.java @@ -34,10 +34,7 @@ import java.util.List; import java.util.Map; import net.runelite.asm.ClassGroup; import net.runelite.asm.Method; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; -import net.runelite.asm.attributes.annotation.SimpleElement; +import net.runelite.asm.Annotation; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.InstructionType; import net.runelite.asm.attributes.code.Instructions; @@ -62,8 +59,8 @@ public class ConstantParameter implements Deobfuscator { private static final Logger logger = LoggerFactory.getLogger(ConstantParameter.class); - private Map parameters = new HashMap<>(); - private Multimap mparams = HashMultimap.create(); + private final Map parameters = new HashMap<>(); + private final Multimap mparams = HashMultimap.create(); private void checkMethodsAreConsistent(List methods) { @@ -436,23 +433,14 @@ public class ConstantParameter implements Deobfuscator { Object value = parameter.values.get(0); - Annotations annotations = m.getAnnotations(); - - Annotation obfuscatedSignature = annotations.find(DeobAnnotations.OBFUSCATED_SIGNATURE); - if (obfuscatedSignature != null && obfuscatedSignature.getElements().size() == 2) + Annotation obfuscatedSignature = m.findAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE, true); + if (obfuscatedSignature.size() == 2) { // already annotated continue; } - - if (obfuscatedSignature == null) - { - obfuscatedSignature = annotations.addAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE, "signature", m.getDescriptor().toString()); - } - - // Add garbage value - Element element = new SimpleElement("garbageValue", value.toString()); - obfuscatedSignature.addElement(element); + obfuscatedSignature.setElement("signature", m.getDescriptor().toString()); + obfuscatedSignature.setElement("garbageValue", value); } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationIntegrityChecker.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationIntegrityChecker.java index c837f178ea..c86b66e34e 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationIntegrityChecker.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationIntegrityChecker.java @@ -30,8 +30,6 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; import net.runelite.deob.DeobAnnotations; import net.runelite.mapping.Import; import net.runelite.rs.api.RSClient; @@ -65,11 +63,6 @@ public class AnnotationIntegrityChecker return errors; } - public int getWarnings() - { - return warnings; - } - public void run() { for (ClassFile cf : one.getClasses()) @@ -97,11 +90,11 @@ public class AnnotationIntegrityChecker if (f1.isStatic()) { - f2 = findExportedFieldStatic(two, DeobAnnotations.getExportedName(f1.getAnnotations())); + f2 = findExportedFieldStatic(two, DeobAnnotations.getExportedName(f1)); } else { - f2 = findExportedField(other, DeobAnnotations.getExportedName(f1.getAnnotations())); + f2 = findExportedField(other, DeobAnnotations.getExportedName(f1)); } if (f2 == null) @@ -110,7 +103,7 @@ public class AnnotationIntegrityChecker { logger.error("Missing IMPORTED field on {} named {}", other, - DeobAnnotations.getExportedName(f1.getAnnotations())); + DeobAnnotations.getExportedName(f1)); ++errors; } @@ -118,7 +111,7 @@ public class AnnotationIntegrityChecker { logger.warn("Missing exported field on {} named {}", other, - DeobAnnotations.getExportedName(f1.getAnnotations())); + DeobAnnotations.getExportedName(f1)); ++warnings; } @@ -143,11 +136,11 @@ public class AnnotationIntegrityChecker if (m1.isStatic()) { - m2 = findExportedMethodStatic(two, DeobAnnotations.getExportedName(m1.getAnnotations())); + m2 = findExportedMethodStatic(two, DeobAnnotations.getExportedName(m1)); } else { - m2 = findExportedMethod(other, DeobAnnotations.getExportedName(m1.getAnnotations())); + m2 = findExportedMethod(other, DeobAnnotations.getExportedName(m1)); } if (m2 == null) @@ -156,7 +149,7 @@ public class AnnotationIntegrityChecker { logger.error("Missing IMPORTED method on {} named {} ({})", other, - DeobAnnotations.getExportedName(m1.getAnnotations()), + DeobAnnotations.getExportedName(m1), m1); ++errors; @@ -165,7 +158,7 @@ public class AnnotationIntegrityChecker { logger.warn("Missing exported method on {} named {} ({})", other, - DeobAnnotations.getExportedName(m1.getAnnotations()), + DeobAnnotations.getExportedName(m1), m1); ++warnings; @@ -173,36 +166,6 @@ public class AnnotationIntegrityChecker } } } - - checkAnnotationCounts(); - } - - private void checkAnnotationCounts() - { - for (ClassFile cf : two.getClasses()) - { - for (Field f : cf.getFields()) - { - int num = this.getNumberOfExports(f.getAnnotations()); - - if (num > 1) - { - logger.warn("Field {} has more than 1 export", f); - ++errors; - } - } - - for (Method m : cf.getMethods()) - { - int num = this.getNumberOfExports(m.getAnnotations()); - - if (num > 1) - { - logger.warn("Method {} has more than 1 export", m); - ++errors; - } - } - } } /** @@ -212,7 +175,6 @@ public class AnnotationIntegrityChecker * @param cf Class file field/method is on * @param name Exported name of field/method * @param isStatic Whether or not field/method is static - * @return */ private boolean isImported(ClassFile cf, String name, boolean isStatic) { @@ -259,7 +221,7 @@ public class AnnotationIntegrityChecker List list = new ArrayList<>(); for (Field f : clazz.getFields()) { - if (DeobAnnotations.getExportedName(f.getAnnotations()) != null) + if (DeobAnnotations.getExportedName(f) != null) { list.add(f); } @@ -272,7 +234,7 @@ public class AnnotationIntegrityChecker List list = new ArrayList<>(); for (Method m : clazz.getMethods()) { - if (DeobAnnotations.getExportedName(m.getAnnotations()) != null) + if (DeobAnnotations.getExportedName(m) != null) { list.add(m); } @@ -280,26 +242,11 @@ public class AnnotationIntegrityChecker return list; } - private int getNumberOfExports(Annotations an) - { - int count = 0; - - for (Annotation a : an.getAnnotations()) - { - if (a.getType().equals(DeobAnnotations.EXPORT)) - { - ++count; - } - } - - return count; - } - private Field findExportedField(ClassFile clazz, String name) { for (Field f : getExportedFields(clazz)) { - if (DeobAnnotations.getExportedName(f.getAnnotations()).equals(name)) + if (name.equals(DeobAnnotations.getExportedName(f))) { return f; } @@ -315,7 +262,7 @@ public class AnnotationIntegrityChecker { if (f.isStatic()) { - if (name.equals(DeobAnnotations.getExportedName(f.getAnnotations()))) + if (name.equals(DeobAnnotations.getExportedName(f))) { return f; } @@ -333,7 +280,7 @@ public class AnnotationIntegrityChecker { if (m.isStatic()) { - if (name.equals(DeobAnnotations.getExportedName(m.getAnnotations()))) + if (name.equals(DeobAnnotations.getExportedName(m))) { return m; } @@ -347,7 +294,7 @@ public class AnnotationIntegrityChecker { for (Method m : getExportedMethods(clazz)) { - if (DeobAnnotations.getExportedName(m.getAnnotations()).equals(name)) + if (name.equals(DeobAnnotations.getExportedName(m))) { return m; } diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationMapper.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationMapper.java index bd60ec165e..7cbe4c9862 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationMapper.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/AnnotationMapper.java @@ -29,10 +29,8 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; -import net.runelite.asm.attributes.annotation.SimpleElement; +import net.runelite.asm.Annotation; +import net.runelite.asm.attributes.Annotated; import net.runelite.deob.DeobAnnotations; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,11 +67,11 @@ public class AnnotationMapper { int count = 0; - if (hasCopyableAnnotation(from.getAnnotations())) + if (hasCopyableAnnotation(from)) { if (to != null) { - count += copyAnnotations(from.getAnnotations(), to.getAnnotations()); + count += copyAnnotations(from, to); } else { @@ -83,57 +81,49 @@ public class AnnotationMapper for (Field f : from.getFields()) { - if (!hasCopyableAnnotation(f.getAnnotations())) + if (!hasCopyableAnnotation(f)) continue; Field other = (Field) mapping.get(f); if (other == null) { - logger.warn("Unable to map annotated field {} named {}", f, DeobAnnotations.getExportedName(f.getAnnotations())); + logger.warn("Unable to map annotated field {} named {}", f, DeobAnnotations.getExportedName(f)); continue; } - count += copyAnnotations(f.getAnnotations(), other.getAnnotations()); + count += copyAnnotations(f, other); } for (Method m : from.getMethods()) { - if (!hasCopyableAnnotation(m.getAnnotations())) + if (!hasCopyableAnnotation(m)) continue; Method other = (Method) mapping.get(m); if (other == null) { - logger.warn("Unable to map annotated method {} named {}", m, DeobAnnotations.getExportedName(m.getAnnotations())); + logger.warn("Unable to map annotated method {} named {}", m, DeobAnnotations.getExportedName(m)); continue; } - count += copyAnnotations(m.getAnnotations(), other.getAnnotations()); + count += copyAnnotations(m, other); } return count; } - private int copyAnnotations(Annotations from, Annotations to) + private int copyAnnotations(Annotated from, Annotated to) { int count = 0; if (from.getAnnotations() == null) return count; - for (Annotation a : from.getAnnotations()) + for (Annotation a : from.getAnnotations().values()) { if (isCopyable(a)) { - Annotation annotation = new Annotation(a.getType()); - to.addAnnotation(annotation); - - for (Element e : a.getElements()) - { - Element element = new SimpleElement(e.getName(), e.getValue()); - annotation.addElement(element); - } - + to.addAnnotation(a.getType(), a); ++count; } } @@ -141,13 +131,9 @@ public class AnnotationMapper return count; } - private boolean hasCopyableAnnotation(Annotations a) + private boolean hasCopyableAnnotation(Annotated a) { - for (Annotation an : a.getAnnotations()) - if (isCopyable(an)) - return true; - - return false; + return a.findAnnotation(DeobAnnotations.EXPORT) != null || a.findAnnotation(DeobAnnotations.IMPLEMENTS) != null; } private boolean isCopyable(Annotation a) diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/StaticMethodSignatureMapper.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/StaticMethodSignatureMapper.java index 9f2a55df26..4ec9aaec8e 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/StaticMethodSignatureMapper.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/mapping/StaticMethodSignatureMapper.java @@ -36,7 +36,7 @@ import net.runelite.asm.signature.Signature; public class StaticMethodSignatureMapper { - private Multimap map = LinkedHashMultimap.create(); + private final Multimap map = LinkedHashMultimap.create(); private List getStaticMethods(ClassGroup group) { diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/packetwrite/PacketWriteDeobfuscator.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/packetwrite/PacketWriteDeobfuscator.java index 2f7deecfe3..0cbd411952 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/packetwrite/PacketWriteDeobfuscator.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/packetwrite/PacketWriteDeobfuscator.java @@ -33,7 +33,6 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Type; import net.runelite.asm.attributes.code.Instruction; -import static net.runelite.asm.attributes.code.InstructionType.INVOKEVIRTUAL; import net.runelite.asm.attributes.code.Instructions; import net.runelite.asm.attributes.code.Label; import net.runelite.asm.attributes.code.instruction.types.InvokeInstruction; @@ -55,6 +54,7 @@ import net.runelite.deob.Deobfuscator; import net.runelite.deob.c2s.RWOpcodeFinder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static net.runelite.asm.attributes.code.InstructionType.INVOKEVIRTUAL; public class PacketWriteDeobfuscator implements Deobfuscator { diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationAdder.java b/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationAdder.java index d2c3d62034..3d5463bdd1 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationAdder.java +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationAdder.java @@ -5,10 +5,8 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; -import net.runelite.asm.attributes.annotation.SimpleElement; +import net.runelite.asm.Named; +import net.runelite.asm.attributes.Annotated; import net.runelite.deob.Deob; import net.runelite.deob.DeobAnnotations; import org.slf4j.Logger; @@ -24,7 +22,6 @@ public class AnnotationAdder private final ClassGroup group; private final Logger log = LoggerFactory.getLogger(AnnotationAdder.class); - @SuppressWarnings("unchecked") public void run() { int impl = 0; @@ -46,83 +43,43 @@ public class AnnotationAdder // Still error here cause I don't wanna call classes dumb shit assert implementingName.equals(c.getClassName()) : c + " implements " + implementingName + " but is called " + c.getClassName(); } - else + else if (!Deob.isObfuscated(c.getClassName())) { - if (!Deob.isObfuscated(c.getClassName())) - { - Annotations an = c.getAnnotations(); - - Annotation implAn = new Annotation(DeobAnnotations.IMPLEMENTS); - - Element value = new SimpleElement(c.getClassName()); - - implAn.addElement(value); - an.addAnnotation(implAn); - impl++; - } + c.addAnnotation(DeobAnnotations.IMPLEMENTS, c.getClassName()); + impl++; } for (Field f : c.getFields()) { - Annotations an = f.getAnnotations(); - - String fieldName = f.getName(); - String exportedName = DeobAnnotations.getExportedName(an); - - if (exportedName == null && Deob.isObfuscated(fieldName) || fieldName.equals(DeobAnnotations.getObfuscatedName(an)) || DeobAnnotations.getObfuscatedName(an) == null) - { - continue; - } - - if (!fieldName.equals(exportedName)) - { - log.info("Changed export from {} to {}", exportedName, fieldName); - Annotation a = an.find(DeobAnnotations.EXPORT); - if (a == null) - { - a = new Annotation(DeobAnnotations.EXPORT); - - Element value = new SimpleElement(fieldName); - a.addElement(value); - an.addAnnotation(a); - - } - a.getElement().setValue(fieldName); + if (addExport(f)) field++; - } } for (Method m : c.getMethods()) { - Annotations an = m.getAnnotations(); - - String methodName = m.getName(); - String exportedName = DeobAnnotations.getExportedName(an); - - if (exportedName == null && Deob.isObfuscated(methodName) || methodName.equals(DeobAnnotations.getObfuscatedName(an)) || DeobAnnotations.getObfuscatedName(an) == null) - { - continue; - } - - if (!methodName.equals(exportedName)) - { - log.info("Changed export from {} to {}", exportedName, methodName); - Annotation a = an.find(DeobAnnotations.EXPORT); - if (a == null) - { - a = new Annotation(DeobAnnotations.EXPORT); - - Element value = new SimpleElement(methodName); - a.addElement(value); - an.addAnnotation(a); - - } - a.getElement().setValue(methodName); + if (addExport(m)) meth++; - } } } log.info("Changed {} classes, {} methods, {} fields", impl, meth, field); } + + private boolean addExport(T m) + { + String methodName = m.getName(); + String exportedName = DeobAnnotations.getExportedName(m); + + if (exportedName == null && Deob.isObfuscated(methodName) + || methodName.equals(DeobAnnotations.getObfuscatedName(m)) + || DeobAnnotations.getObfuscatedName(m) == null + || methodName.equals(exportedName)) + { + return false; + } + + log.info("Changed export from {} to {}", exportedName, methodName); + m.findAnnotation(DeobAnnotations.EXPORT, true).setElement(methodName); + return true; + } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationCopier.java b/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationCopier.java index 5d495b9029..857610b271 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationCopier.java +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationCopier.java @@ -26,26 +26,26 @@ package net.runelite.deob.updater; import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; import net.runelite.asm.Type; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; -import net.runelite.asm.attributes.annotation.SimpleElement; +import net.runelite.asm.Annotation; +import net.runelite.asm.attributes.Annotated; public class AnnotationCopier { private final ClassGroup group1, group2; - private final Type[] types; + private final Set types; public AnnotationCopier(ClassGroup group1, ClassGroup group2, Type... types) { this.group1 = group1; this.group2 = group2; - this.types = types; + this.types = new HashSet<>(Arrays.asList(types)); } public void copy() @@ -56,63 +56,46 @@ public class AnnotationCopier assert cf2 != null; - copy(cf1.getAnnotations(), cf2.getAnnotations()); + copy(cf1, cf2); for (Field f : cf1.getFields()) { Field f2 = cf2.findField(f.getName(), f.getType()); - assert f2 != null || f.getAnnotations() == null; + assert f2 != null || f.getAnnotations().isEmpty(); if (f2 == null) continue; - copy(f.getAnnotations(), f2.getAnnotations()); + copy(f, f2); } for (Method m : cf1.getMethods()) { Method m2 = cf2.findMethod(m.getName(), m.getDescriptor()); - assert m2 != null || m.getAnnotations() == null; + assert m2 != null || m == null; if (m2 == null) continue; - copy(m.getAnnotations(), m2.getAnnotations()); + copy(m, m2); } } } - private void copy(Annotations an, Annotations an2) + private void copy(Annotated an, Annotated an2) { - for (Annotation a : an2.getAnnotations()) + for (Annotation a : an.getAnnotations().values()) { - if (isType(a.getType())) - { - an2.removeAnnotation(a); - } - } - - for (Annotation a : an.getAnnotations()) - { - if (!isType(a.getType())) - continue; - - Annotation a2 = new Annotation(a.getType()); - - for (Element element : a.getElements()) - { - Element element2 = new SimpleElement(element.getName(), element.getValue()); - a2.addElement(element2); - } - - an2.addAnnotation(a2); + final var t = a.getType(); + if (isType(t)) + an2.getAnnotations().replace(t, a); } } private boolean isType(Type type) { - return Arrays.asList(types).contains(type); + return types.contains(type); } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationRenamer.java b/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationRenamer.java index da920899bc..263a850fa9 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationRenamer.java +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/AnnotationRenamer.java @@ -29,8 +29,8 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; +import net.runelite.asm.Annotation; +import net.runelite.asm.attributes.Annotated; import net.runelite.deob.DeobAnnotations; import net.runelite.deob.deobfuscators.Renamer; import net.runelite.deob.util.NameMappings; @@ -58,20 +58,20 @@ public class AnnotationRenamer for (ClassFile cf : group.getClasses()) { - String name = getImplements(cf.getAnnotations()); + String name = getImplements(cf); if (name != null) mappings.map(cf.getPoolClass(), name); for (Field f : cf.getFields()) { - name = DeobAnnotations.getExportedName(f.getAnnotations()); + name = DeobAnnotations.getExportedName(f); if (name != null) mappings.map(f.getPoolField(), name); } for (Method m : cf.getMethods()) { - name = DeobAnnotations.getExportedName(m.getAnnotations()); + name = DeobAnnotations.getExportedName(m); if (name != null) mappings.map(m.getPoolMethod(), name); } @@ -80,9 +80,9 @@ public class AnnotationRenamer return mappings; } - private String getImplements(Annotations annotations) + private String getImplements(Annotated cf) { - Annotation an = annotations.find(DeobAnnotations.IMPLEMENTS); - return an != null ? an.getElement().getString() : null; + Annotation an = cf.findAnnotation(DeobAnnotations.IMPLEMENTS); + return an == null ? null : an.getValueString(); } } diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedClass.java b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedClass.java index 9a0a6e7511..97dfc60d1c 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedClass.java +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedClass.java @@ -27,7 +27,7 @@ public class MappedClass implementingName = DeobAnnotations.getImplements(c); - obfuscatedName = DeobAnnotations.getObfuscatedName(c.getAnnotations()); + obfuscatedName = DeobAnnotations.getObfuscatedName(c); if (obfuscatedName == null) { obfuscatedName = c.getName(); @@ -36,7 +36,7 @@ public class MappedClass ClassFile parent = c.getParent(); if (parent != null) { - superClass = DeobAnnotations.getObfuscatedName(parent.getAnnotations()); + superClass = DeobAnnotations.getObfuscatedName(parent); } access = c.getAccess(); @@ -44,7 +44,6 @@ public class MappedClass interfaces = c.getInterfaces() .getMyInterfaces() .stream() - .map(ClassFile::getAnnotations) .map(DeobAnnotations::getObfuscatedName) .collect(Collectors.toList()); diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedField.java b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedField.java index dc2b7a7242..ba4ae28f54 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedField.java +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedField.java @@ -26,11 +26,11 @@ public class MappedField { MappingDumper.putMap(f.getPoolField(), this); - exportedName = DeobAnnotations.getExportedName(f.getAnnotations()); + exportedName = DeobAnnotations.getExportedName(f); owner = MappingDumper.getMap(f.getClassFile()).obfuscatedName; - obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations()); + obfuscatedName = DeobAnnotations.getObfuscatedName(f); if (obfuscatedName == null) { obfuscatedName = f.getName(); diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedMethod.java b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedMethod.java index 8131ecd1f6..f2eb549770 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedMethod.java +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/mappingdumper/MappedMethod.java @@ -4,6 +4,7 @@ import com.google.gson.annotations.SerializedName; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import net.runelite.asm.Method; import net.runelite.asm.attributes.Code; @@ -37,11 +38,11 @@ public class MappedMethod public MappedMethod visitMethod(final Method m, final MappingDump dump) { MappingDumper.putMap(m.getPoolMethod(), this); - exportedName = DeobAnnotations.getExportedName(m.getAnnotations()); + exportedName = DeobAnnotations.getExportedName(m); owner = MappingDumper.getMap(m.getClassFile()).obfuscatedName; - obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); + obfuscatedName = DeobAnnotations.getObfuscatedName(m); if (obfuscatedName == null) { obfuscatedName = m.getName(); @@ -94,8 +95,8 @@ public class MappedMethod { Method mme = met.get(0); k = new net.runelite.asm.pool.Method( - new Class(DeobAnnotations.getObfuscatedName(mme.getClassFile().getAnnotations())), - DeobAnnotations.getObfuscatedName(mme.getAnnotations()), + new Class(Objects.requireNonNull(DeobAnnotations.getObfuscatedName(mme.getClassFile()))), + DeobAnnotations.getObfuscatedName(mme), mme.getObfuscatedSignature() != null ? mme.getObfuscatedSignature() : mme.getDescriptor() ); } diff --git a/deobfuscator/src/main/java/net/runelite/deob/util/NameMappings.java b/deobfuscator/src/main/java/net/runelite/deob/util/NameMappings.java index 36c1b52c92..b1dea2b93b 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/util/NameMappings.java +++ b/deobfuscator/src/main/java/net/runelite/deob/util/NameMappings.java @@ -27,6 +27,8 @@ package net.runelite.deob.util; import java.util.HashMap; import java.util.Map; +import lombok.Getter; +import lombok.Setter; import net.runelite.asm.pool.Class; import net.runelite.asm.pool.Field; import net.runelite.asm.pool.Method; @@ -36,7 +38,11 @@ public class NameMappings private final Map map = new HashMap<>(); private final Map paramMap = new HashMap<>(); - + + @Getter + @Setter + private int fields, methods, classes; + public void map(Class cf, String name) { map.put(cf, name); diff --git a/deobfuscator/src/test/java/net/runelite/asm/annotations/AnnotationTest.java b/deobfuscator/src/test/java/net/runelite/asm/annotations/AnnotationTest.java index 642dbf076f..8967d2319f 100644 --- a/deobfuscator/src/test/java/net/runelite/asm/annotations/AnnotationTest.java +++ b/deobfuscator/src/test/java/net/runelite/asm/annotations/AnnotationTest.java @@ -27,16 +27,11 @@ package net.runelite.asm.annotations; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.List; -import java.util.Optional; import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.ClassUtil; import net.runelite.asm.Method; import net.runelite.asm.Type; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; import net.runelite.deob.util.JarUtil; import org.junit.Assert; import org.junit.Test; @@ -62,20 +57,14 @@ public class AnnotationTest Method method = cf.getMethods().get(1); Assert.assertEquals("method1", method.getName()); - Annotations annotations = method.getAnnotations(); - Assert.assertNotNull(annotations); + var annotation = method.findAnnotation(new Type("Lnet/runelite/asm/annotations/MyAnnotation;")); + Assert.assertNotNull(annotation); - Optional annotation = annotations.getAnnotations().stream().filter(a -> a.getType().equals(new Type("Lnet/runelite/asm/annotations/MyAnnotation;"))).findFirst(); - Assert.assertTrue(annotation.isPresent()); + Assert.assertEquals(1, annotation.size()); - Annotation an = annotation.get(); - List elements = an.getElements(); - - Assert.assertEquals(1, elements.size()); - - Element element = elements.get(0); - - Assert.assertEquals("value", element.getName()); - Assert.assertEquals("method1", element.getValue()); + Object element = annotation.getValue(); + Object also = annotation.get("value"); + Assert.assertEquals(also, element); + Assert.assertEquals("method1", element); } } diff --git a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/MappingDumper.java b/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/MappingDumper.java index 53481982c5..97a496a983 100644 --- a/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/MappingDumper.java +++ b/deobfuscator/src/test/java/net/runelite/deob/deobfuscators/mapping/MappingDumper.java @@ -82,7 +82,7 @@ public class MappingDumper for (ClassFile cf : group.getClasses()) { String implName = cf.getName(); - String className = DeobAnnotations.getObfuscatedName(cf.getAnnotations()); + String className = DeobAnnotations.getObfuscatedName(cf); if (implName != null) { @@ -92,7 +92,7 @@ public class MappingDumper for (Field f : cf.getFields()) { - String exportName = DeobAnnotations.getExportedName(f.getAnnotations()); + String exportName = DeobAnnotations.getExportedName(f); if (exportName == null) { @@ -101,7 +101,7 @@ public class MappingDumper ++fields; - String fieldName = DeobAnnotations.getObfuscatedName(f.getAnnotations()); + String fieldName = DeobAnnotations.getObfuscatedName(f); Type type = f.getType(); Number getter = DeobAnnotations.getObfuscatedGetter(f); @@ -171,7 +171,7 @@ public class MappingDumper for (Method m : cf.getMethods()) { - String exportName = DeobAnnotations.getExportedName(m.getAnnotations()); + String exportName = DeobAnnotations.getExportedName(m); if (exportName == null) { @@ -180,7 +180,7 @@ public class MappingDumper methods++; - String methodName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); + String methodName = DeobAnnotations.getObfuscatedName(m); Signature signature = DeobAnnotations.getObfuscatedSignature(m); String garbageValue = DeobAnnotations.getDecoder(m); @@ -329,18 +329,18 @@ public class MappingDumper for (ClassFile cf : group.getClasses()) { String implName = DeobAnnotations.getImplements(cf); - String className = DeobAnnotations.getObfuscatedName(cf.getAnnotations()); + String className = DeobAnnotations.getObfuscatedName(cf); for (Field f : cf.getFields()) { - String exportName = DeobAnnotations.getExportedName(f.getAnnotations()); + String exportName = DeobAnnotations.getExportedName(f); if (exportName == null) { continue; } - String fieldName = DeobAnnotations.getObfuscatedName(f.getAnnotations()); + String fieldName = DeobAnnotations.getObfuscatedName(f); Type obfType = DeobAnnotations.getObfuscatedType(f); Number getter = DeobAnnotations.getObfuscatedGetter(f); @@ -361,14 +361,14 @@ public class MappingDumper for (Method m : cf.getMethods()) { - String exportName = DeobAnnotations.getExportedName(m.getAnnotations()); + String exportName = DeobAnnotations.getExportedName(m); if (exportName == null) { continue; } - String methodName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); + String methodName = DeobAnnotations.getObfuscatedName(m); Signature obfSignature = DeobAnnotations.getObfuscatedSignature(m); String predicate = DeobAnnotations.getDecoder(m); diff --git a/deobfuscator/src/test/java/net/runelite/deob/updater/AnnotationCleaner.java b/deobfuscator/src/test/java/net/runelite/deob/updater/AnnotationCleaner.java index 97c82e6734..0f7b3eaf01 100644 --- a/deobfuscator/src/test/java/net/runelite/deob/updater/AnnotationCleaner.java +++ b/deobfuscator/src/test/java/net/runelite/deob/updater/AnnotationCleaner.java @@ -8,7 +8,6 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; -import net.runelite.asm.attributes.Annotations; import net.runelite.deob.Deob; import net.runelite.deob.DeobAnnotations; import net.runelite.deob.DeobTestProperties; @@ -58,14 +57,12 @@ public class AnnotationCleaner for (Field f : c.getFields()) { - Annotations an = f.getAnnotations(); - String fieldName = f.getName(); - String exportedName = DeobAnnotations.getExportedName(an); + String exportedName = DeobAnnotations.getExportedName(f); if (exportedName == null) { - if (!Deob.isObfuscated(fieldName) && DeobAnnotations.getObfuscatedName(an) != null) + if (!Deob.isObfuscated(fieldName) && DeobAnnotations.getObfuscatedName(f) != null) { missing.add("Export: (field) " + className + '.' + fieldName + " == missing"); } @@ -78,14 +75,12 @@ public class AnnotationCleaner for (Method m : c.getMethods()) { - Annotations an = m.getAnnotations(); - String methodName = m.getName(); - String exportedName = DeobAnnotations.getExportedName(an); + String exportedName = DeobAnnotations.getExportedName(m); if (exportedName == null) { - if (!Deob.isObfuscated(methodName) && DeobAnnotations.getObfuscatedName(an) != null) + if (!Deob.isObfuscated(methodName) && DeobAnnotations.getObfuscatedName(m) != null) { missing.add("Export: (method) " + className + '.' + methodName + " == missing"); } @@ -124,7 +119,7 @@ public class AnnotationCleaner JarUtil.saveJar(group, new File("C:/Users/Lucas/Desktop/niec.jar")); } - private class OhNoException extends Exception + private static class OhNoException extends Exception { private OhNoException() { diff --git a/deobfuscator/src/test/java/net/runelite/deob/updater/UpdateMappingsTest.java b/deobfuscator/src/test/java/net/runelite/deob/updater/UpdateMappingsTest.java index bb34282e22..eea6cea7ab 100644 --- a/deobfuscator/src/test/java/net/runelite/deob/updater/UpdateMappingsTest.java +++ b/deobfuscator/src/test/java/net/runelite/deob/updater/UpdateMappingsTest.java @@ -105,16 +105,16 @@ public class UpdateMappingsTest { for (ClassFile cf : group.getClasses()) { - cf.getAnnotations().clearAnnotations(); + cf.getAnnotations().clear(); for (Field f : cf.getFields()) { - f.getAnnotations().clearAnnotations(); + f.getAnnotations().clear(); } for (Method m : cf.getMethods()) { - m.getAnnotations().clearAnnotations(); + m.getAnnotations().clear(); } } } @@ -136,8 +136,8 @@ public class UpdateMappingsTest assert otherf != null : "unable to find " + f; - String name = DeobAnnotations.getExportedName(f.getAnnotations()); - String otherName = DeobAnnotations.getExportedName(otherf.getAnnotations()); + String name = DeobAnnotations.getExportedName(f); + String otherName = DeobAnnotations.getExportedName(otherf); Assert.assertEquals(name + " <-> " + otherName, name, otherName); } @@ -148,8 +148,8 @@ public class UpdateMappingsTest assert otherm != null : "unable to find " + m; - String name = DeobAnnotations.getExportedName(m.getAnnotations()); - String otherName = DeobAnnotations.getExportedName(otherm.getAnnotations()); + String name = DeobAnnotations.getExportedName(m); + String otherName = DeobAnnotations.getExportedName(otherm); Assert.assertEquals(name + " <-> " + otherName, name, otherName); } diff --git a/deobfuscator/src/test/java/net/runelite/osb/HookImporter.java b/deobfuscator/src/test/java/net/runelite/osb/HookImporter.java index ac178bfa7b..5475b69558 100644 --- a/deobfuscator/src/test/java/net/runelite/osb/HookImporter.java +++ b/deobfuscator/src/test/java/net/runelite/osb/HookImporter.java @@ -36,10 +36,9 @@ import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; import net.runelite.asm.Type; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; +import net.runelite.asm.attributes.Annotated; import net.runelite.asm.signature.Signature; +import net.runelite.deob.DeobAnnotations; import net.runelite.deob.util.JarUtil; import net.runelite.osb.inject.ClassHook; import net.runelite.osb.inject.FieldHook; @@ -88,17 +87,17 @@ public class HookImporter { int classes = 0, fields = 0, methods = 0, callbacks = 0; - for (String deobfuscatedClassName : hooks.keySet()) + for (Map.Entry entry : hooks.entrySet()) { - ClassHook ch = hooks.get(deobfuscatedClassName); + ClassHook ch = entry.getValue(); ClassFile cf = this.findClassWithObfuscatedName(ch.getClazz()); assert cf != null; - String implementsName = getAnnotation(cf.getAnnotations(), IMPLEMENTS); + String implementsName = getAnnotation(cf, IMPLEMENTS); if (implementsName.isEmpty()) { - cf.getAnnotations().addAnnotation(IMPLEMENTS, "value", deobfuscatedClassName); + cf.addAnnotation(IMPLEMENTS, entry.getKey()); ++classes; } @@ -127,10 +126,10 @@ public class HookImporter assert f != null; - String exportedName = getAnnotation(f.getAnnotations(), EXPORT); + String exportedName = getAnnotation(f, EXPORT); if (exportedName.isEmpty()) { - f.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedFieldName); + f.addAnnotation(EXPORT, deobfuscatedFieldName); ++fields; } } @@ -160,10 +159,10 @@ public class HookImporter assert m != null; - String exportedName = getAnnotation(m.getAnnotations(), EXPORT); + String exportedName = getAnnotation(m, EXPORT); if (exportedName.isEmpty()) { - m.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedMethodName); + m.addAnnotation(EXPORT, deobfuscatedMethodName); ++methods; } } @@ -193,10 +192,10 @@ public class HookImporter assert m != null; - String exportedName = getAnnotation(m.getAnnotations(), EXPORT); + String exportedName = getAnnotation(m, EXPORT); if (exportedName.isEmpty()) { - m.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedMethodName); + m.addAnnotation(EXPORT, deobfuscatedMethodName); ++callbacks; } } @@ -214,8 +213,7 @@ public class HookImporter return c; } - Annotations an = c.getAnnotations(); - if (getAnnotation(an, OBFUSCATED_NAME).equals(name)) + if (getAnnotation(c, OBFUSCATED_NAME).equals(name)) { return c; } @@ -227,8 +225,7 @@ public class HookImporter { for (Field f : c.getFields()) { - Annotations an = f.getAnnotations(); - if (getAnnotation(an, OBFUSCATED_NAME).equals(name)) + if (name.equals(DeobAnnotations.getObfuscatedName(f))) { return f; } @@ -242,8 +239,7 @@ public class HookImporter for (Method m : c.getMethods()) { - Annotations an = m.getAnnotations(); - if (getAnnotation(an, OBFUSCATED_NAME).equals(name)) + if (getAnnotation(m, OBFUSCATED_NAME).equals(name)) { Signature methodSig = getObfuscatedMethodSignature(m); @@ -261,30 +257,15 @@ public class HookImporter return null; } - private String getAnnotation(Annotations an, Type type) + private String getAnnotation(Annotated an, Type type) { - if (an == null) - { - return ""; - } - - for (Annotation a : an.getAnnotations()) - { - if (a.getType().equals(type)) - { - for (Element e : a.getElements()) - { - return (String) e.getValue(); - } - } - } - - return ""; + final var s = DeobAnnotations.getStringValue(an, type); + return s == null ? "" : s; } private Signature getObfuscatedMethodSignature(Method method) { - String sig = getAnnotation(method.getAnnotations(), OBFUSCATED_SIGNATURE); + String sig = getAnnotation(method, OBFUSCATED_SIGNATURE); if (!sig.isEmpty()) { return toObSignature(new Signature(sig)); // if it is annoted, use that @@ -310,8 +291,7 @@ public class HookImporter ClassFile cf = group.findClass(t.getInternalName()); assert cf != null; - Annotations an = cf.getAnnotations(); - String obfuscatedName = an.find(OBFUSCATED_NAME).getElement().getString(); + String obfuscatedName = (String) cf.findAnnotation(OBFUSCATED_NAME).getValue(); return Type.getType("L" + obfuscatedName + ";", t.getDimensions()); } diff --git a/deobfuscator/src/test/java/net/runelite/runeloader/MappingImporter.java b/deobfuscator/src/test/java/net/runelite/runeloader/MappingImporter.java index 6e8cbd8c72..62c23e3651 100644 --- a/deobfuscator/src/test/java/net/runelite/runeloader/MappingImporter.java +++ b/deobfuscator/src/test/java/net/runelite/runeloader/MappingImporter.java @@ -30,9 +30,9 @@ import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Type; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; +import net.runelite.asm.Annotation; +import net.runelite.asm.attributes.Annotated; +import net.runelite.deob.DeobAnnotations; import net.runelite.deob.util.JarUtil; import net.runelite.runeloader.inject.AddInterfaceInstruction; import net.runelite.runeloader.inject.GetterInjectInstruction; @@ -73,29 +73,13 @@ public class MappingImporter JarUtil.saveJar(group, OUT); } - private boolean hasObfuscatedName(Annotations an, String name) + private boolean hasObfuscatedName(Annotated an, String name) { if (an == null) { return false; } - - for (Annotation a : an.getAnnotations()) - { - if (a.getType().equals(OBFUSCATED_NAME)) - { - for (Element e : a.getElements()) - { - String str = (String) e.getValue(); - if (str.equals(name)) - { - return true; - } - } - } - } - - return false; + return name.equals(DeobAnnotations.getStringValue(an, OBFUSCATED_NAME)); } private ClassFile findClassWithObfuscatedName(String name) @@ -107,8 +91,7 @@ public class MappingImporter return c; } - Annotations an = c.getAnnotations(); - if (this.hasObfuscatedName(an, name)) + if (this.hasObfuscatedName(c, name)) { return c; } @@ -120,8 +103,7 @@ public class MappingImporter { for (Field f : c.getFields()) { - Annotations an = f.getAnnotations(); - if (this.hasObfuscatedName(an, name)) + if (this.hasObfuscatedName(f, name)) { return f; } @@ -131,7 +113,7 @@ public class MappingImporter @Test @Ignore - public void makeMappings() throws IOException + public void makeMappings() { InjectionModscript mod = Injection.load(MappingImporter.class.getResourceAsStream(RL_INJECTION)); int fields = 0, classes = 0; @@ -154,12 +136,10 @@ public class MappingImporter String attrName = gii.getGetterName(); attrName = Utils.toExportedName(attrName); - Annotations an = f.getAnnotations(); - - Annotation a = an.find(EXPORT); + Annotation a = f.findAnnotation(EXPORT); if (a != null) { - String exportedName = a.getElement().getString(); + String exportedName = a.getValueString(); if (!attrName.equals(exportedName)) { @@ -168,7 +148,7 @@ public class MappingImporter } else { - an.addAnnotation(EXPORT, "value", attrName); + f.addAnnotation(EXPORT, attrName); logger.info("Exporting field " + f + " with name " + attrName); ++fields; @@ -184,12 +164,10 @@ public class MappingImporter iface = iface.replace("com/runeloader/api/bridge/os/accessor/", ""); - Annotations an = cf.getAnnotations(); - - Annotation a = an.find(IMPLEMENTS); + Annotation a = cf.findAnnotation(IMPLEMENTS); if (a != null) { - String implementsName = a.getElement().getString(); + String implementsName = a.getValueString(); if (!iface.equals(implementsName)) { @@ -198,7 +176,7 @@ public class MappingImporter } else { - an.addAnnotation(IMPLEMENTS, "value", iface); + cf.addAnnotation(IMPLEMENTS, iface); logger.info("Exporting class " + cf.getName() + " with name " + iface); ++classes; diff --git a/deobfuscator/src/test/java/net/runelite/runesuite/HookImporter.java b/deobfuscator/src/test/java/net/runelite/runesuite/HookImporter.java index d72e2ea46c..0c661b69df 100644 --- a/deobfuscator/src/test/java/net/runelite/runesuite/HookImporter.java +++ b/deobfuscator/src/test/java/net/runelite/runesuite/HookImporter.java @@ -36,9 +36,7 @@ import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; import net.runelite.asm.Type; -import net.runelite.asm.attributes.Annotations; -import net.runelite.asm.attributes.annotation.Annotation; -import net.runelite.asm.attributes.annotation.Element; +import net.runelite.asm.attributes.Annotated; import net.runelite.asm.attributes.code.LocalVariable; import net.runelite.asm.attributes.code.Parameter; import net.runelite.asm.signature.Signature; @@ -107,11 +105,11 @@ public class HookImporter assert cf != null; - String implementsName = getAnnotation(cf.getAnnotations(), IMPLEMENTS); + String implementsName = getAnnotation(cf, IMPLEMENTS); if (implementsName.isEmpty()) { String deobfuscatedClassName = hc.clazz; - cf.getAnnotations().addAnnotation(IMPLEMENTS, "value", deobfuscatedClassName); + cf.addAnnotation(IMPLEMENTS, deobfuscatedClassName); mappings.map(cf.getPoolClass(), deobfuscatedClassName); ++classes; } @@ -138,7 +136,7 @@ public class HookImporter continue; } - String exportedName = getAnnotation(f.getAnnotations(), EXPORT); + String exportedName = getAnnotation(f, EXPORT); if (exportedName.isEmpty()) { String deobfuscatedFieldName = fh.field; @@ -150,7 +148,7 @@ public class HookImporter continue; } - f.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedFieldName); + f.addAnnotation(EXPORT, deobfuscatedFieldName); mappings.map(f.getPoolField(), deobfuscatedFieldName); ++fields; } @@ -219,7 +217,7 @@ public class HookImporter List virtualMethods = VirtualMethods.getVirtualMethods(m); for (Method method : virtualMethods) { - String exportedName = getAnnotation(method.getAnnotations(), EXPORT); + String exportedName = getAnnotation(method, EXPORT); if (!exportedName.isEmpty()) { if (!exportedName.equals(hm.method)) @@ -231,7 +229,7 @@ public class HookImporter } String deobfuscatedMethodName = hm.method; - m.getAnnotations().addAnnotation(EXPORT, "value", deobfuscatedMethodName); + m.addAnnotation(EXPORT, deobfuscatedMethodName); mappings.map(m.getPoolMethod(), deobfuscatedMethodName); ++methods; } @@ -252,8 +250,7 @@ public class HookImporter return c; } - Annotations an = c.getAnnotations(); - if (getAnnotation(an, OBFUSCATED_NAME).equals(name)) + if (getAnnotation(c, OBFUSCATED_NAME).equals(name)) { return c; } @@ -265,8 +262,7 @@ public class HookImporter { for (Field f : c.getFields()) { - Annotations an = f.getAnnotations(); - if (getAnnotation(an, OBFUSCATED_NAME).equals(name)) + if (getAnnotation(f, OBFUSCATED_NAME).equals(name)) { return f; } @@ -280,8 +276,7 @@ public class HookImporter for (Method m : c.getMethods()) { - Annotations an = m.getAnnotations(); - if (m.getName().equals(name) || getAnnotation(an, OBFUSCATED_NAME).equals(name)) + if (m.getName().equals(name) || getAnnotation(m, OBFUSCATED_NAME).equals(name)) { Signature methodSig = getObfuscatedMethodSignature(m); @@ -294,15 +289,12 @@ public class HookImporter return null; } - private String getAnnotation(Annotations an, Type type) + private String getAnnotation(Annotated an, Type type) { - Annotation a = an.find(type); + final var a = an.findAnnotation(type); if (a != null) { - for (Element e : a.getElements()) - { - return (String) e.getValue(); - } + return a.getValueString(); } return ""; @@ -310,7 +302,7 @@ public class HookImporter private Signature getObfuscatedMethodSignature(Method method) { - String sig = getAnnotation(method.getAnnotations(), OBFUSCATED_SIGNATURE); + String sig = getAnnotation(method, OBFUSCATED_SIGNATURE); if (sig.isEmpty()) { return method.getDescriptor(); diff --git a/runelite-client/runelite-client.gradle.kts b/runelite-client/runelite-client.gradle.kts index b31a24ce21..6de03245ea 100644 --- a/runelite-client/runelite-client.gradle.kts +++ b/runelite-client/runelite-client.gradle.kts @@ -155,7 +155,7 @@ tasks { register("RuneLite.main()") { group = "openosrs" - classpath = project.sourceSets.main.get().runtimeClasspath + classpath = sourceSets["main"].runtimeClasspath enableAssertions = true main = "net.runelite.client.RuneLite" }