Fix mixins with multiple targets, turn injectutil into a interface

This commit is contained in:
Lucwousin
2019-10-30 09:35:21 +01:00
parent b360349dd7
commit 8f2adb8185
5 changed files with 88 additions and 116 deletions

View File

@@ -31,7 +31,7 @@ import net.runelite.asm.pool.Class;
import net.runelite.asm.signature.Signature;
import net.runelite.deob.DeobAnnotations;
public class InjectUtil
public interface InjectUtil
{
/**
* Finds a static method in deob and converts it to ob
@@ -40,7 +40,7 @@ public class InjectUtil
* @param name The name of the method you want to find
* @return The obfuscated version of the found method
*/
public static Method findStaticMethod(InjectData data, String name) throws Injexception
static Method findStaticMethod(InjectData data, String name) throws Injexception
{
return findStaticMethod(data, name, null, null);
}
@@ -55,10 +55,10 @@ public class InjectUtil
*
* @return The obfuscated version of the found method
*/
public static Method findStaticMethod(InjectData data, String name, String classHint, Signature sig) throws Injexception
static Method findStaticMethod(InjectData data, String name, String classHint, Signature sig) throws Injexception
{
final ClassGroup deob = data.getDeobfuscated();
Method method = null;
Method method;
if (classHint != null)
{
@@ -95,7 +95,7 @@ public class InjectUtil
throw new Injexception("Static method " + name + " doesn't exist");
}
private static ClassFile findClassOrThrow(ClassGroup group, String name) throws Injexception
static ClassFile findClassOrThrow(ClassGroup group, String name) throws Injexception
{
ClassFile clazz = group.findClass(name);
if (clazz == null)
@@ -112,12 +112,12 @@ public class InjectUtil
*
* @return The obfuscated version of the found method
*/
public static Method findStaticMethod(InjectData data, net.runelite.asm.pool.Method pool) throws Injexception
static Method findStaticMethod(InjectData data, net.runelite.asm.pool.Method pool) throws Injexception
{
return findStaticMethod(data, pool.getName(), pool.getClazz().getName(), pool.getType());
}
public static Method findMethodWithArgs(InjectData data, String name, String hintClass, Signature sig) throws Injexception
static Method findMethodWithArgs(InjectData data, String name, String hintClass, Signature sig) throws Injexception
{
final ClassGroup deob = data.getDeobfuscated();
if (hintClass != null)
@@ -137,7 +137,7 @@ public class InjectUtil
throw new Injexception("Method called " + name + " with args matching " + sig + " doesn't exist");
}
public static Method findMethodWithArgsDeep(InjectData data, ClassFile clazz, String name, Signature sig) throws Injexception
static Method findMethodWithArgsDeep(InjectData data, ClassFile clazz, String name, Signature sig) throws Injexception
{
do
for (Method m : clazz.getMethods())
@@ -151,19 +151,7 @@ public class InjectUtil
/**
* Fail-fast implementation of ClassGroup.findStaticMethod
*/
public static Method findStaticMethod(ClassGroup group, String name) throws Injexception
{
Method m = group.findStaticMethod(name);
if (m == null)
throw new Injexception(String.format("Method %s couldn't be found", name));
return m;
}
/**
* Fail-fast implementation of ClassGroup.findStaticMethod
*/
public static Method findStaticMethod(ClassGroup group, String name, Signature type) throws Injexception
static Method findStaticMethod(ClassGroup group, String name, Signature type) throws Injexception
{
Method m = group.findStaticMethod(name, type);
if (m == null)
@@ -176,20 +164,7 @@ public class InjectUtil
/**
* Fail-fast implementation of ClassFile.findMethodDeep
*/
public static Method findMethodDeep(ClassFile clazz, String name) throws Injexception
{
Method m = clazz.findMethodDeep(name);
if (m == null)
{
throw new Injexception(String.format("Method %s couldn't be found", name));
}
return m;
}
/**
* Fail-fast implementation of ClassFile.findMethodDeep
*/
public static Method findMethodDeep(ClassFile clazz, String name, Signature type) throws Injexception
static Method findMethodDeep(ClassFile clazz, String name, Signature type) throws Injexception
{
Method m = clazz.findMethodDeep(name, type);
if (m == null)
@@ -204,7 +179,7 @@ public class InjectUtil
*
* well...
*/
public static Field findStaticField(ClassGroup group, String name) throws Injexception
static Field findStaticField(ClassGroup group, String name) throws Injexception
{
for (ClassFile clazz : group)
{
@@ -227,10 +202,10 @@ public class InjectUtil
*
* @return The obfuscated version of the found field
*/
public static Field findStaticField(InjectData data, String name, String classHint, Type type) throws Injexception
static Field findStaticField(InjectData data, String name, String classHint, Type type) throws Injexception
{
final ClassGroup deob = data.getDeobfuscated();
Field field = null;
Field field;
if (classHint != null)
{
@@ -279,7 +254,7 @@ public class InjectUtil
*
* @return The obfuscated version of the found field
*/
public static Field findStaticField(InjectData data, net.runelite.asm.pool.Field pool) throws Injexception
static Field findStaticField(InjectData data, net.runelite.asm.pool.Field pool) throws Injexception
{
return findStaticField(data, pool.getName(), pool.getClazz().getName(), pool.getType());
}
@@ -287,7 +262,7 @@ public class InjectUtil
/**
* Fail-fast implementation of ClassGroup.findFieldDeep
*/
public static Field findFieldDeep(ClassFile clazz, String name) throws Injexception
static Field findFieldDeep(ClassFile clazz, String name) throws Injexception
{
do
{
@@ -301,13 +276,13 @@ public class InjectUtil
throw new Injexception("Couldn't find field " + name);
}
public static Field findField(InjectData data, String name, String hintClass) throws Injexception
static Field findField(InjectData data, String name, String hintClass) throws Injexception
{
final ClassGroup deob = data.getDeobfuscated();
return data.toVanilla(findField(deob, name, hintClass));
}
public static Field findField(ClassGroup group, String name, String hintClass) throws Injexception
static Field findField(ClassGroup group, String name, String hintClass) throws Injexception
{
Field field;
if (hintClass != null)
@@ -333,12 +308,12 @@ public class InjectUtil
throw new Injexception("Field " + name + " doesn't exist");
}
public static ClassFile fromApiMethod(InjectData data, RSApiMethod apiMethod)
static ClassFile fromApiMethod(InjectData data, RSApiMethod apiMethod)
{
return data.toVanilla(data.toDeob(apiMethod.getClazz().getName()));
}
public static Signature apiToDeob(InjectData data, Signature api)
static Signature apiToDeob(InjectData data, Signature api)
{
return new Signature.Builder()
.setReturnType(apiToDeob(data, api.getReturnValue()))
@@ -349,7 +324,7 @@ public class InjectUtil
).build();
}
public static Type apiToDeob(InjectData data, Type api)
static Type apiToDeob(InjectData data, Type api)
{
if (api.isPrimitive())
{
@@ -392,7 +367,7 @@ public class InjectUtil
return api;
}
public static Type deobToVanilla(InjectData data, Type deobT)
static Type deobToVanilla(InjectData data, Type deobT)
{
if (deobT.isPrimitive())
{
@@ -408,12 +383,12 @@ public class InjectUtil
return Type.getType("L" + data.toVanilla(deobClass).getName() + ";", deobT.getDimensions());
}
public static boolean apiToDeobSigEquals(InjectData data, Signature deobSig, Signature apiSig)
static boolean apiToDeobSigEquals(InjectData data, Signature deobSig, Signature apiSig)
{
return deobSig.equals(apiToDeob(data, apiSig));
}
public static boolean argsMatch(Signature a, Signature b)
static boolean argsMatch(Signature a, Signature b)
{
List<Type> aa = a.getArguments();
List<Type> bb = b.getArguments();
@@ -439,7 +414,7 @@ public class InjectUtil
*
* If the annotation doesn't exist return the current name instead.
*/
public static <T extends Annotated & Named> String getObfuscatedName(T from)
static <T extends Annotated & Named> String getObfuscatedName(T from)
{
Annotation name = from.getAnnotations().find(DeobAnnotations.OBFUSCATED_NAME);
return name == null ? from.getName() : name.getElement().getString();
@@ -448,7 +423,7 @@ public class InjectUtil
/**
* Gets the value of the @Export annotation on the object.
*/
public static String getExportedName(Annotated from)
static String getExportedName(Annotated from)
{
Annotation export = from.getAnnotations().find(DeobAnnotations.EXPORT);
return export == null ? null : export.getElement().getString();
@@ -457,7 +432,7 @@ public class InjectUtil
/**
* Creates the correct load instruction for the variable with Type type and var index index.
*/
public static Instruction createLoadForTypeIndex(Instructions instructions, Type type, int index)
static Instruction createLoadForTypeIndex(Instructions instructions, Type type, int index)
{
if (type.getDimensions() > 0 || !type.isPrimitive())
{
@@ -486,7 +461,7 @@ public class InjectUtil
/**
* Creates the right return instruction for an object with Type type
*/
public static Instruction createReturnForType(Instructions instructions, Type type)
static Instruction createReturnForType(Instructions instructions, Type type)
{
if (!type.isPrimitive())
{
@@ -514,7 +489,7 @@ public class InjectUtil
}
}
public static Instruction createInvokeFor(Instructions instructions, net.runelite.asm.pool.Method method, boolean isStatic)
static Instruction createInvokeFor(Instructions instructions, net.runelite.asm.pool.Method method, boolean isStatic)
{
if (isStatic)
{
@@ -525,4 +500,14 @@ public class InjectUtil
return new InvokeVirtual(instructions, method);
}
}
/**
* Legit fuck annotations
*/
static ClassFile getVanillaClassFromAnnotationString(InjectData data, Annotation annotation)
{
Object v = annotation.getElement().getValue();
String str = ((org.objectweb.asm.Type) v).getInternalName();
return data.toVanilla(data.toDeob(str));
}
}

View File

@@ -19,6 +19,7 @@ import net.runelite.asm.Method;
import net.runelite.asm.Type;
import net.runelite.asm.attributes.Code;
import net.runelite.asm.attributes.annotation.Annotation;
import net.runelite.asm.attributes.annotation.ArrayElement;
import net.runelite.asm.attributes.code.Instruction;
import net.runelite.asm.attributes.code.Instructions;
import net.runelite.asm.attributes.code.instruction.types.FieldInstruction;
@@ -28,7 +29,6 @@ import net.runelite.asm.attributes.code.instruction.types.PushConstantInstructio
import net.runelite.asm.attributes.code.instruction.types.ReturnInstruction;
import net.runelite.asm.attributes.code.instructions.ALoad;
import net.runelite.asm.attributes.code.instructions.ANewArray;
import net.runelite.asm.attributes.code.instructions.CheckCast;
import net.runelite.asm.attributes.code.instructions.GetField;
import net.runelite.asm.attributes.code.instructions.ILoad;
import net.runelite.asm.attributes.code.instructions.InvokeDynamic;
@@ -78,7 +78,7 @@ public class MixinInjector extends AbstractInjector
for (Map.Entry<Provider<ClassFile>, List<ClassFile>> entry : mixinTargets.entrySet())
{
findShadowFields(entry.getKey(), entry.getValue());
findShadowFields(entry.getKey());
}
log.info("Shadowed {} fields", shadowFields.size());
@@ -106,8 +106,6 @@ public class MixinInjector extends AbstractInjector
// to make sure we aren't changing code in all classes at once
if (MIXIN.equals(annotation.getType()))
{
final String str = ((org.objectweb.asm.Type) annotation.getElement().getValue()).getInternalName();
builder.put(
new Provider<ClassFile>()
{
@@ -117,7 +115,7 @@ public class MixinInjector extends AbstractInjector
return mixinClass;
}
},
ImmutableList.of(inject.toVanilla(inject.toDeob(str)))
ImmutableList.of(InjectUtil.getVanillaClassFromAnnotationString(inject, annotation))
);
}
else if (MIXINS.equals(annotation.getType()))
@@ -141,15 +139,18 @@ public class MixinInjector extends AbstractInjector
}
};
final List<ClassFile> targetClasses = annotation
.getElements()
.stream()
.map(e -> ((org.objectweb.asm.Type) e.getValue()).getInternalName())
.map(inject::toDeob)
.map(inject::toVanilla)
.collect(ImmutableList.toImmutableList());
assert annotation.getElement() instanceof ArrayElement;
ArrayElement arr = (ArrayElement) annotation.getElement();
builder.put(mixinProvider, targetClasses);
ImmutableList.Builder<ClassFile> b = ImmutableList.builder();
for (Object ob : arr)
{
assert ob instanceof Annotation;
b.add(InjectUtil.getVanillaClassFromAnnotationString(inject, (Annotation) ob));
}
builder.put(mixinProvider, b.build());
}
}
}
@@ -195,7 +196,7 @@ public class MixinInjector extends AbstractInjector
}
}
private void findShadowFields(Provider<ClassFile> mixinProvider, List<ClassFile> targetClasses) throws Injexception
private void findShadowFields(Provider<ClassFile> mixinProvider) throws Injexception
{
final ClassFile mixinClass = mixinProvider.get();
@@ -267,7 +268,7 @@ public class MixinInjector extends AbstractInjector
throw new Injexception("Mixin methods cannot have more parameters than their corresponding ob method");
}
Method copy = new Method(targetClass, "copy$" + copiedName, sourceMethod.getObfuscatedSignature());
Method copy = new Method(targetClass, "copy$" + copiedName, sourceMethod.getDescriptor());
moveCode(copy, sourceMethod.getCode());
copy.setAccessFlags(sourceMethod.getAccessFlags());
copy.setPublic();
@@ -444,32 +445,32 @@ public class MixinInjector extends AbstractInjector
throw new Injexception("Mixin methods cannot have more parameters than their corresponding ob method");
}
Type returnType = mixinMethod.getDescriptor().getReturnValue();
Type deobReturnType = InjectUtil.apiToDeob(inject, returnType);
if (!returnType.equals(deobReturnType))
{
ClassFile deobReturnTypeClassFile = inject.getDeobfuscated()
.findClass(deobReturnType.getInternalName());
if (deobReturnTypeClassFile != null)
{
ClassFile obReturnTypeClass = inject.toVanilla(deobReturnTypeClassFile);
//Type returnType = mixinMethod.getDescriptor().getReturnValue();
//Type deobReturnType = InjectUtil.apiToDeob(inject, returnType);
//if (!returnType.equals(deobReturnType))
//{
// ClassFile deobReturnTypeClassFile = inject.getDeobfuscated()
// .findClass(deobReturnType.getInternalName());
// if (deobReturnTypeClassFile != null)
// {
// ClassFile obReturnTypeClass = inject.toVanilla(deobReturnTypeClassFile);
Instructions instructions = mixinMethod.getCode().getInstructions();
ListIterator<Instruction> listIter = instructions.listIterator();
while (listIter.hasNext())
{
Instruction instr = listIter.next();
if (instr instanceof ReturnInstruction)
{
listIter.previous();
CheckCast checkCast = new CheckCast(instructions);
checkCast.setType(new Type(obReturnTypeClass.getName()));
listIter.add(checkCast);
listIter.next();
}
}
}
}
// Instructions instructions = mixinMethod.getCode().getInstructions();
// ListIterator<Instruction> listIter = instructions.listIterator();
// while (listIter.hasNext())
// {
// Instruction instr = listIter.next();
// if (instr instanceof ReturnInstruction)
// {
// listIter.previous();
// CheckCast checkCast = new CheckCast(instructions);
// checkCast.setType(new Type(obReturnTypeClass.getName()));
// listIter.add(checkCast);
// listIter.next();
// }
// }
// }
//}
moveCode(obMethod, mixinMethod.getCode());

View File

@@ -10,7 +10,7 @@ public class RSApiClassVisitor extends ClassVisitor
{
private final RSApiClass apiClass;
public RSApiClassVisitor(RSApiClass apiClass)
RSApiClassVisitor(RSApiClass apiClass)
{
super(Opcodes.ASM5);
this.apiClass = apiClass;

View File

@@ -1,42 +1,27 @@
package com.openosrs.injector.rsapi;
import net.runelite.asm.Type;
import net.runelite.asm.attributes.annotation.Annotation;
import net.runelite.asm.attributes.annotation.Element;
import net.runelite.asm.attributes.annotation.SimpleElement;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Opcodes;
public class RSApiMethodAnnotationVisitor extends AnnotationVisitor
{
private final RSApiMethod method;
private final Type type;
private final Annotation annotation;
public RSApiMethodAnnotationVisitor(RSApiMethod method, Type type)
RSApiMethodAnnotationVisitor(Annotation annotation)
{
super(Opcodes.ASM5);
this.method = method;
this.type = type;
annotation = new Annotation(method.getAnnotations());
annotation.setType(type);
this.annotation = annotation;
}
@Override
public void visit(String name, Object value)
{
Element element = new Element(annotation);
element.setName(name);
element.setValue(value);
Element element = new SimpleElement(name, value);
annotation.addElement(element);
}
@Override
public void visitEnd()
{
method.getAnnotations().addAnnotation(annotation);
}
}

View File

@@ -1,6 +1,7 @@
package com.openosrs.injector.rsapi;
import net.runelite.asm.Type;
import net.runelite.asm.attributes.annotation.Annotation;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -17,8 +18,8 @@ public class RSApiMethodVisitor extends MethodVisitor
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible)
{
final Type type = new Type(descriptor);
return new RSApiMethodAnnotationVisitor(method, type);
Annotation annotation = new Annotation(new Type(descriptor));
this.method.getAnnotations().addAnnotation(annotation);
return new RSApiMethodAnnotationVisitor(annotation);
}
}