asm: Use a more sensible approach for annotations
This commit is contained in:
@@ -202,6 +202,8 @@ subprojects {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurations["compileOnly"].extendsFrom(configurations["annotationProcessor"])
|
||||
}
|
||||
|
||||
application {
|
||||
|
||||
@@ -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<JavaExec>("Downloader.main()") {
|
||||
group = "gamepack"
|
||||
|
||||
|
||||
@@ -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<Annotation>
|
||||
{
|
||||
Annotations getAnnotations();
|
||||
|
||||
@NotNull
|
||||
default Iterator<Annotation> iterator()
|
||||
{
|
||||
return getAnnotations().iterator();
|
||||
}
|
||||
}
|
||||
195
deobfuscator/src/main/java/net/runelite/asm/Annotation.java
Normal file
195
deobfuscator/src/main/java/net/runelite/asm/Annotation.java
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (c) 2020, Lucas <https://github.com/Lucwousin>
|
||||
* 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<Annotation>
|
||||
{
|
||||
/**
|
||||
* 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<String, Object> 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());
|
||||
}
|
||||
}
|
||||
@@ -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<Field> fields = new ArrayList<>();
|
||||
private final List<Method> methods = new ArrayList<>();
|
||||
private final Annotations annotations;
|
||||
@Getter
|
||||
private final Map<Type, Annotation> 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;
|
||||
|
||||
@@ -151,7 +151,7 @@ public class ClassGroup implements Iterable<ClassFile>
|
||||
{
|
||||
for (ClassFile cf : classes)
|
||||
{
|
||||
if (name.equals(getObfuscatedName(cf.getAnnotations())))
|
||||
if (name.equals(getObfuscatedName(cf)))
|
||||
{
|
||||
return cf;
|
||||
}
|
||||
|
||||
@@ -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<Type, Annotation> 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()
|
||||
);
|
||||
|
||||
@@ -98,7 +98,7 @@ public class Interfaces implements Iterable<Class>
|
||||
final List<String> names = new ArrayList<>();
|
||||
for (ClassFile c : getMyInterfaces())
|
||||
{
|
||||
String name = DeobAnnotations.getObfuscatedName(c.getAnnotations());
|
||||
String name = DeobAnnotations.getObfuscatedName(c);
|
||||
if (name == null)
|
||||
{
|
||||
continue;
|
||||
|
||||
@@ -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<Type, Annotation> annotations = new TreeMap<>(Comparator.comparing(Type::toString));
|
||||
private List<Parameter> 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 <T extends Instruction & LVTInstruction> List<T> 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
|
||||
);
|
||||
|
||||
@@ -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<Type, Annotation> 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");
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* 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<Annotation>
|
||||
{
|
||||
private final List<Annotation> annotations = new ArrayList<>();
|
||||
|
||||
public List<Annotation> 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<Annotation> iterator()
|
||||
{
|
||||
return this.annotations.iterator();
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* 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<List<Element>> implements Iterable<Element>
|
||||
{
|
||||
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<Element> getElements()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public Element getElement()
|
||||
{
|
||||
return value.get(0);
|
||||
}
|
||||
|
||||
public void addElement(Element element)
|
||||
{
|
||||
value.add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setValue(List<Element> 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<Element> iterator()
|
||||
{
|
||||
return this.value.iterator();
|
||||
}
|
||||
}
|
||||
@@ -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<List> implements Iterable<Object>
|
||||
{
|
||||
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<Object> iterator()
|
||||
{
|
||||
return this.value.iterator();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Stream<Object> stream()
|
||||
{
|
||||
return this.value.stream();
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* 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<T>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package net.runelite.asm.attributes.annotation;
|
||||
|
||||
public class SimpleElement extends Element<Object>
|
||||
{
|
||||
public SimpleElement(Object value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public SimpleElement(String name, Object value)
|
||||
{
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -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<Type> arguments;
|
||||
private final Type rv;
|
||||
|
||||
private Signature(List<Type> arguments, Type rv)
|
||||
public Signature(List<Type> 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<Type> findArgs(final String str, final List<Type> 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(""));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<Element> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Method> 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<Field> 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("<clinit>"))
|
||||
|
||||
@@ -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<Method> methods = unsortedHandlers.stream()
|
||||
.map(ph -> ph.getMethod())
|
||||
.map(PacketHandler::getMethod)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@@ -439,10 +439,6 @@ public class PacketHandlerOrder implements Deobfuscator
|
||||
}
|
||||
|
||||
List<Instruction> 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<PacketRead> r1, List<PacketRead> r2)
|
||||
{
|
||||
List<Type> t1 = r1.stream()
|
||||
.map(pr -> pr.getType())
|
||||
.map(PacketRead::getType)
|
||||
.sorted(this::compareType)
|
||||
.collect(Collectors.toList());
|
||||
List<Type> t2 = r2.stream()
|
||||
.map(pr -> pr.getType())
|
||||
.map(PacketRead::getType)
|
||||
.sorted(this::compareType)
|
||||
.collect(Collectors.toList());
|
||||
if (t1.size() != t2.size())
|
||||
|
||||
@@ -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<Method> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <T extends Annotated & Named> void addObfuscatedName(T object)
|
||||
{
|
||||
object.findAnnotation(OBFUSCATED_NAME, true).setElement(object.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Method, Method> methods = new HashMap<>();
|
||||
|
||||
public void run(ClassGroup group)
|
||||
{
|
||||
int replacedCalls = 0;
|
||||
int removedInstructions = 0;
|
||||
int removedMethods = 0;
|
||||
int removedAnnotations = 0;
|
||||
List<net.runelite.asm.Method> 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<Instruction> 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<Instruction> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<Method> m : unused.keySet())
|
||||
for (Map.Entry<List<Method>, Collection<Integer>> entry : unused.entrySet())
|
||||
{
|
||||
Collection<Integer> u = unused.get(m);
|
||||
List<Method> m = entry.getKey();
|
||||
Collection<Integer> u = entry.getValue();
|
||||
|
||||
int offset = m.size() == 1 && m.get(0).isStatic() ? 0 : 1;
|
||||
|
||||
@@ -188,7 +188,7 @@ public class UnusedParameters implements Deobfuscator
|
||||
}
|
||||
}
|
||||
|
||||
List<Integer> l = new ArrayList<>(list);
|
||||
List<Integer> 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<InstructionContext> 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ConstantMethodParameter, ConstantMethodParameter> parameters = new HashMap<>();
|
||||
private Multimap<Method, ConstantMethodParameter> mparams = HashMultimap.create();
|
||||
private final Map<ConstantMethodParameter, ConstantMethodParameter> parameters = new HashMap<>();
|
||||
private final Multimap<Method, ConstantMethodParameter> mparams = HashMultimap.create();
|
||||
|
||||
private void checkMethodsAreConsistent(List<Method> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Field> 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<Method> 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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -36,7 +36,7 @@ import net.runelite.asm.signature.Signature;
|
||||
|
||||
public class StaticMethodSignatureMapper
|
||||
{
|
||||
private Multimap<Method, Method> map = LinkedHashMultimap.create();
|
||||
private final Multimap<Method, Method> map = LinkedHashMultimap.create();
|
||||
|
||||
private List<Method> getStaticMethods(ClassGroup group)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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 <T extends Annotated & Named> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Type> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -37,6 +39,10 @@ public class NameMappings
|
||||
|
||||
private final Map<Object, String[]> paramMap = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int fields, methods, classes;
|
||||
|
||||
public void map(Class cf, String name)
|
||||
{
|
||||
map.put(cf, name);
|
||||
|
||||
@@ -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> 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<Element> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<String, ClassHook> 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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<Method> 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();
|
||||
|
||||
@@ -155,7 +155,7 @@ tasks {
|
||||
register<JavaExec>("RuneLite.main()") {
|
||||
group = "openosrs"
|
||||
|
||||
classpath = project.sourceSets.main.get().runtimeClasspath
|
||||
classpath = sourceSets["main"].runtimeClasspath
|
||||
enableAssertions = true
|
||||
main = "net.runelite.client.RuneLite"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user