Search in sources :

Example 76 with Method

use of net.runelite.asm.Method in project runelite by runelite.

the class UnusedParameters method findUnusedParameters.

public Collection<Integer> findUnusedParameters(Collection<Method> methods) {
    Set<Integer> list = null;
    for (Method m : methods) {
        Set<Integer> p = findUnusedParameters(m);
        if (list == null) {
            list = p;
        } else {
            list = Sets.intersection(list, p);
        }
    }
    List<Integer> l = new ArrayList<>(list);
    Collections.sort(l);
    Collections.reverse(l);
    return l;
}
Also used : ArrayList(java.util.ArrayList) Method(net.runelite.asm.Method)

Example 77 with Method

use of net.runelite.asm.Method in project runelite by runelite.

the class UnusedParameters method processUnused.

private int processUnused(Execution execution, ClassGroup group) {
    int count = 0;
    for (List<Method> m : unused.keySet()) {
        Collection<Integer> u = unused.get(m);
        int offset = m.size() == 1 && m.get(0).isStatic() ? 0 : 1;
        for (int unusedParameter : u) {
            if (!shouldRemove(m.get(0), unusedParameter)) {
                continue;
            }
            Signature signature = m.get(0).getDescriptor();
            int lvtIndex = this.getLvtIndex(signature, offset, unusedParameter);
            /* removing the parameter can't cause collisions on other (overloaded) methods because prior to this we rename
				 * all classes/fields/methods to have unique names.
				 */
            logger.debug("Removing parameter {} at index {} from {}", unusedParameter, lvtIndex, m);
            removeParameter(group, m, signature, execution, unusedParameter, lvtIndex);
            break;
        }
        ++count;
    }
    return count;
}
Also used : Signature(net.runelite.asm.signature.Signature) Method(net.runelite.asm.Method)

Example 78 with Method

use of net.runelite.asm.Method in project runelite by runelite.

the class UnusedParameters method buildUnused.

private void buildUnused(ClassGroup group) {
    unused.clear();
    for (ClassFile cf : group.getClasses()) {
        for (Method m : cf.getMethods()) {
            if (!Deob.isObfuscated(m.getName())) {
                continue;
            }
            List<Method> ms = VirtualMethods.getVirtualMethods(m);
            Collection<Integer> u = this.findUnusedParameters(ms);
            if (!u.isEmpty()) {
                unused.put(ms, u);
            }
        }
    }
}
Also used : ClassFile(net.runelite.asm.ClassFile) Method(net.runelite.asm.Method)

Example 79 with Method

use of net.runelite.asm.Method in project runelite by runelite.

the class ClassGroupFactory method generateGroup.

public static ClassGroup generateGroup() {
    ClassGroup group = new ClassGroup();
    ClassFile cf = new ClassFile(group);
    cf.setName("test");
    cf.setSuperName("java/lang/Object");
    group.addClass(cf);
    Field field = new Field(cf, "field", Type.INT);
    field.setStatic();
    cf.addField(field);
    Method method = new Method(cf, "func", new Signature("()V"));
    method.setStatic();
    cf.addMethod(method);
    Code code = new Code(method);
    method.setCode(code);
    {
        method = new Method(cf, "func2", new Signature("(III)V"));
        method.setStatic();
        cf.addMethod(method);
        code = new Code(method);
        method.setCode(code);
        Instructions ins = code.getInstructions();
        ins.addInstruction(new VReturn(ins));
    }
    addVoidMethod(cf, "void1");
    addVoidMethod(cf, "void2");
    addVoidMethod(cf, "void3");
    addVoidMethod(cf, "void4");
    return group;
}
Also used : Field(net.runelite.asm.Field) ClassFile(net.runelite.asm.ClassFile) ClassGroup(net.runelite.asm.ClassGroup) Signature(net.runelite.asm.signature.Signature) Instructions(net.runelite.asm.attributes.code.Instructions) Method(net.runelite.asm.Method) Code(net.runelite.asm.attributes.Code) VReturn(net.runelite.asm.attributes.code.instructions.VReturn)

Example 80 with Method

use of net.runelite.asm.Method 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

Method (net.runelite.asm.Method)90 ClassFile (net.runelite.asm.ClassFile)64 Field (net.runelite.asm.Field)34 Instruction (net.runelite.asm.attributes.code.Instruction)29 Code (net.runelite.asm.attributes.Code)28 Instructions (net.runelite.asm.attributes.code.Instructions)28 Signature (net.runelite.asm.signature.Signature)28 ClassGroup (net.runelite.asm.ClassGroup)20 ArrayList (java.util.ArrayList)18 Type (net.runelite.asm.Type)18 List (java.util.List)13 Test (org.junit.Test)13 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)12 Logger (org.slf4j.Logger)12 LoggerFactory (org.slf4j.LoggerFactory)12 LDC (net.runelite.asm.attributes.code.instructions.LDC)10 DeobAnnotations (net.runelite.deob.DeobAnnotations)9 Annotation (net.runelite.asm.attributes.annotation.Annotation)8 InstructionType (net.runelite.asm.attributes.code.InstructionType)8 Label (net.runelite.asm.attributes.code.Label)8