diff --git a/deobfuscator/src/main/java/net/runelite/asm/Method.java b/deobfuscator/src/main/java/net/runelite/asm/Method.java index bc2c8b305b..e8cbdef92b 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/Method.java +++ b/deobfuscator/src/main/java/net/runelite/asm/Method.java @@ -203,9 +203,16 @@ public class Method return (accessFlags & ACC_STATIC) != 0; } - public void setStatic() + public void setStatic(boolean s) { - accessFlags |= ACC_STATIC; + if (s) + { + accessFlags |= ACC_STATIC; + } + else + { + accessFlags &= ~ACC_STATIC; + } } public boolean isSynchronized() diff --git a/deobfuscator/src/main/java/net/runelite/deob/Deob.java b/deobfuscator/src/main/java/net/runelite/deob/Deob.java index 8f37a9b167..e46bdfbe20 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/Deob.java +++ b/deobfuscator/src/main/java/net/runelite/deob/Deob.java @@ -27,14 +27,10 @@ package net.runelite.deob; import com.google.common.base.Stopwatch; import java.io.File; import java.io.IOException; -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.execution.Execution; import net.runelite.deob.deobfuscators.CastNull; +import net.runelite.deob.deobfuscators.StaticShouldBeInstance; import net.runelite.deob.deobfuscators.constparam.ConstantParameter; import net.runelite.deob.deobfuscators.EnumDeobfuscator; import net.runelite.deob.deobfuscators.FieldInliner; @@ -85,85 +81,70 @@ public class Deob ClassGroup group = JarUtil.loadJar(new File(args[0])); - for (ClassFile f : group.getClasses()) + if (args.length > 2 && args[2].equals("rl")) { - f.getAnnotations().clearAnnotations(); - for (Method m : f.getMethods()) - { - Annotations an = m.getAnnotations(); - an.clearAnnotations(); - } - for (Field fi : f.getFields()) - { - Annotations an = fi.getAnnotations(); - if (an.find(new Type("Ljavax/inject/Inject;")) == null) - { - an.clearAnnotations(); - } - else - { - logger.info("Class {}, field {} has inject", f.getClassName(), fi.getName()); - } - } + run(group, new StaticShouldBeInstance()); } + else + { + // remove except RuntimeException + run(group, new RuntimeExceptions()); - // remove except RuntimeException - run(group, new RuntimeExceptions()); + run(group, new ControlFlowDeobfuscator()); - run(group, new ControlFlowDeobfuscator()); + run(group, new RenameUnique()); - run(group, new RenameUnique()); + // remove unused methods - this leaves Code with no instructions, + // which is not valid, so unused methods is run after + run(group, new UnreachedCode()); + run(group, new UnusedMethods()); - // remove unused methods - this leaves Code with no instructions, - // which is not valid, so unused methods is run after - run(group, new UnreachedCode()); - run(group, new UnusedMethods()); + // remove illegal state exceptions, frees up some parameters + run(group, new IllegalStateExceptions()); - // remove illegal state exceptions, frees up some parameters - run(group, new IllegalStateExceptions()); + // remove constant logically dead parameters + run(group, new ConstantParameter()); - // remove constant logically dead parameters - run(group, new ConstantParameter()); + // remove unhit blocks + run(group, new UnreachedCode()); + run(group, new UnusedMethods()); - // remove unhit blocks - run(group, new UnreachedCode()); - run(group, new UnusedMethods()); + // remove unused parameters + run(group, new UnusedParameters()); - // remove unused parameters - run(group, new UnusedParameters()); + // remove unused fields + run(group, new UnusedFields()); - // remove unused fields - run(group, new UnusedFields()); + run(group, new FieldInliner()); - run(group, new FieldInliner()); + // order uses class name order for sorting fields/methods, + // so run it before removing classes below + run(group, new Order()); - // order uses class name order for sorting fields/methods, - // so run it before removing classes below - run(group, new Order()); + run(group, new UnusedClass()); - run(group, new UnusedClass()); + runMath(group); - runMath(group); + run(group, new ExprArgOrder()); - run(group, new ExprArgOrder()); + run(group, new Lvt()); - run(group, new Lvt()); + run(group, new CastNull()); - run(group, new CastNull()); + run(group, new EnumDeobfuscator()); - run(group, new EnumDeobfuscator()); + new OpcodesTransformer().transform(group); + //run(group, new PacketHandlerOrder()); + //run(group, new PacketWriteDeobfuscator()); - new OpcodesTransformer().transform(group); - //run(group, new PacketHandlerOrder()); - //run(group, new PacketWriteDeobfuscator()); + run(group, new MenuActionDeobfuscator()); - run(group, new MenuActionDeobfuscator()); - - new GetPathTransformer().transform(group); - new ClientErrorTransformer().transform(group); - new ReflectionTransformer().transform(group); - new MaxMemoryTransformer().transform(group); - //new RuneliteBufferTransformer().transform(group); + new GetPathTransformer().transform(group); + new ClientErrorTransformer().transform(group); + new ReflectionTransformer().transform(group); + new MaxMemoryTransformer().transform(group); + //new RuneliteBufferTransformer().transform(group); + } JarUtil.saveJar(group, new File(args[1])); diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/StaticShouldBeInstance.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/StaticShouldBeInstance.java new file mode 100644 index 0000000000..1cae903698 --- /dev/null +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/StaticShouldBeInstance.java @@ -0,0 +1,171 @@ +package net.runelite.deob.deobfuscators; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import net.runelite.asm.ClassFile; +import net.runelite.asm.ClassGroup; +import net.runelite.asm.Field; +import net.runelite.asm.Type; +import net.runelite.asm.attributes.Annotations; +import net.runelite.asm.attributes.Code; +import net.runelite.asm.attributes.code.Instruction; +import net.runelite.asm.attributes.code.Instructions; +import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction; +import net.runelite.asm.attributes.code.instructions.InvokeStatic; +import net.runelite.asm.attributes.code.instructions.InvokeVirtual; +import net.runelite.asm.pool.Method; +import net.runelite.asm.signature.Signature; +import net.runelite.deob.Deobfuscator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StaticShouldBeInstance implements Deobfuscator +{ + private static final Logger logger = LoggerFactory.getLogger(StaticShouldBeInstance.class); + private static Map methods = new HashMap<>(); + + public void run(ClassGroup group) + { + int replacedCalls = 0; + int removedInstructions = 0; + int removedMethods = 0; + int removedAnnotations = 0; + List obfuscatedMethods = new ArrayList<>(); + + for (ClassFile cf : group.getClasses()) + { + // Remove unused annotations + Annotations a = cf.getAnnotations(); + removedAnnotations += a.getAnnotations().size(); + a.clearAnnotations(); + + Type type = new Type('L' + cf.getClassName() + ';'); + obfuscatedMethods.clear(); + + for (net.runelite.asm.Method m : cf.getMethods()) + { + // Remove unused annotations + a = m.getAnnotations(); + removedAnnotations += a.size(); + a.clearAnnotations(); + + if (m.isStatic() && m.getCode() != null) + { + if (checkIfObf(m, type, cf)) + { + removedMethods++; + obfuscatedMethods.add(m); + } + } + } + + + for (net.runelite.asm.Method m : obfuscatedMethods) + { + Signature sig = m.getDescriptor(); + Signature.Builder builder = new Signature.Builder(); + builder.setReturnType(sig.getReturnValue()); + if (sig.getArguments().size() > 1) + { + builder.addArguments(sig.getArguments().subList(1, sig.getArguments().size())); + } + + Signature toFind = builder.build(); + + net.runelite.asm.Method notStatic = cf.findMethod(m.getName(), toFind); + net.runelite.asm.pool.Method oldPool = m.getPoolMethod(); + cf.removeMethod(notStatic); + + m.setDescriptor(toFind); + m.setStatic(false); + Code c = m.getCode(); + Instructions ins = c.getInstructions(); + int startLength = ins.getInstructions().size(); + ListIterator it = ins.getInstructions().listIterator(); + assert it.hasNext(); + Instruction i = it.next(); + while (!(i instanceof ReturnInstruction)) + { + it.remove(); + i = it.next(); + } + it.remove(); + net.runelite.asm.pool.Method newPool = m.getPoolMethod(); + + methods.put(oldPool, newPool); + + removedInstructions += startLength - ins.getInstructions().size(); + } + + for (Field fi : cf.getFields()) + { + a = fi.getAnnotations(); + if (a.find(new Type("Ljavax/inject/Inject;")) == null) + { + removedAnnotations += a.size(); + a.clearAnnotations(); + } + else + { + logger.info("Class {}, field {} has inject", cf.getClassName(), fi.getName()); + } + } + } + + for (ClassFile cf : group.getClasses()) + { + for (net.runelite.asm.Method m : cf.getMethods()) + { + if (m.getCode() == null) + { + continue; + } + + Instructions ins = m.getCode().getInstructions(); + List instructions = ins.getInstructions(); + for (int i1 = 0, instructionsSize = instructions.size(); i1 < instructionsSize; i1++) + { + Instruction i = instructions.get(i1); + if (!(i instanceof InvokeStatic)) + { + continue; + } + + if (methods.containsKey(((InvokeStatic) i).getMethod())) + { + InvokeVirtual invoke = new InvokeVirtual(ins, methods.get(((InvokeStatic) i).getMethod())); + ins.replace(i, invoke); + replacedCalls++; + } + } + } + } + + logger.info("Made {} methods not static, removed {} instructions, replaced {} invokes, and removed {} annotations", removedMethods, removedInstructions, replacedCalls, removedAnnotations); + } + + private static boolean checkIfObf(net.runelite.asm.Method m, Type type, ClassFile cf) + { + Signature sig = m.getDescriptor(); + if (sig.getArguments().size() < 1 || !sig.getTypeOfArg(0).equals(type)) + { + return false; + } + + Signature.Builder builder = new Signature.Builder(); + builder.setReturnType(sig.getReturnValue()); + if (sig.getArguments().size() > 1) + { + builder.addArguments(sig.getArguments().subList(1, sig.getArguments().size())); + } + + Signature toFind = builder.build(); + + net.runelite.asm.Method notStatic = cf.findMethod(m.getName(), toFind); + + return notStatic != null; + } +} diff --git a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/transformers/OpcodesTransformer.java b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/transformers/OpcodesTransformer.java index 15f9eae248..d515c3bcd4 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/transformers/OpcodesTransformer.java +++ b/deobfuscator/src/main/java/net/runelite/deob/deobfuscators/transformers/OpcodesTransformer.java @@ -60,7 +60,7 @@ public class OpcodesTransformer implements Transformer if (clinit == null) { clinit = new Method(runeliteOpcodes, "", new Signature("()V")); - clinit.setStatic(); + clinit.setStatic(true); Code code = new Code(clinit); code.setMaxStack(1); clinit.setCode(code); diff --git a/deobfuscator/src/main/java/net/runelite/deob/updater/UpdateMappings.java b/deobfuscator/src/main/java/net/runelite/deob/updater/UpdateMappings.java index 0df369e8ad..db6ed0ef1c 100644 --- a/deobfuscator/src/main/java/net/runelite/deob/updater/UpdateMappings.java +++ b/deobfuscator/src/main/java/net/runelite/deob/updater/UpdateMappings.java @@ -26,19 +26,24 @@ package net.runelite.deob.updater; import java.io.File; import java.io.IOException; +import java.util.Map; import net.runelite.asm.ClassGroup; +import net.runelite.asm.Field; +import net.runelite.asm.Method; +import net.runelite.deob.deobfuscators.Renamer; import net.runelite.deob.deobfuscators.mapping.AnnotationIntegrityChecker; import net.runelite.deob.deobfuscators.mapping.AnnotationMapper; import net.runelite.deob.deobfuscators.mapping.Mapper; import net.runelite.deob.deobfuscators.mapping.ParallelExecutorMapping; import net.runelite.deob.util.JarUtil; +import net.runelite.deob.util.NameMappings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class UpdateMappings { private static final Logger logger = LoggerFactory.getLogger(UpdateMappings.class); - + private static boolean renameRL = true; private final ClassGroup group1, group2; public UpdateMappings(ClassGroup group1, ClassGroup group2) @@ -74,6 +79,32 @@ public class UpdateMappings pr.run(); } + public void updateRL() + { + Mapper mapper = new Mapper(group1, group2); + mapper.run(); + ParallelExecutorMapping mapping = mapper.getMapping(); + NameMappings names = new NameMappings(); + + for (Map.Entry e : mapping.getMap().entrySet()) + { + Object k = e.getKey(); + Object v = e.getValue(); + + if (k instanceof Field) + { + names.map(((Field) v).getPoolField(), ((Field) k).getName()); + } + else if (k instanceof Method) + { + names.map(((Method) v).getPoolMethod(), ((Method) k).getName()); + } + } + + Renamer renamer = new Renamer(names); + renamer.run(group2); + } + public void save(File out) throws IOException { JarUtil.saveJar(group2, out); @@ -90,7 +121,14 @@ public class UpdateMappings JarUtil.loadJar(new File(args[0])), JarUtil.loadJar(new File(args[1])) ); - u.update(); + if (renameRL) + { + u.updateRL(); + } + else + { + u.update(); + } u.save(new File(args[2])); } } diff --git a/deobfuscator/src/test/java/net/runelite/deob/ClassGroupFactory.java b/deobfuscator/src/test/java/net/runelite/deob/ClassGroupFactory.java index 6faef99743..3c2a5bebf9 100644 --- a/deobfuscator/src/test/java/net/runelite/deob/ClassGroupFactory.java +++ b/deobfuscator/src/test/java/net/runelite/deob/ClassGroupFactory.java @@ -39,7 +39,7 @@ public class ClassGroupFactory private static void addVoidMethod(ClassFile cf, String name) { Method method = new Method(cf, name, new Signature("()V")); - method.setStatic(); + method.setStatic(true); cf.addMethod(method); Code code = new Code(method); @@ -63,7 +63,7 @@ public class ClassGroupFactory cf.addField(field); Method method = new Method(cf, "func", new Signature("()V")); - method.setStatic(); + method.setStatic(true); cf.addMethod(method); Code code = new Code(method); @@ -71,7 +71,7 @@ public class ClassGroupFactory { method = new Method(cf, "func2", new Signature("(III)V")); - method.setStatic(); + method.setStatic(true); cf.addMethod(method); code = new Code(method); diff --git a/injector-plugin/src/main/java/net/runelite/injector/Inject.java b/injector-plugin/src/main/java/net/runelite/injector/Inject.java index dcc0236937..3e24a55374 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/Inject.java +++ b/injector-plugin/src/main/java/net/runelite/injector/Inject.java @@ -47,6 +47,7 @@ import net.runelite.deob.DeobAnnotations; import net.runelite.deob.deobfuscators.arithmetic.DMath; import net.runelite.injector.raw.ClearColorBuffer; import net.runelite.injector.raw.DrawAfterWidgets; +import net.runelite.injector.raw.DrawMenu; import net.runelite.injector.raw.RasterizerHook; import net.runelite.injector.raw.RenderDraw; import net.runelite.injector.raw.ScriptVM; @@ -68,6 +69,7 @@ public class Inject private final InjectInvoker invokes = new InjectInvoker(this); private final InjectConstruct construct = new InjectConstruct(this); + private final DrawMenu drawMenu = new DrawMenu(this); private final RasterizerHook rasterizerHook = new RasterizerHook(this); private final MixinInjector mixinInjector = new MixinInjector(this); private final DrawAfterWidgets drawAfterWidgets = new DrawAfterWidgets(this); @@ -331,6 +333,7 @@ public class Inject scriptVM.inject(); clearColorBuffer.inject(); renderDraw.inject(); + drawMenu.inject(); } private java.lang.Class injectInterface(ClassFile cf, ClassFile other) diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectConstruct.java b/injector-plugin/src/main/java/net/runelite/injector/InjectConstruct.java index 88e527d405..8a87451da6 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/InjectConstruct.java +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectConstruct.java @@ -54,7 +54,7 @@ public class InjectConstruct private final Inject inject; - public InjectConstruct(Inject inject) + InjectConstruct(Inject inject) { this.inject = inject; } @@ -99,7 +99,7 @@ public class InjectConstruct } } - public void injectConstruct(ClassFile targetClass, java.lang.reflect.Method apiMethod) throws InjectionException + void injectConstruct(ClassFile targetClass, java.lang.reflect.Method apiMethod) throws InjectionException { logger.info("Injecting construct for {}", apiMethod); diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectGetter.java b/injector-plugin/src/main/java/net/runelite/injector/InjectGetter.java index b9758b4f61..cd94ee80d8 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/InjectGetter.java +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectGetter.java @@ -44,7 +44,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class InjectGetter +class InjectGetter { private static final Logger logger = LoggerFactory.getLogger(InjectGetter.class); @@ -52,12 +52,12 @@ public class InjectGetter private int injectedGetters; - public InjectGetter(Inject inject) + InjectGetter(Inject inject) { this.inject = inject; } - public void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter) + void injectGetter(ClassFile clazz, java.lang.reflect.Method method, Field field, Number getter) { // clazz = class file we're injecting the method into. // method = api method (java reflect) that we're overriding @@ -148,7 +148,7 @@ public class InjectGetter ++injectedGetters; } - public int getInjectedGetters() + int getInjectedGetters() { return injectedGetters; } diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectHook.java b/injector-plugin/src/main/java/net/runelite/injector/InjectHook.java index a709d92072..19ae3a3df6 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/InjectHook.java +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectHook.java @@ -55,7 +55,7 @@ import net.runelite.asm.signature.Signature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class InjectHook +class InjectHook { private static final Logger logger = LoggerFactory.getLogger(InjectHook.class); private static final String HOOK_METHOD_SIGNATURE = "(I)V"; @@ -64,7 +64,7 @@ public class InjectHook private final Map hooked = new HashMap<>(); private int injectedHooks; - public InjectHook(Inject inject) + InjectHook(Inject inject) { this.inject = inject; } @@ -74,7 +74,7 @@ public class InjectHook hooked.put(field, hookInfo); } - public void run() + void run() { Execution e = new Execution(inject.getVanilla()); e.populateInitialMethods(); @@ -129,8 +129,7 @@ public class InjectHook StackContext objectStackContext = null; if (sfi instanceof PutField) { - StackContext objectStack = ic.getPops().get(1); // Object being set on - objectStackContext = objectStack; + objectStackContext = ic.getPops().get(1); } int idx = ins.getInstructions().indexOf(sfi); @@ -206,8 +205,7 @@ public class InjectHook StackContext objectStackContext = null; if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD) { - StackContext objectReference = arrayReferencePushed.getPops().get(0); - objectStackContext = objectReference; + objectStackContext = arrayReferencePushed.getPops().get(0); } // inject hook after 'i' @@ -382,7 +380,7 @@ public class InjectHook } } - public int getInjectedHooks() + int getInjectedHooks() { return injectedHooks; } diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectHookMethod.java b/injector-plugin/src/main/java/net/runelite/injector/InjectHookMethod.java index 9cd7d4326d..94303e81d3 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/InjectHookMethod.java +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectHookMethod.java @@ -53,12 +53,12 @@ public class InjectHookMethod private static final Logger logger = LoggerFactory.getLogger(InjectHookMethod.class); private final Inject inject; - public InjectHookMethod(Inject inject) + InjectHookMethod(Inject inject) { this.inject = inject; } - public void process(Method method) throws InjectionException + void process(Method method) throws InjectionException { Annotations an = method.getAnnotations(); if (an == null) diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectInvoker.java b/injector-plugin/src/main/java/net/runelite/injector/InjectInvoker.java index 6b3fa13d33..1153609b8e 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/InjectInvoker.java +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectInvoker.java @@ -51,7 +51,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class InjectInvoker +class InjectInvoker { private static final Logger logger = LoggerFactory.getLogger(InjectInvoker.class); @@ -59,7 +59,7 @@ public class InjectInvoker private int injectedInvokers; - public InjectInvoker(Inject inject) + InjectInvoker(Inject inject) { this.inject = inject; } @@ -73,7 +73,7 @@ public class InjectInvoker * @param implementingClass Java class for the API interface the class * will implement */ - public void process(Method m, ClassFile other, java.lang.Class implementingClass) + void process(Method m, ClassFile other, java.lang.Class implementingClass) { Annotations an = m.getAnnotations(); @@ -284,7 +284,7 @@ public class InjectInvoker clazz.addMethod(invokerMethodSignature); } - public int getInjectedInvokers() + int getInjectedInvokers() { return injectedInvokers; } diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectSetter.java b/injector-plugin/src/main/java/net/runelite/injector/InjectSetter.java index 6b10ab3b56..58c225fa87 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/InjectSetter.java +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectSetter.java @@ -45,7 +45,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class InjectSetter +class InjectSetter { private static final Logger logger = LoggerFactory.getLogger(InjectSetter.class); @@ -53,7 +53,7 @@ public class InjectSetter private int injectedSetters; - public InjectSetter(Inject inject) + InjectSetter(Inject inject) { this.inject = inject; } @@ -67,9 +67,8 @@ public class InjectSetter * setter declared * @param field Field of vanilla that will be set * @param exportedName exported name of field - * @param setter */ - public void injectSetter(ClassFile targetClass, Class targetApiClass, Field field, String exportedName, Number setter) + void injectSetter(ClassFile targetClass, Class targetApiClass, Field field, String exportedName, Number setter) { java.lang.reflect.Method method = inject.findImportMethodOnApi(targetApiClass, exportedName, true); if (method == null) @@ -152,7 +151,7 @@ public class InjectSetter ins.add(new VReturn(instructions)); } - public int getInjectedSetters() + int getInjectedSetters() { return injectedSetters; } diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectUtil.java b/injector-plugin/src/main/java/net/runelite/injector/InjectUtil.java new file mode 100644 index 0000000000..e9a32a0bb0 --- /dev/null +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectUtil.java @@ -0,0 +1,130 @@ +package net.runelite.injector; + +import net.runelite.asm.ClassFile; +import net.runelite.asm.Field; +import net.runelite.asm.Method; +import net.runelite.asm.signature.Signature; +import net.runelite.deob.DeobAnnotations; + +public class InjectUtil +{ + public static Method findStaticObMethod(Inject inject, String name) throws InjectionException + { + for (ClassFile c : inject.getVanilla().getClasses()) + { + for (Method m : c.getMethods()) + { + if (!m.getName().equals(name)) + { + continue; + } + return m; + } + } + + throw new InjectionException(String.format("Method \"%s\" could not be found.", name)); + } + + public static Method findMethod(Inject inject, String name) throws InjectionException + { + for (ClassFile c : inject.getDeobfuscated().getClasses()) + { + for (Method m : c.getMethods()) + { + if (!m.getName().equals(name)) + { + continue; + } + + String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); + Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m); + + ClassFile c2 = inject.toObClass(c); + + return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor()); + } + } + + throw new InjectionException("Couldn't find method " + name); + } + + public static Method findStaticMethod(Inject inject, String name) throws InjectionException + { + for (ClassFile c : inject.getDeobfuscated().getClasses()) + { + for (Method m : c.getMethods()) + { + if (!m.isStatic() || !m.getName().equals(name)) + { + continue; + } + + String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); + Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m); + + ClassFile c2 = inject.toObClass(c); + + return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor()); + } + } + + throw new InjectionException("Couldn't find static method " + name); + } + + + public static Field findObField(Inject inject, String name) throws InjectionException + { + for (ClassFile c : inject.getVanilla().getClasses()) + { + for (Field f : c.getFields()) + { + if (!f.getName().equals(name)) + { + continue; + } + return f; + } + } + + throw new InjectionException(String.format("Field \"%s\" could not be found.", name)); + } + + public static Field findDeobField(Inject inject, String name) throws InjectionException + { + for (ClassFile c : inject.getDeobfuscated().getClasses()) + { + for (Field f : c.getFields()) + { + if (!f.getName().equals(name)) + { + continue; + } + + String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations()); + + ClassFile c2 = inject.toObClass(c); + return c2.findField(obfuscatedName); + } + } + + throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name)); + } + + public static Field findDeobFieldButUseless(Inject inject, String name) throws InjectionException + { + for (ClassFile c : inject.getDeobfuscated().getClasses()) + { + for (Field f : c.getFields()) + { + if (!f.getName().equals(name)) + { + continue; + } + + return f; + } + } + + throw new InjectionException(String.format("Mapped field \"%s\" could not be found.", name)); + } +} diff --git a/injector-plugin/src/main/java/net/runelite/injector/Injector.java b/injector-plugin/src/main/java/net/runelite/injector/Injector.java index d8b61f901b..9409b02075 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/Injector.java +++ b/injector-plugin/src/main/java/net/runelite/injector/Injector.java @@ -67,7 +67,7 @@ public class Injector instance.run(); } - public void save(File out) throws IOException + private void save(File out) throws IOException { JarUtil.saveJar(vanilla, out); } diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectorValidator.java b/injector-plugin/src/main/java/net/runelite/injector/InjectorValidator.java index f4e2cad9b9..a49df63a3a 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/InjectorValidator.java +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectorValidator.java @@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory; * * @author Adam */ -public class InjectorValidator +class InjectorValidator { private static final Logger logger = LoggerFactory.getLogger(InjectorValidator.class); @@ -49,12 +49,12 @@ public class InjectorValidator private int error, missing, okay; - public InjectorValidator(ClassGroup group) + InjectorValidator(ClassGroup group) { this.group = group; } - public void validate() + void validate() { for (ClassFile cf : group.getClasses()) { @@ -131,17 +131,17 @@ public class InjectorValidator } } - public int getError() + int getError() { return error; } - public int getMissing() + int getMissing() { return missing; } - public int getOkay() + int getOkay() { return okay; } diff --git a/injector-plugin/src/main/java/net/runelite/injector/MixinInjector.java b/injector-plugin/src/main/java/net/runelite/injector/MixinInjector.java index 1547880140..815b3699aa 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/MixinInjector.java +++ b/injector-plugin/src/main/java/net/runelite/injector/MixinInjector.java @@ -87,7 +87,7 @@ public class MixinInjector // Use net.runelite.asm.pool.Field instead of Field because the pool version has hashcode implemented private final Map shadowFields = new HashMap<>(); - public MixinInjector(Inject inject) + MixinInjector(Inject inject) { this.inject = inject; } @@ -165,9 +165,6 @@ public class MixinInjector /** * Finds fields that are marked @Inject and inject them into the target - * - * @param mixinClasses - * @throws InjectionException */ private void injectFields(Map, List> mixinClasses) throws InjectionException { @@ -245,9 +242,6 @@ public class MixinInjector /** * Find fields which are marked @Shadow, and what they shadow - * - * @param mixinClasses - * @throws InjectionException */ private void findShadowFields(Map, List> mixinClasses) throws InjectionException { @@ -287,7 +281,7 @@ public class MixinInjector else { // Shadow a field already in the gamepack - Field shadowField = findDeobField(shadowName); + Field shadowField = InjectUtil.findDeobFieldButUseless(inject, shadowName); if (shadowField == null) { @@ -316,21 +310,6 @@ public class MixinInjector } } - private Field findDeobField(String name) - { - for (ClassFile cf : inject.getDeobfuscated().getClasses()) - { - for (Field f : cf.getFields()) - { - if (f.getName().equals(name) && f.isStatic()) - { - return f; - } - } - } - return null; - } - private void injectMethods(ClassFile mixinCf, ClassFile cf, Map shadowFields) throws InjectionException { @@ -901,7 +880,7 @@ public class MixinInjector if (targetField == null) { // first try non static fields, then static - targetField = findDeobField(hookName); + targetField = InjectUtil.findDeobFieldButUseless(inject, hookName); } if (targetField == null) diff --git a/injector-plugin/src/main/java/net/runelite/injector/raw/ClearColorBuffer.java b/injector-plugin/src/main/java/net/runelite/injector/raw/ClearColorBuffer.java index ffacb7f1a8..ac40a35e14 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/raw/ClearColorBuffer.java +++ b/injector-plugin/src/main/java/net/runelite/injector/raw/ClearColorBuffer.java @@ -11,8 +11,8 @@ import net.runelite.asm.attributes.code.instructions.InvokeStatic; import net.runelite.asm.attributes.code.instructions.LDC; import net.runelite.asm.pool.Class; import net.runelite.asm.signature.Signature; -import net.runelite.deob.DeobAnnotations; import net.runelite.injector.Inject; +import net.runelite.injector.InjectUtil; import net.runelite.injector.InjectionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +39,7 @@ public class ClearColorBuffer private void injectColorBufferHooks() throws InjectionException { - net.runelite.asm.pool.Method fillRectangle = findStaticMethod("Rasterizer2D_fillRectangle").getPoolMethod(); + net.runelite.asm.pool.Method fillRectangle = InjectUtil.findStaticMethod(inject, "Rasterizer2D_fillRectangle").getPoolMethod(); int count = 0; int replaced = 0; @@ -119,28 +119,4 @@ public class ClearColorBuffer } } } - - private Method findStaticMethod(String name) throws InjectionException - { - for (ClassFile c : inject.getDeobfuscated().getClasses()) - { - for (Method m : c.getMethods()) - { - if (!m.getName().equals(name)) - { - continue; - } - - String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); - Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m); - - ClassFile c2 = inject.toObClass(c); - - return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor()); - } - } - - throw new InjectionException("Couldn't find static method " + name); - } - } \ No newline at end of file diff --git a/injector-plugin/src/main/java/net/runelite/injector/raw/DrawAfterWidgets.java b/injector-plugin/src/main/java/net/runelite/injector/raw/DrawAfterWidgets.java index ae2a3d5478..e2250b894e 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/raw/DrawAfterWidgets.java +++ b/injector-plugin/src/main/java/net/runelite/injector/raw/DrawAfterWidgets.java @@ -38,9 +38,9 @@ import net.runelite.asm.attributes.code.instructions.GetStatic; import net.runelite.asm.attributes.code.instructions.IMul; import net.runelite.asm.attributes.code.instructions.InvokeStatic; import net.runelite.asm.signature.Signature; -import net.runelite.deob.DeobAnnotations; import net.runelite.injector.Inject; import static net.runelite.injector.InjectHookMethod.HOOKS; +import static net.runelite.injector.InjectUtil.findStaticMethod; import net.runelite.injector.InjectionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,7 +107,7 @@ public class DrawAfterWidgets boolean injected = false; - Method noClip = findStaticMethod("Rasterizer2D_resetClip"); // !!!!! + Method noClip = findStaticMethod(inject, "Rasterizer2D_resetClip"); // !!!!! if (noClip == null) { @@ -261,27 +261,4 @@ public class DrawAfterWidgets throw new InjectionException("injectDrawAfterWidgets failed to inject!"); } } - - private Method findStaticMethod(String name) - { - for (ClassFile c : inject.getDeobfuscated().getClasses()) - { - for (Method m : c.getMethods()) - { - if (!m.getName().equals(name)) - { - continue; - } - - String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); - Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m); - - ClassFile c2 = inject.toObClass(c); - - return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor()); - } - } - - return null; - } } diff --git a/injector-plugin/src/main/java/net/runelite/injector/raw/DrawMenu.java b/injector-plugin/src/main/java/net/runelite/injector/raw/DrawMenu.java index 65cb9bdab4..b6634e68c5 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/raw/DrawMenu.java +++ b/injector-plugin/src/main/java/net/runelite/injector/raw/DrawMenu.java @@ -1,193 +1,135 @@ -/* package net.runelite.injector.raw; -import com.google.common.base.Strings; -import java.util.HashSet; -import java.util.Set; +import java.util.ListIterator; import net.runelite.asm.ClassFile; import net.runelite.asm.Method; -import net.runelite.asm.Type; -import net.runelite.asm.attributes.Annotations; import net.runelite.asm.attributes.Code; -import net.runelite.asm.attributes.annotation.Annotation; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.Instructions; import net.runelite.asm.attributes.code.Label; -import net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction; import net.runelite.asm.attributes.code.instruction.types.JumpingInstruction; -import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction; import net.runelite.asm.attributes.code.instructions.GetStatic; -import net.runelite.asm.attributes.code.instructions.IfACmpEq; -import net.runelite.asm.attributes.code.instructions.IfACmpNe; import net.runelite.asm.attributes.code.instructions.IfEq; import net.runelite.asm.attributes.code.instructions.IfNe; import net.runelite.asm.attributes.code.instructions.InvokeStatic; -import net.runelite.asm.execution.Execution; -import net.runelite.asm.execution.InstructionContext; import net.runelite.asm.pool.Class; import net.runelite.asm.pool.Field; import net.runelite.asm.signature.Signature; -import net.runelite.deob.DeobAnnotations; import net.runelite.injector.Inject; +import static net.runelite.injector.InjectUtil.findDeobField; +import static net.runelite.injector.InjectUtil.findStaticMethod; import net.runelite.injector.InjectionException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DrawMenu { + private final Logger log = LoggerFactory.getLogger(DrawMenu.class); private final Inject inject; - private static final Field isMenuOpen = new Field( - new Class("Client"), - "isMenuOpen", - Type.BOOLEAN - ); private static final net.runelite.asm.pool.Method hook = new net.runelite.asm.pool.Method( new Class("net.runelite.client.callback.Hooks"), "drawMenu", new Signature("()Z") ); + //Label Getstatic client.isMenuOpen + //Ifne -> Label Drawmenu + //Jump -> Label Drawtext + + //Label drawtext + //Ldc xxx + //Getstatic client. something with viewport size? + //Imul + //Iconst_m1 + //Ifne -> Label after draw menu <- info we need + //Getstatic / LDC (same getstatic and LDC before) + //Getstatic / LDC + public DrawMenu(Inject inject) { - this.inject =inject; + this.inject = inject; } public void inject() throws InjectionException { - Method drawLoggedIn = findDeobThing("drawLoggedIn", "Client", false); - Instructions ins = drawLoggedIn.getCode().getInstructions(); + Field isMenuOpen = findDeobField(inject, "isMenuOpen").getPoolField(); + net.runelite.asm.pool.Method topLeftText = findStaticMethod(inject, "drawMenuActionTextAt").getPoolMethod(); - int menuOpenIdx = -1; - Field field = toObField(isMenuOpen).getPoolField(); - - for (Instruction i : ins.getInstructions()) - { - if (!(i instanceof GetStatic)) - { - continue; - } - - if (((GetStatic) i).getField().equals(field)) - { - menuOpenIdx = ins.getInstructions().indexOf(i); - } - } - - if (menuOpenIdx == -1) - { - throw new InjectionException("Couldn't find the isMenuOpen check!"); - } - - // This is where the IFEQ or IFNE will be - final Instruction jump = ins.getInstructions().get(menuOpenIdx + 1); - // We want to inject if it's false so - if (jump instanceof IfEq) - { - // Not this one, but we gotta find out where the paths will intersect - Set