Injector: Tiny bit of cleanup

This commit is contained in:
Lucwousin
2019-07-10 01:51:18 +02:00
parent 91fbcf3d6b
commit 7a4e213e25
6 changed files with 185 additions and 94 deletions

View File

@@ -94,7 +94,7 @@ public class ClassFile
public void accept(ClassVisitor visitor) 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.visit(version, access, name.getName(), null, super_class.getName(), ints);
visitor.visitSource(source, null); visitor.visitSource(source, null);
@@ -113,7 +113,7 @@ public class ClassFile
for (Method method : methods) 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) if (exceptions.length == 0)
{ {
exceptions = null; exceptions = null;
@@ -294,6 +294,20 @@ public class ClassFile
return null; 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) public Method findMethod(String name)
{ {
for (Method m : methods) for (Method m : methods)
@@ -306,6 +320,18 @@ public class ClassFile
return null; 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) public Method findMethodDeep(String name, Signature type)
{ {
Method m = findMethod(name, type); Method m = findMethod(name, type);
@@ -325,8 +351,8 @@ public class ClassFile
public Method findMethodDeepStatic(String name, Signature type) public Method findMethodDeepStatic(String name, Signature type)
{ {
Method m = findMethod(name, type); Method m = findStaticMethod(name, type);
if (m != null && m.isStatic()) if (m != null)
{ {
return m; return m;
} }

View File

@@ -30,6 +30,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import net.runelite.asm.attributes.Code; import net.runelite.asm.attributes.Code;
import net.runelite.asm.signature.Signature;
public class ClassGroup 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;
}
} }

View File

@@ -45,6 +45,7 @@ import net.runelite.asm.pool.Class;
import net.runelite.asm.signature.Signature; import net.runelite.asm.signature.Signature;
import net.runelite.deob.DeobAnnotations; import net.runelite.deob.DeobAnnotations;
import net.runelite.deob.deobfuscators.arithmetic.DMath; 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.ClearColorBuffer;
import net.runelite.injector.raw.DrawAfterWidgets; import net.runelite.injector.raw.DrawAfterWidgets;
import net.runelite.injector.raw.DrawMenu; import net.runelite.injector.raw.DrawMenu;
@@ -71,15 +72,7 @@ public class Inject
private final InjectInvoker invokes = new InjectInvoker(this); private final InjectInvoker invokes = new InjectInvoker(this);
private final InjectConstruct construct = new InjectConstruct(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 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 // deobfuscated contains exports etc to apply to vanilla
private final ClassGroup deobfuscated, vanilla; private final ClassGroup deobfuscated, vanilla;
@@ -148,20 +141,6 @@ public class Inject
return Type.getType("L" + c.getName().replace('.', '/') + ";", dimms); 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) public Signature getMethodSignature(Method m)
{ {
Signature signature = m.getDescriptor(); Signature signature = m.getDescriptor();
@@ -227,7 +206,7 @@ public class Inject
// Has to be done before mixins // Has to be done before mixins
// well, can be done after really // well, can be done after really
// but why do that when you can do it before // but why do that when you can do it before
rasterizerHook.inject(); new RasterizerHook(this).inject();
// requires interfaces to be injected // requires interfaces to be injected
mixinInjector.inject(); mixinInjector.inject();
@@ -333,13 +312,13 @@ public class Inject
getters.getInjectedGetters(), getters.getInjectedGetters(),
setters.getInjectedSetters(), invokes.getInjectedInvokers()); setters.getInjectedSetters(), invokes.getInjectedInvokers());
drawAfterWidgets.inject(); new DrawAfterWidgets(this).inject();
scriptVM.inject(); new ScriptVM(this).inject();
clearColorBuffer.inject(); new ClearColorBuffer(this).inject();
renderDraw.inject(); new RenderDraw(this).inject();
drawMenu.inject(); new DrawMenu(this).inject();
occluder.inject(); new Occluder(this).inject();
hidePlayerAttacks.inject(); new HidePlayerAttacks(this).inject();
} }
private java.lang.Class injectInterface(ClassFile cf, ClassFile other) private java.lang.Class injectInterface(ClassFile cf, ClassFile other)
@@ -457,36 +436,6 @@ public class Inject
return null; 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 Type deobfuscatedTypeToApiType(Type type) throws InjectionException
{ {
if (type.isPrimitive()) if (type.isPrimitive())
@@ -620,12 +569,12 @@ public class Inject
return false; return false;
} }
public ClassGroup getDeobfuscated() public final ClassGroup getDeobfuscated()
{ {
return deobfuscated; return deobfuscated;
} }
public ClassGroup getVanilla() public final ClassGroup getVanilla()
{ {
return vanilla; return vanilla;
} }

View File

@@ -1,28 +1,100 @@
package net.runelite.injector; package net.runelite.injector;
import net.runelite.asm.ClassFile; import net.runelite.asm.ClassFile;
import net.runelite.asm.ClassGroup;
import net.runelite.asm.Field; import net.runelite.asm.Field;
import net.runelite.asm.Method; 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.asm.signature.Signature;
import net.runelite.deob.DeobAnnotations; import net.runelite.deob.DeobAnnotations;
public class InjectUtil 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()) throw new InjectionException(String.format("ClassFile \"%s\" could not be found.", obfuscatedName));
{
if (!m.getName().equals(name))
{
continue;
}
return m;
}
} }
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 public static Method findMethod(Inject inject, String name) throws InjectionException
@@ -48,7 +120,7 @@ public class InjectUtil
String obfuscatedName = DeobAnnotations.getObfuscatedName(deob.getAnnotations()); String obfuscatedName = DeobAnnotations.getObfuscatedName(deob.getAnnotations());
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(deob); 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()); return ob.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : deob.getDescriptor());
} }
@@ -66,7 +138,7 @@ public class InjectUtil
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m); 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()); return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
} }
@@ -89,7 +161,7 @@ public class InjectUtil
String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations()); String obfuscatedName = DeobAnnotations.getObfuscatedName(m.getAnnotations());
Signature obfuscatedSignature = DeobAnnotations.getObfuscatedSignature(m); 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()); return c2.findMethod(obfuscatedName, (obfuscatedSignature != null) ? obfuscatedSignature : m.getDescriptor());
} }
@@ -140,7 +212,7 @@ public class InjectUtil
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations()); String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
ClassFile c2 = inject.toObClass(c); ClassFile c2 = toObClass(inject.getVanilla(), c);
return c2.findField(obfuscatedName); return c2.findField(obfuscatedName);
} }
} }
@@ -156,7 +228,7 @@ public class InjectUtil
String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations()); String obfuscatedName = DeobAnnotations.getObfuscatedName(f.getAnnotations());
ClassFile c2 = inject.toObClass(c); ClassFile c2 = toObClass(inject.getVanilla(), c);
return c2.findField(obfuscatedName); return c2.findField(obfuscatedName);
} }
} }

View File

@@ -60,6 +60,8 @@ import net.runelite.asm.attributes.code.instructions.PutField;
import net.runelite.asm.signature.Signature; import net.runelite.asm.signature.Signature;
import net.runelite.asm.visitors.ClassFileVisitor; import net.runelite.asm.visitors.ClassFileVisitor;
import net.runelite.deob.DeobAnnotations; 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.objectweb.asm.ClassReader;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -288,7 +290,7 @@ public class MixinInjector
throw new InjectionException("Shadow of nonexistent field " + shadowName); throw new InjectionException("Shadow of nonexistent field " + shadowName);
} }
Field obShadow = inject.toObField(shadowField); Field obShadow = toObField(inject.getVanilla(), shadowField);
assert obShadow != null; assert obShadow != null;
shadowFields.put(field.getPoolField(), obShadow); shadowFields.put(field.getPoolField(), obShadow);
} }
@@ -559,7 +561,8 @@ public class MixinInjector
.findClass(deobReturnType.getInternalName()); .findClass(deobReturnType.getInternalName());
if (deobReturnTypeClassFile != null) if (deobReturnTypeClassFile != null)
{ {
ClassFile obReturnTypeClass = inject.toObClass(deobReturnTypeClassFile); ClassFile obReturnTypeClass = toObClass(inject.getVanilla(), deobReturnTypeClassFile);
Instructions instructions = method.getCode().getInstructions(); Instructions instructions = method.getCode().getInstructions();
ListIterator<Instruction> listIter = instructions.getInstructions().listIterator(); ListIterator<Instruction> listIter = instructions.getInstructions().listIterator();
for (; listIter.hasNext(); ) for (; listIter.hasNext(); )
@@ -641,7 +644,7 @@ public class MixinInjector
if (deobCf != null) if (deobCf != null)
{ {
ClassFile obReturnTypeClass = inject.toObClass(deobCf); ClassFile obReturnTypeClass = toObClass(inject.getVanilla(), deobCf);
Type newType = new Type("L" + obReturnTypeClass.getName() + ";"); Type newType = new Type("L" + obReturnTypeClass.getName() + ";");
((ANewArray) i).setType(newType); ((ANewArray) i).setType(newType);
@@ -895,7 +898,7 @@ public class MixinInjector
getter = (Number) an.getElement().getValue(); getter = (Number) an.getElement().getValue();
} }
Field obField = inject.toObField(targetField); Field obField = toObField(inject.getVanilla(), targetField);
if (method.isStatic() != targetField.isStatic()) if (method.isStatic() != targetField.isStatic())
{ {

View File

@@ -28,6 +28,7 @@ import java.util.HashSet;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import net.runelite.asm.ClassGroup;
import net.runelite.asm.Field; import net.runelite.asm.Field;
import net.runelite.asm.Method; import net.runelite.asm.Method;
import net.runelite.asm.Type; import net.runelite.asm.Type;
@@ -53,9 +54,9 @@ import net.runelite.asm.execution.MethodContext;
import net.runelite.asm.execution.StackContext; import net.runelite.asm.execution.StackContext;
import net.runelite.deob.DeobAnnotations; import net.runelite.deob.DeobAnnotations;
import net.runelite.injector.Inject; import net.runelite.injector.Inject;
import net.runelite.injector.InjectUtil;
import static net.runelite.injector.InjectUtil.findDeobField; import static net.runelite.injector.InjectUtil.findDeobField;
import static net.runelite.injector.InjectUtil.findObField; import static net.runelite.injector.InjectUtil.findObField;
import static net.runelite.injector.InjectUtil.findStaticMethod;
import net.runelite.injector.InjectionException; import net.runelite.injector.InjectionException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -78,6 +79,8 @@ public class ScriptVM
private void injectScriptVMHooks() throws InjectionException private void injectScriptVMHooks() throws InjectionException
{ {
final ClassGroup vanilla = inject.getVanilla();
/* /*
This hooks local variable assignments in the copied version of runScript: This hooks local variable assignments in the copied version of runScript:
- The currently executing script > client.currentScript - The currently executing script > client.currentScript
@@ -105,13 +108,16 @@ public class ScriptVM
if_icmpge L52 if_icmpge L52
*/ */
String scriptObName = DeobAnnotations.getObfuscatedName(inject.getDeobfuscated().findClass("Script").getAnnotations()); final String scriptObName = DeobAnnotations.getObfuscatedName(inject.getDeobfuscated().findClass("Script").getAnnotations());
Method runScript = InjectUtil.findStaticObMethod(inject, "copy$runScript0");
Method vmExecuteOpcode = InjectUtil.findStaticObMethod(inject, "vmExecuteOpcode"); final Method runScript = findStaticMethod(vanilla, "copy$runScript0");
Field scriptInstructions = findDeobField(inject, "opcodes"); final Method vmExecuteOpcode = findStaticMethod(vanilla, "vmExecuteOpcode");
Field scriptStatePC = findDeobField(inject, "pc");
Field currentScriptField = findObField(inject, "currentScript"); final Field scriptInstructions = findDeobField(inject, "opcodes");
Field currentScriptPCField = findObField(inject, "currentScriptPC"); final Field scriptStatePC = findDeobField(inject, "pc");
final Field currentScriptField = findObField(inject, "currentScript");
final Field currentScriptPCField = findObField(inject, "currentScriptPC");
Execution e = new Execution(inject.getVanilla()); Execution e = new Execution(inject.getVanilla());
e.addMethod(runScript); e.addMethod(runScript);