Search in sources :

Example 46 with Field

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

the class PacketTypeFinder method run.

private void run(Code code) {
    if (code == null) {
        return;
    }
    Instructions instructions = code.getInstructions();
    for (int i = 0; i < instructions.getInstructions().size() - 1; ++i) {
        Instruction i1 = instructions.getInstructions().get(i), i2 = instructions.getInstructions().get(i + 1);
        if (i1 instanceof PushConstantInstruction && i2.getType() == InstructionType.PUTSTATIC) {
            PushConstantInstruction pci = (PushConstantInstruction) i1;
            SetFieldInstruction sfi = (SetFieldInstruction) i2;
            Field field = sfi.getMyField();
            if (Objects.equal(-1, pci.getConstant()) && field != null) {
                Integer count = sets.get(field);
                if (count == null) {
                    sets.put(field, 1);
                } else {
                    sets.put(field, count + 1);
                }
            }
        }
    }
}
Also used : Field(net.runelite.asm.Field) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instructions(net.runelite.asm.attributes.code.Instructions) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) Instruction(net.runelite.asm.attributes.code.Instruction)

Example 47 with Field

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

the class OpcodeReplacer method run.

public void run(ClassGroup group, Collection<PacketWrite> writes) {
    int count = 0;
    ClassFile runeliteOpcodes = group.findClass(RUNELITE_OPCODES);
    assert runeliteOpcodes != null : "Opcodes class must exist";
    for (PacketWrite wp : writes) {
        Instructions ins = wp.getInstructions();
        Instruction param = wp.getOpcodeIns();
        if (!(param instanceof PushConstantInstruction)) {
            continue;
        }
        final String fieldName = "PACKET_CLIENT_" + wp.getOpcode();
        net.runelite.asm.pool.Field field = new net.runelite.asm.pool.Field(new net.runelite.asm.pool.Class(RUNELITE_OPCODES), fieldName, Type.INT);
        ins.replace(param, new GetStatic(ins, field));
        if (runeliteOpcodes.findField(fieldName) == null) {
            Field opField = new Field(runeliteOpcodes, fieldName, Type.INT);
            // ACC_FINAL causes javac to inline the fields, which prevents
            // the mapper from doing field mapping
            opField.setAccessFlags(ACC_PUBLIC | ACC_STATIC);
            // setting a non-final static field value
            // doesn't work with fernflower
            opField.setValue(wp.getOpcode());
            runeliteOpcodes.addField(opField);
            // add initialization
            Method clinit = runeliteOpcodes.findMethod("<clinit>");
            assert clinit != null;
            Instructions instructions = clinit.getCode().getInstructions();
            instructions.addInstruction(0, new LDC(instructions, wp.getOpcode()));
            instructions.addInstruction(1, new PutStatic(instructions, opField));
        }
        ++count;
    }
    logger.info("Injected {} packet writes", count);
}
Also used : ClassFile(net.runelite.asm.ClassFile) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) Method(net.runelite.asm.Method) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) PutStatic(net.runelite.asm.attributes.code.instructions.PutStatic) Field(net.runelite.asm.Field) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic)

Example 48 with Field

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

the class UnusedFields method run.

@Override
public void run(ClassGroup group) {
    checkForFieldUsage(group);
    int count = 0;
    for (ClassFile cf : group.getClasses()) for (Field f : new ArrayList<>(cf.getFields())) if (!used.contains(f)) {
        cf.removeField(f);
        ++count;
    }
    logger.info("Removed " + count + " unused fields");
}
Also used : Field(net.runelite.asm.Field) ClassFile(net.runelite.asm.ClassFile)

Example 49 with Field

use of net.runelite.asm.Field 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 50 with Field

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

Field (net.runelite.asm.Field)65 ClassFile (net.runelite.asm.ClassFile)39 Method (net.runelite.asm.Method)33 Instruction (net.runelite.asm.attributes.code.Instruction)19 InstructionContext (net.runelite.asm.execution.InstructionContext)19 GetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction)17 Instructions (net.runelite.asm.attributes.code.Instructions)16 StackContext (net.runelite.asm.execution.StackContext)16 Type (net.runelite.asm.Type)15 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)12 LDC (net.runelite.asm.attributes.code.instructions.LDC)11 Code (net.runelite.asm.attributes.Code)10 SetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction)10 Signature (net.runelite.asm.signature.Signature)9 ClassGroup (net.runelite.asm.ClassGroup)8 FieldInstruction (net.runelite.asm.attributes.code.instruction.types.FieldInstruction)8 PutField (net.runelite.asm.attributes.code.instructions.PutField)8 Test (org.junit.Test)8 List (java.util.List)7 Annotation (net.runelite.asm.attributes.annotation.Annotation)7