asm: Use a more sensible approach for annotations

This commit is contained in:
Lucwousin
2020-07-16 02:01:33 +02:00
parent eb1d6bbd74
commit 29105c9501
49 changed files with 625 additions and 1271 deletions

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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>"))

View File

@@ -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())

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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
{

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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());

View File

@@ -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();

View File

@@ -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()
);
}

View File

@@ -27,6 +27,8 @@ package net.runelite.deob.util;
import java.util.HashMap;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
import net.runelite.asm.pool.Class;
import net.runelite.asm.pool.Field;
import net.runelite.asm.pool.Method;
@@ -36,7 +38,11 @@ public class NameMappings
private final Map<Object, String> map = new HashMap<>();
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);