From 7a4e213e259c62a112d4c2ff9ce963b4c989793b Mon Sep 17 00:00:00 2001 From: Lucwousin Date: Wed, 10 Jul 2019 01:51:18 +0200 Subject: [PATCH] Injector: Tiny bit of cleanup --- .../main/java/net/runelite/asm/ClassFile.java | 34 +++++- .../java/net/runelite/asm/ClassGroup.java | 35 ++++++ .../java/net/runelite/injector/Inject.java | 73 ++---------- .../net/runelite/injector/InjectUtil.java | 104 +++++++++++++++--- .../net/runelite/injector/MixinInjector.java | 11 +- .../net/runelite/injector/raw/ScriptVM.java | 22 ++-- 6 files changed, 185 insertions(+), 94 deletions(-) diff --git a/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java b/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java index dcbbd91bac..6d9110a3b3 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java +++ b/deobfuscator/src/main/java/net/runelite/asm/ClassFile.java @@ -94,7 +94,7 @@ public class ClassFile public void accept(ClassVisitor visitor) { - String[] ints = interfaces.getInterfaces().stream().map(i -> i.getName()).toArray(String[]::new); + String[] ints = interfaces.getInterfaces().stream().map(Class::getName).toArray(String[]::new); visitor.visit(version, access, name.getName(), null, super_class.getName(), ints); visitor.visitSource(source, null); @@ -113,7 +113,7 @@ public class ClassFile for (Method method : methods) { - String[] exceptions = method.getExceptions().getExceptions().stream().map(cl -> cl.getName()).toArray(String[]::new); + String[] exceptions = method.getExceptions().getExceptions().stream().map(Class::getName).toArray(String[]::new); if (exceptions.length == 0) { exceptions = null; @@ -294,6 +294,20 @@ public class ClassFile return null; } + public Method findStaticMethod(String name, Signature type) + { + for (Method m : methods) + { + if (m.isStatic() && + m.getName().equals(name) && + m.getDescriptor().equals(type)) + { + return m; + } + } + return null; + } + public Method findMethod(String name) { for (Method m : methods) @@ -306,6 +320,18 @@ public class ClassFile return null; } + public Method findStaticMethod(String name) + { + for (Method m : methods) + { + if (m.isStatic() && m.getName().equals(name)) + { + return m; + } + } + return null; + } + public Method findMethodDeep(String name, Signature type) { Method m = findMethod(name, type); @@ -325,8 +351,8 @@ public class ClassFile public Method findMethodDeepStatic(String name, Signature type) { - Method m = findMethod(name, type); - if (m != null && m.isStatic()) + Method m = findStaticMethod(name, type); + if (m != null) { return m; } diff --git a/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java b/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java index 2c6ba531a5..416281c305 100644 --- a/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java +++ b/deobfuscator/src/main/java/net/runelite/asm/ClassGroup.java @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import net.runelite.asm.attributes.Code; +import net.runelite.asm.signature.Signature; public class ClassGroup { @@ -107,4 +108,38 @@ public class ClassGroup } } } + + public Method findStaticMethod(String name, Signature type) + { + Method m = null; + + for (ClassFile cf : classes) + { + m = cf.findStaticMethod(name, type); + + if (m != null) + { + break; + } + } + + return m; + } + + public Method findStaticMethod(String name) + { + Method m = null; + + for (ClassFile cf : classes) + { + m = cf.findStaticMethod(name); + + if (m != null) + { + break; + } + } + + return m; + } } 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 ad0e2a61ae..942d349729 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/Inject.java +++ b/injector-plugin/src/main/java/net/runelite/injector/Inject.java @@ -45,6 +45,7 @@ import net.runelite.asm.pool.Class; import net.runelite.asm.signature.Signature; import net.runelite.deob.DeobAnnotations; import net.runelite.deob.deobfuscators.arithmetic.DMath; +import static net.runelite.injector.InjectUtil.getFieldType; import net.runelite.injector.raw.ClearColorBuffer; import net.runelite.injector.raw.DrawAfterWidgets; import net.runelite.injector.raw.DrawMenu; @@ -71,15 +72,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); - private final ScriptVM scriptVM = new ScriptVM(this); - private final ClearColorBuffer clearColorBuffer = new ClearColorBuffer(this); - private final RenderDraw renderDraw = new RenderDraw(this); - private final Occluder occluder = new Occluder(this); - private final HidePlayerAttacks hidePlayerAttacks = new HidePlayerAttacks(this); // deobfuscated contains exports etc to apply to vanilla private final ClassGroup deobfuscated, vanilla; @@ -148,20 +141,6 @@ public class Inject return Type.getType("L" + c.getName().replace('.', '/') + ";", dimms); } - public Type getFieldType(Field f) - { - Type type = f.getType(); - - Annotation obfSignature = f.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE); - if (obfSignature != null) - { - //Annotation exists. Type was updated by us during deobfuscation - type = DeobAnnotations.getObfuscatedType(f); - } - - return type; - } - public Signature getMethodSignature(Method m) { Signature signature = m.getDescriptor(); @@ -227,7 +206,7 @@ public class Inject // Has to be done before mixins // well, can be done after really // but why do that when you can do it before - rasterizerHook.inject(); + new RasterizerHook(this).inject(); // requires interfaces to be injected mixinInjector.inject(); @@ -333,13 +312,13 @@ public class Inject getters.getInjectedGetters(), setters.getInjectedSetters(), invokes.getInjectedInvokers()); - drawAfterWidgets.inject(); - scriptVM.inject(); - clearColorBuffer.inject(); - renderDraw.inject(); - drawMenu.inject(); - occluder.inject(); - hidePlayerAttacks.inject(); + new DrawAfterWidgets(this).inject(); + new ScriptVM(this).inject(); + new ClearColorBuffer(this).inject(); + new RenderDraw(this).inject(); + new DrawMenu(this).inject(); + new Occluder(this).inject(); + new HidePlayerAttacks(this).inject(); } private java.lang.Class injectInterface(ClassFile cf, ClassFile other) @@ -457,36 +436,6 @@ public class Inject return null; } - public ClassFile toObClass(ClassFile deobClass) - { - String obfuscatedName = DeobAnnotations.getObfuscatedName(deobClass.getAnnotations()); - - for (ClassFile cf : vanilla.getClasses()) - { - if (cf.getName().equalsIgnoreCase(obfuscatedName)) - { - return cf; - } - } - - return null; - } - - public Field toObField(Field field) - { - String obfuscatedClassName = DeobAnnotations.getObfuscatedName(field.getClassFile().getAnnotations()); - String obfuscatedFieldName = DeobAnnotations.getObfuscatedName(field.getAnnotations()); // obfuscated name of field - Type type = getFieldType(field); - - ClassFile obfuscatedClass = vanilla.findClass(obfuscatedClassName); - assert obfuscatedClass != null; - - Field obfuscatedField = obfuscatedClass.findFieldDeep(obfuscatedFieldName, type); - assert obfuscatedField != null; - - return obfuscatedField; - } - Type deobfuscatedTypeToApiType(Type type) throws InjectionException { if (type.isPrimitive()) @@ -620,12 +569,12 @@ public class Inject return false; } - public ClassGroup getDeobfuscated() + public final ClassGroup getDeobfuscated() { return deobfuscated; } - public ClassGroup getVanilla() + public final ClassGroup getVanilla() { return vanilla; } diff --git a/injector-plugin/src/main/java/net/runelite/injector/InjectUtil.java b/injector-plugin/src/main/java/net/runelite/injector/InjectUtil.java index 1f0275110c..ff5022957e 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/InjectUtil.java +++ b/injector-plugin/src/main/java/net/runelite/injector/InjectUtil.java @@ -1,28 +1,100 @@ package net.runelite.injector; 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.annotation.Annotation; import net.runelite.asm.signature.Signature; import net.runelite.deob.DeobAnnotations; public class InjectUtil { - public static Method findStaticObMethod(Inject inject, String name) throws InjectionException + public static ClassFile toObClass(final ClassGroup vanilla, final ClassFile deobCf) throws InjectionException { - for (ClassFile c : inject.getVanilla().getClasses()) + final String obfuscatedName = DeobAnnotations.getObfuscatedName(deobCf.getAnnotations()); + final ClassFile obCf = vanilla.findClass(obfuscatedName); + + if (obCf == null) { - for (Method m : c.getMethods()) - { - if (!m.getName().equals(name)) - { - continue; - } - return m; - } + throw new InjectionException(String.format("ClassFile \"%s\" could not be found.", obfuscatedName)); } - throw new InjectionException(String.format("Method \"%s\" could not be found.", name)); + return obCf; + } + + public static Field toObField(final ClassGroup vanilla, final Field field) throws InjectionException + { + String obfuscatedClassName = DeobAnnotations.getObfuscatedName(field.getClassFile().getAnnotations()); + String obfuscatedFieldName = DeobAnnotations.getObfuscatedName(field.getAnnotations()); // obfuscated name of field + Type type = getFieldType(field); + + ClassFile obfuscatedClass = vanilla.findClass(obfuscatedClassName); + if (obfuscatedClass == null) + { + throw new InjectionException(String.format("ClassFile \"%s\" could not be found.", obfuscatedClassName)); + } + + Field obfuscatedField = obfuscatedClass.findFieldDeep(obfuscatedFieldName, type); + if (obfuscatedField == null) + { + throw new InjectionException(String.format("Field \"%s\" could not be found.", obfuscatedFieldName)); + } + + return obfuscatedField; + } + + public static Type getFieldType(final Field f) + { + Type type = f.getType(); + + Annotation obfSignature = f.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE); + if (obfSignature != null) + { + //Annotation exists. Type was updated by us during deobfuscation + type = DeobAnnotations.getObfuscatedType(f); + } + + return type; + } + + /** + * Find a static method in ClassGroup group. Check the class with name hint first. + * (useful for static methods which are in the class they belong to) + */ + public static Method findStaticMethod(final ClassGroup group, final String name, final String hint) throws InjectionException + { + final ClassFile cf = group.findClass(hint); + + if (cf == null) + { + throw new InjectionException(String.format("ClassFile \"%s\" could not be found.", hint)); + } + + Method m = cf.findStaticMethod(name); + + if (m == null) + { + m = group.findStaticMethod(name); + } + + return m; + } + + /** + * Find a static method in ClassGroup group. Throws exception if not found. + */ + public static Method findStaticMethod(final ClassGroup group, final String name) throws InjectionException + { + Method m = group.findStaticMethod(name); + + if (m == null) + { + throw new InjectionException(String.format("Static method \"%s\" could not be found.", name)); + } + + return m; } public static Method findMethod(Inject inject, String name) throws InjectionException @@ -48,7 +120,7 @@ public class InjectUtil String obfuscatedName = DeobAnnotations.getObfuscatedName(deob.getAnnotations()); Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(deob); - ClassFile ob = inject.toObClass(c); + ClassFile ob = toObClass(inject.getVanilla(), c); return ob.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : deob.getDescriptor()); } @@ -66,7 +138,7 @@ public class InjectUtil String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m); - ClassFile c2 = inject.toObClass(c); + ClassFile c2 = toObClass(inject.getVanilla(), c); return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor()); } @@ -89,7 +161,7 @@ public class InjectUtil String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m); - ClassFile c2 = inject.toObClass(c); + ClassFile c2 = toObClass(inject.getVanilla(), c); return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor()); } @@ -140,7 +212,7 @@ public class InjectUtil String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations()); - ClassFile c2 = inject.toObClass(c); + ClassFile c2 = toObClass(inject.getVanilla(), c); return c2.findField(obfuscatedName); } } @@ -156,7 +228,7 @@ public class InjectUtil String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations()); - ClassFile c2 = inject.toObClass(c); + ClassFile c2 = toObClass(inject.getVanilla(), c); return c2.findField(obfuscatedName); } } 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 815b3699aa..45acd543d1 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/MixinInjector.java +++ b/injector-plugin/src/main/java/net/runelite/injector/MixinInjector.java @@ -60,6 +60,8 @@ import net.runelite.asm.attributes.code.instructions.PutField; import net.runelite.asm.signature.Signature; import net.runelite.asm.visitors.ClassFileVisitor; import net.runelite.deob.DeobAnnotations; +import static net.runelite.injector.InjectUtil.toObClass; +import static net.runelite.injector.InjectUtil.toObField; import org.objectweb.asm.ClassReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -288,7 +290,7 @@ public class MixinInjector throw new InjectionException("Shadow of nonexistent field " + shadowName); } - Field obShadow = inject.toObField(shadowField); + Field obShadow = toObField(inject.getVanilla(), shadowField); assert obShadow != null; shadowFields.put(field.getPoolField(), obShadow); } @@ -559,7 +561,8 @@ public class MixinInjector .findClass(deobReturnType.getInternalName()); if (deobReturnTypeClassFile != null) { - ClassFile obReturnTypeClass = inject.toObClass(deobReturnTypeClassFile); + ClassFile obReturnTypeClass = toObClass(inject.getVanilla(), deobReturnTypeClassFile); + Instructions instructions = method.getCode().getInstructions(); ListIterator listIter = instructions.getInstructions().listIterator(); for (; listIter.hasNext(); ) @@ -641,7 +644,7 @@ public class MixinInjector if (deobCf != null) { - ClassFile obReturnTypeClass = inject.toObClass(deobCf); + ClassFile obReturnTypeClass = toObClass(inject.getVanilla(), deobCf); Type newType = new Type("L" + obReturnTypeClass.getName() + ";"); ((ANewArray) i).setType(newType); @@ -895,7 +898,7 @@ public class MixinInjector getter = (Number) an.getElement().getValue(); } - Field obField = inject.toObField(targetField); + Field obField = toObField(inject.getVanilla(), targetField); if (method.isStatic() != targetField.isStatic()) { diff --git a/injector-plugin/src/main/java/net/runelite/injector/raw/ScriptVM.java b/injector-plugin/src/main/java/net/runelite/injector/raw/ScriptVM.java index 9fe87975c1..c4f0987894 100644 --- a/injector-plugin/src/main/java/net/runelite/injector/raw/ScriptVM.java +++ b/injector-plugin/src/main/java/net/runelite/injector/raw/ScriptVM.java @@ -28,6 +28,7 @@ import java.util.HashSet; import java.util.ListIterator; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; +import net.runelite.asm.ClassGroup; import net.runelite.asm.Field; import net.runelite.asm.Method; import net.runelite.asm.Type; @@ -53,9 +54,9 @@ import net.runelite.asm.execution.MethodContext; import net.runelite.asm.execution.StackContext; import net.runelite.deob.DeobAnnotations; import net.runelite.injector.Inject; -import net.runelite.injector.InjectUtil; import static net.runelite.injector.InjectUtil.findDeobField; import static net.runelite.injector.InjectUtil.findObField; +import static net.runelite.injector.InjectUtil.findStaticMethod; import net.runelite.injector.InjectionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -78,6 +79,8 @@ public class ScriptVM private void injectScriptVMHooks() throws InjectionException { + final ClassGroup vanilla = inject.getVanilla(); + /* This hooks local variable assignments in the copied version of runScript: - The currently executing script > client.currentScript @@ -105,13 +108,16 @@ public class ScriptVM if_icmpge L52 */ - String scriptObName = DeobAnnotations.getObfuscatedName(inject.getDeobfuscated().findClass("Script").getAnnotations()); - Method runScript = InjectUtil.findStaticObMethod(inject, "copy$runScript0"); - Method vmExecuteOpcode = InjectUtil.findStaticObMethod(inject, "vmExecuteOpcode"); - Field scriptInstructions = findDeobField(inject, "opcodes"); - Field scriptStatePC = findDeobField(inject, "pc"); - Field currentScriptField = findObField(inject, "currentScript"); - Field currentScriptPCField = findObField(inject, "currentScriptPC"); + final String scriptObName = DeobAnnotations.getObfuscatedName(inject.getDeobfuscated().findClass("Script").getAnnotations()); + + final Method runScript = findStaticMethod(vanilla, "copy$runScript0"); + final Method vmExecuteOpcode = findStaticMethod(vanilla, "vmExecuteOpcode"); + + final Field scriptInstructions = findDeobField(inject, "opcodes"); + final Field scriptStatePC = findDeobField(inject, "pc"); + + final Field currentScriptField = findObField(inject, "currentScript"); + final Field currentScriptPCField = findObField(inject, "currentScriptPC"); Execution e = new Execution(inject.getVanilla()); e.addMethod(runScript);