Search in sources :

Example 11 with Annotation

use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.

the class ConstantParameter method annotateObfuscatedSignature.

private void annotateObfuscatedSignature(ConstantMethodParameter parameter) {
    for (Method m : parameter.methods) {
        Object value = parameter.values.get(0);
        Annotations annotations = m.getAnnotations();
        Annotation obfuscatedSignature = annotations.find(DeobAnnotations.OBFUSCATED_SIGNATURE);
        if (obfuscatedSignature != null && obfuscatedSignature.getElements().size() == 2) {
            // already annotated
            continue;
        }
        if (obfuscatedSignature == null) {
            obfuscatedSignature = annotations.addAnnotation(DeobAnnotations.OBFUSCATED_SIGNATURE, "signature", m.getDescriptor().toString());
        }
        // Add garbage value
        Element element = new Element(obfuscatedSignature);
        element.setName("garbageValue");
        element.setValue(value.toString());
        obfuscatedSignature.addElement(element);
    }
}
Also used : Annotations(net.runelite.asm.attributes.Annotations) DeobAnnotations(net.runelite.deob.DeobAnnotations) Element(net.runelite.asm.attributes.annotation.Element) Method(net.runelite.asm.Method) Annotation(net.runelite.asm.attributes.annotation.Annotation)

Example 12 with Annotation

use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.

the class AnnotationTest method testAnnotation.

@Test
public void testAnnotation() throws IOException {
    InputStream in = this.getClass().getClassLoader().getResourceAsStream("net/runelite/asm/annotations/TestClass.class");
    Assert.assertNotNull(in);
    ClassGroup group = new ClassGroup();
    ClassFile cf = ClassUtil.loadClass(in);
    group.addClass(cf);
    byte[] out = JarUtil.writeClass(group, cf);
    // parse it again
    cf = ClassUtil.loadClass(new ByteArrayInputStream(out));
    Method method = cf.getMethods().get(1);
    Assert.assertEquals("method1", method.getName());
    Annotations annotations = method.getAnnotations();
    Assert.assertNotNull(annotations);
    Optional<Annotation> annotation = annotations.getAnnotations().stream().filter(a -> a.getType().equals(new Type("Lnet/runelite/asm/annotations/MyAnnotation;"))).findFirst();
    Assert.assertTrue(annotation.isPresent());
    Annotation an = annotation.get();
    List<Element> elements = an.getElements();
    Assert.assertEquals(1, elements.size());
    Element element = elements.get(0);
    Assert.assertEquals("value", element.getName());
    Assert.assertEquals("method1", element.getValue());
}
Also used : Annotations(net.runelite.asm.attributes.Annotations) IOException(java.io.IOException) Test(org.junit.Test) Type(net.runelite.asm.Type) ClassGroup(net.runelite.asm.ClassGroup) JarUtil(net.runelite.deob.util.JarUtil) List(java.util.List) ClassFile(net.runelite.asm.ClassFile) Annotation(net.runelite.asm.attributes.annotation.Annotation) ByteArrayInputStream(java.io.ByteArrayInputStream) Method(net.runelite.asm.Method) ClassUtil(net.runelite.asm.ClassUtil) Element(net.runelite.asm.attributes.annotation.Element) Optional(java.util.Optional) Assert(org.junit.Assert) InputStream(java.io.InputStream) ClassFile(net.runelite.asm.ClassFile) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Element(net.runelite.asm.attributes.annotation.Element) Method(net.runelite.asm.Method) Annotation(net.runelite.asm.attributes.annotation.Annotation) Type(net.runelite.asm.Type) Annotations(net.runelite.asm.attributes.Annotations) ByteArrayInputStream(java.io.ByteArrayInputStream) ClassGroup(net.runelite.asm.ClassGroup) Test(org.junit.Test)

Example 13 with Annotation

use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.

the class AnnotationCopier method copy.

private void copy(Annotations an, Annotations an2) {
    for (Annotation a : an2.getAnnotations()) {
        if (isType(a.getType())) {
            an2.removeAnnotation(a);
        }
    }
    for (Annotation a : an.getAnnotations()) {
        if (!isType(a.getType()))
            continue;
        Annotation a2 = new Annotation(an2);
        a2.setType(a.getType());
        for (Element element : a.getElements()) {
            Element element2 = new Element(a2);
            element2.setName(element.getName());
            element2.setValue(element.getValue());
            a2.addElement(element2);
        }
        an2.addAnnotation(a2);
    }
}
Also used : Element(net.runelite.asm.attributes.annotation.Element) Annotation(net.runelite.asm.attributes.annotation.Annotation)

Example 14 with Annotation

use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.

the class Inject method getMethodSignature.

public Signature getMethodSignature(Method m) {
    Signature signature = m.getDescriptor();
    Annotation obfSignature = m.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE);
    if (obfSignature != null) {
        // Annotation exists. Signature was updated by us during deobfuscation
        signature = DeobAnnotations.getObfuscatedSignature(m);
    }
    return signature;
}
Also used : Signature(net.runelite.asm.signature.Signature) Annotation(net.runelite.asm.attributes.annotation.Annotation)

Example 15 with Annotation

use of net.runelite.asm.attributes.annotation.Annotation in project runelite by runelite.

the class Inject method run.

public void run() throws InjectionException {
    Map<ClassFile, java.lang.Class> implemented = new HashMap<>();
    // check below works
    for (ClassFile cf : deobfuscated.getClasses()) {
        Annotations an = cf.getAnnotations();
        if (an == null || an.size() == 0) {
            continue;
        }
        String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
        if (obfuscatedName == null) {
            obfuscatedName = cf.getName();
        }
        ClassFile other = vanilla.findClass(obfuscatedName);
        assert other != null : "unable to find vanilla class from obfuscated name: " + obfuscatedName;
        java.lang.Class implementingClass = injectInterface(cf, other);
        // it can not implement an interface but still have exported static fields, which are
        // moved to client
        implemented.put(cf, implementingClass);
    }
    // requires interfaces to be injected
    mixinInjector.inject();
    construct.inject(implemented);
    for (ClassFile cf : deobfuscated.getClasses()) {
        java.lang.Class implementingClass = implemented.get(cf);
        Annotations an = cf.getAnnotations();
        if (an == null || an.size() == 0) {
            continue;
        }
        String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
        if (obfuscatedName == null) {
            obfuscatedName = cf.getName();
        }
        ClassFile other = vanilla.findClass(obfuscatedName);
        assert other != null : "unable to find vanilla class from obfuscated name: " + obfuscatedName;
        for (Field f : cf.getFields()) {
            an = f.getAnnotations();
            if (an == null || an.find(DeobAnnotations.EXPORT) == null) {
                // not an exported field
                continue;
            }
            Annotation exportAnnotation = an.find(DeobAnnotations.EXPORT);
            String exportedName = exportAnnotation.getElement().getString();
            obfuscatedName = DeobAnnotations.getObfuscatedName(an);
            Annotation getterAnnotation = an.find(DeobAnnotations.OBFUSCATED_GETTER);
            Number getter = null;
            if (getterAnnotation != null) {
                getter = (Number) getterAnnotation.getElement().getValue();
            }
            // the ob jar is the same as the vanilla so this field must exist in this class.
            Type obType = getFieldType(f);
            Field otherf = other.findField(obfuscatedName, obType);
            assert otherf != null;
            assert f.isStatic() == otherf.isStatic();
            // target class for getter
            ClassFile targetClass = f.isStatic() ? vanilla.findClass("client") : other;
            // target api class for getter
            java.lang.Class targetApiClass = f.isStatic() ? CLIENT_CLASS : implementingClass;
            if (targetApiClass == null) {
                assert !f.isStatic();
                // non static field exported on non exported interface
                logger.debug("Non static exported field {} on non exported interface", exportedName);
                continue;
            }
            java.lang.reflect.Method apiMethod = findImportMethodOnApi(targetApiClass, exportedName, true);
            if (apiMethod != null) {
                Number setter = null;
                if (getter != null) {
                    // inverse getter to get the setter
                    setter = DMath.modInverse(getter);
                }
                setters.injectSetter(targetClass, targetApiClass, otherf, exportedName, setter);
            }
            apiMethod = findImportMethodOnApi(targetApiClass, exportedName, false);
            if (apiMethod == null) {
                logger.debug("Unable to find import method on api class {} with imported name {}, not injecting getter", targetApiClass, exportedName);
                continue;
            }
            // check that otherf is converable to apiMethod's
            // return type
            Type fieldType = otherf.getType();
            Type returnType = classToType(apiMethod.getReturnType());
            if (!validateTypeIsConvertibleTo(fieldType, returnType)) {
                throw new InjectionException("Type " + fieldType + " is not convertable to " + returnType + " for getter " + apiMethod);
            }
            getters.injectGetter(targetClass, apiMethod, otherf, getter);
        }
        for (Method m : cf.getMethods()) {
            hookMethod.process(m);
            invokes.process(m, other, implementingClass);
        }
    }
    logger.info("Injected {} getters, {} settters, {} invokers", getters.getInjectedGetters(), setters.getInjectedSetters(), invokes.getInjectedInvokers());
    drawAfterWidgets.inject();
    scriptVM.inject();
}
Also used : ClassFile(net.runelite.asm.ClassFile) HashMap(java.util.HashMap) Method(net.runelite.asm.Method) Annotation(net.runelite.asm.attributes.annotation.Annotation) Field(net.runelite.asm.Field) Type(net.runelite.asm.Type) Annotations(net.runelite.asm.attributes.Annotations) DeobAnnotations(net.runelite.deob.DeobAnnotations) Class(net.runelite.asm.pool.Class)

Aggregations

Annotation (net.runelite.asm.attributes.annotation.Annotation)21 ClassFile (net.runelite.asm.ClassFile)10 Method (net.runelite.asm.Method)8 Annotations (net.runelite.asm.attributes.Annotations)8 Field (net.runelite.asm.Field)7 Element (net.runelite.asm.attributes.annotation.Element)6 Signature (net.runelite.asm.signature.Signature)6 DeobAnnotations (net.runelite.deob.DeobAnnotations)6 IOException (java.io.IOException)5 Type (net.runelite.asm.Type)5 List (java.util.List)4 GetField (net.runelite.asm.attributes.code.instructions.GetField)4 PutField (net.runelite.asm.attributes.code.instructions.PutField)4 ArrayList (java.util.ArrayList)3 ClassGroup (net.runelite.asm.ClassGroup)3 Instruction (net.runelite.asm.attributes.code.Instruction)3 Class (net.runelite.asm.pool.Class)3 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)3 InputStream (java.io.InputStream)2 HashMap (java.util.HashMap)2