Search in sources :

Example 6 with SetFieldInstruction

use of net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction in project runelite by runelite.

the class PacketHandlerOrder method run.

@Override
public void run(ClassGroup group) {
    // This is run on the deobfuscated jar, so there are no symbols yet...
    // Find packetType and buffer classes
    PacketTypeFinder ptf = new PacketTypeFinder(group);
    ptf.find();
    BufferFinder bf = new BufferFinder(group);
    bf.find();
    HandlerFinder hf = new HandlerFinder(group, ptf.getPacketType());
    PacketHandlers handlers = hf.findHandlers();
    logger.info("Found {} packet handlers", handlers.getHandlers().size());
    for (PacketHandler handler : handlers.getHandlers()) {
        Execution e = hf.getExecution();
        e.reset();
        e.staticStep = true;
        e.step = false;
        e.noInvoke = true;
        // exception processing won't do non-local jumps, so
        // depending on whether methods are inlined or not
        // it may jump completely out of the handler into the
        // catch all for all packet handling
        // just disable exception execution
        e.noExceptions = true;
        assert e.frames.isEmpty();
        Frame f = handler.jumpFrame.dup();
        assert f.isExecuting();
        f.getMethodCtx().reset();
        e.clearExecutionVisitor();
        e.addExecutionVisitor(ictx -> {
            if (ictx.getInstruction() instanceof MappableInstruction) {
                if (ictx.getInstruction().getType() != InstructionType.INVOKESTATIC) {
                    if (!handler.mappable.contains(ictx.getInstruction())) {
                        handler.mappable.add(ictx.getInstruction());
                    }
                }
            }
            if (ictx.getInstruction().getType() == InstructionType.INVOKEVIRTUAL) {
                InvokeInstruction ii = (InvokeInstruction) ictx.getInstruction();
                // check if the invoke is on buffer/packetbuffer classes
                boolean matches = ii.getMethods().stream().filter(m -> m.getDescriptor().size() == 0).map(method -> method.getClassFile()).anyMatch(cf -> cf == bf.getBuffer() || cf == bf.getPacketBuffer());
                if (matches) {
                    Method method = ii.getMethods().get(0);
                    Signature signature = method.getDescriptor();
                    Type returnValue = signature.getReturnValue();
                    // buffer reference
                    assert ictx.getPops().size() == 1;
                    InstructionContext bufferCtx = ictx.getPops().get(0).getPushed();
                    if (bufferCtx.getInstruction().getType() != InstructionType.GETSTATIC) {
                        // sometimes buffer is passed to a function and then invoked.
                        return;
                    }
                    PacketRead packetRead = new PacketRead(returnValue, bufferCtx.getInstruction(), ictx);
                    if (!handler.reads.contains(packetRead)) {
                        handler.reads.add(packetRead);
                    }
                }
            }
            if (ictx.getInstruction().getType() == InstructionType.INVOKEVIRTUAL || ictx.getInstruction().getType() == InstructionType.INVOKESPECIAL || ictx.getInstruction().getType() == InstructionType.INVOKEINTERFACE) {
                InvokeInstruction ii = (InvokeInstruction) ictx.getInstruction();
                // read methods are scrambled so cant count them
                if (!handler.hasPacketRead(ictx.getInstruction())) {
                    handler.methodInvokes.addAll(ii.getMethods());
                }
            }
            if (ictx.getInstruction() instanceof SetFieldInstruction) {
                SetFieldInstruction sfi = (SetFieldInstruction) ictx.getInstruction();
                Field field = sfi.getMyField();
                if (field != null) {
                    handler.fieldWrite.add(field);
                }
            }
            if (ictx.getInstruction() instanceof GetFieldInstruction) {
                GetFieldInstruction gfi = (GetFieldInstruction) ictx.getInstruction();
                Field field = gfi.getMyField();
                if (field != null) {
                    handler.fieldRead.add(field);
                }
            }
            if (ictx.getInstruction() instanceof LVTInstruction) {
                LVTInstruction lvt = (LVTInstruction) ictx.getInstruction();
                if (!lvt.store()) {
                    // get lvt access order
                    Frame frame = ictx.getFrame();
                    int order = frame.getNextOrder();
                    if (!handler.lvtOrder.containsKey(lvt.getVariableIndex())) {
                        handler.lvtOrder.put(lvt.getVariableIndex(), order);
                    }
                }
            }
            if (ictx.getInstruction() instanceof PushConstantInstruction) {
                PushConstantInstruction pci = (PushConstantInstruction) ictx.getInstruction();
                handler.constants.add(pci.getConstant());
            }
        });
        logger.debug("Beginning execution of opcode {}", handler.getOpcode());
        e.run();
        logger.info("Executed opcode {}: {} mappable instructions", handler.getOpcode(), handler.mappable.size());
        handler.findReorderableReads();
    }
    List<PacketHandler> unsortedHandlers = new ArrayList<>(handlers.getHandlers());
    List<PacketHandler> sortedHandlers = new ArrayList<>(handlers.getHandlers()).stream().sorted((PacketHandler p1, PacketHandler p2) -> {
        int c = compareReads(p1.reads, p2.reads);
        if (c != 0) {
            return c;
        }
        if (p1.methodInvokes.size() != p2.methodInvokes.size()) {
            return Integer.compare(p1.methodInvokes.size(), p2.methodInvokes.size());
        }
        if (p1.fieldRead.size() != p2.fieldRead.size()) {
            return Integer.compare(p1.fieldRead.size(), p2.fieldRead.size());
        }
        if (p1.fieldWrite.size() != p2.fieldWrite.size()) {
            return Integer.compare(p1.fieldWrite.size(), p2.fieldWrite.size());
        }
        int i = Integer.compare(p1.mappable.size(), p2.mappable.size());
        if (i != 0) {
            return i;
        }
        int s1 = hashConstants(p1.constants), s2 = hashConstants(p2.constants);
        if (s1 != s2) {
            return Integer.compare(s1, s2);
        }
        logger.warn("Unable to differentiate {} from {}", p1, p2);
        return 0;
    }).map(s -> s.clone()).collect(Collectors.toList());
    assert sortedHandlers.size() == handlers.getHandlers().size();
    for (PacketHandler handler : sortedHandlers) {
        handler.sortedReads = new ArrayList<>(handler.reads);
        Collections.sort(handler.sortedReads, (PacketRead p1, PacketRead p2) -> {
            LVTInstruction l1 = (LVTInstruction) p1.getStore();
            LVTInstruction l2 = (LVTInstruction) p2.getStore();
            if (l1 == null && l2 == null) {
                return 0;
            }
            if (l1 == null) {
                return 1;
            }
            if (l2 == null) {
                return -1;
            }
            if (l1.getVariableIndex() == l2.getVariableIndex()) {
                return 0;
            }
            Integer i1 = handler.lvtOrder.get(l1.getVariableIndex());
            Integer i2 = handler.lvtOrder.get(l2.getVariableIndex());
            assert i1 != null;
            assert i2 != null;
            int i = Integer.compare(i1, i2);
            if (i == 0) {
                logger.warn("Cannot differentiate {} from {}", p1, p2);
            }
            return i;
        });
        Collections.reverse(handler.sortedReads);
    }
    ClassFile runeliteOpcodes = group.findClass(RUNELITE_OPCODES);
    assert runeliteOpcodes != null : "Opcodes class must exist";
    for (PacketHandler handler : sortedHandlers) {
        logger.info("Handler {} mappable {} reads {} invokes {} freads {} fwrites {}", handler.getOpcode(), handler.mappable.size(), handler.reads.size(), handler.methodInvokes.size(), handler.fieldRead.size(), handler.fieldWrite.size());
        final String fieldName = "PACKET_SERVER_" + handler.getOpcode();
        // Add opcode fields
        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(handler.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, handler.getOpcode()));
            instructions.addInstruction(1, new PutStatic(instructions, opField));
        }
    }
    // Find unique methods
    List<Method> methods = unsortedHandlers.stream().map(ph -> ph.getMethod()).distinct().collect(Collectors.toList());
    for (Method m : methods) {
        List<PacketHandler> unsortedMethodHandlers = unsortedHandlers.stream().filter(ph -> ph.getMethod() == m).collect(Collectors.toList());
        List<PacketHandler> sortedMethodHandlers = sortedHandlers.stream().filter(ph -> ph.getMethod() == m).collect(Collectors.toList());
        assert unsortedMethodHandlers.size() == sortedMethodHandlers.size();
        for (int i = 0; i < sortedMethodHandlers.size(); ++i) {
            PacketHandler unsorted = unsortedMethodHandlers.get(i);
            PacketHandler sortedh = sortedMethodHandlers.get(i);
            // Set opcode/jump from sorted -> unsorted
            If jump = (If) unsorted.getJump();
            PushConstantInstruction pci = (PushConstantInstruction) unsorted.getPush();
            assert unsorted.getOpcode() == ((Number) pci.getConstant()).intValue();
            Instructions instructions = unsorted.getMethod().getCode().getInstructions();
            final String fieldName = "PACKET_SERVER_" + sortedh.getOpcode();
            net.runelite.asm.pool.Field field = new net.runelite.asm.pool.Field(new net.runelite.asm.pool.Class(RUNELITE_OPCODES), fieldName, Type.INT);
            instructions.replace(unsorted.getPush(), new GetStatic(instructions, field));
            assert jump.getType() == InstructionType.IF_ICMPEQ || jump.getType() == InstructionType.IF_ICMPNE;
            Label startLabel = instructions.createLabelFor(sortedh.getStart());
            if (jump.getType() == InstructionType.IF_ICMPEQ) {
                instructions.replace(jump, new IfICmpEq(instructions, startLabel));
            } else if (jump.getType() == InstructionType.IF_ICMPNE) {
                // insert a jump after to go to sortedh start
                int idx = instructions.getInstructions().indexOf(jump);
                assert idx != -1;
                instructions.addInstruction(idx + 1, new Goto(instructions, startLabel));
            } else {
                throw new IllegalStateException();
            }
        }
    }
    insertSortedReads(group, sortedHandlers);
    insertPacketLength(group, ptf);
}
Also used : IfICmpEq(net.runelite.asm.attributes.code.instructions.IfICmpEq) LoggerFactory(org.slf4j.LoggerFactory) PacketHandler(net.runelite.deob.s2c.PacketHandler) Goto(net.runelite.asm.attributes.code.instructions.Goto) If(net.runelite.asm.attributes.code.instructions.If) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) InstructionType(net.runelite.asm.attributes.code.InstructionType) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) PacketTypeFinder(net.runelite.deob.deobfuscators.packethandler.PacketTypeFinder) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) Type(net.runelite.asm.Type) Deobfuscator(net.runelite.deob.Deobfuscator) BufferFinder(net.runelite.deob.deobfuscators.transformers.buffer.BufferFinder) Collectors(java.util.stream.Collectors) InstructionContext(net.runelite.asm.execution.InstructionContext) ComparisonInstruction(net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction) List(java.util.List) ACC_PUBLIC(org.objectweb.asm.Opcodes.ACC_PUBLIC) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) PacketRead(net.runelite.deob.deobfuscators.packethandler.PacketRead) Signature(net.runelite.asm.signature.Signature) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) MessageDigest(java.security.MessageDigest) PutStatic(net.runelite.asm.attributes.code.instructions.PutStatic) ACC_STATIC(org.objectweb.asm.Opcodes.ACC_STATIC) ArrayList(java.util.ArrayList) ClassGroup(net.runelite.asm.ClassGroup) Method(net.runelite.asm.Method) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) Frame(net.runelite.asm.execution.Frame) Logger(org.slf4j.Logger) RUNELITE_OPCODES(net.runelite.deob.deobfuscators.transformers.OpcodesTransformer.RUNELITE_OPCODES) Field(net.runelite.asm.Field) PacketLengthFinder(net.runelite.deob.deobfuscators.packethandler.PacketLengthFinder) Ints(com.google.common.primitives.Ints) InvokeVirtual(net.runelite.asm.attributes.code.instructions.InvokeVirtual) Execution(net.runelite.asm.execution.Execution) ClassFile(net.runelite.asm.ClassFile) Label(net.runelite.asm.attributes.code.Label) PacketHandlers(net.runelite.deob.s2c.PacketHandlers) HandlerFinder(net.runelite.deob.s2c.HandlerFinder) IfEq(net.runelite.asm.attributes.code.instructions.IfEq) LDC(net.runelite.asm.attributes.code.instructions.LDC) Instructions(net.runelite.asm.attributes.code.Instructions) Instruction(net.runelite.asm.attributes.code.Instruction) MappableInstruction(net.runelite.asm.attributes.code.instruction.types.MappableInstruction) Collections(java.util.Collections) Frame(net.runelite.asm.execution.Frame) BufferFinder(net.runelite.deob.deobfuscators.transformers.buffer.BufferFinder) PacketHandlers(net.runelite.deob.s2c.PacketHandlers) ArrayList(java.util.ArrayList) Label(net.runelite.asm.attributes.code.Label) LDC(net.runelite.asm.attributes.code.instructions.LDC) PacketRead(net.runelite.deob.deobfuscators.packethandler.PacketRead) Field(net.runelite.asm.Field) MappableInstruction(net.runelite.asm.attributes.code.instruction.types.MappableInstruction) Execution(net.runelite.asm.execution.Execution) GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) IfICmpEq(net.runelite.asm.attributes.code.instructions.IfICmpEq) InstructionContext(net.runelite.asm.execution.InstructionContext) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) Goto(net.runelite.asm.attributes.code.instructions.Goto) ClassFile(net.runelite.asm.ClassFile) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instructions(net.runelite.asm.attributes.code.Instructions) Method(net.runelite.asm.Method) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) PutStatic(net.runelite.asm.attributes.code.instructions.PutStatic) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) InstructionType(net.runelite.asm.attributes.code.InstructionType) Type(net.runelite.asm.Type) PacketHandler(net.runelite.deob.s2c.PacketHandler) Signature(net.runelite.asm.signature.Signature) HandlerFinder(net.runelite.deob.s2c.HandlerFinder) PacketTypeFinder(net.runelite.deob.deobfuscators.packethandler.PacketTypeFinder) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) If(net.runelite.asm.attributes.code.instructions.If)

Example 7 with SetFieldInstruction

use of net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction in project runelite by runelite.

the class PacketWriteDeobfuscator method isEnd.

private boolean isEnd(InstructionContext ctx) {
    // conditions where packet write ends:
    // any invoke that isn't to the packet buffer
    // any variable assignment
    // any field assignment
    // any conditional jump
    // any return
    Instruction i = ctx.getInstruction();
    if (i instanceof InvokeInstruction) {
        InvokeInstruction ii = (InvokeInstruction) i;
        Method method = ii.getMethod();
        if (!method.getClazz().equals(rw.getSecretBuffer().getPoolClass()) && !method.getClazz().equals(rw.getBuffer().getPoolClass())) {
            return true;
        }
    }
    if (i instanceof LVTInstruction) {
        LVTInstruction lvt = (LVTInstruction) i;
        if (lvt.store()) {
            return true;
        }
    }
    if (i instanceof SetFieldInstruction) {
        return true;
    }
    if (i instanceof If || i instanceof If0) {
        return true;
    }
    if (i instanceof ReturnInstruction) {
        return true;
    }
    return false;
}
Also used : InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) ReturnInstruction(net.runelite.asm.attributes.code.instruction.types.ReturnInstruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) If0(net.runelite.asm.attributes.code.instructions.If0) Method(net.runelite.asm.pool.Method) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) ReturnInstruction(net.runelite.asm.attributes.code.instruction.types.ReturnInstruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) If(net.runelite.asm.attributes.code.instructions.If)

Example 8 with SetFieldInstruction

use of net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction in project runelite by runelite.

the class ModArith method findUses.

// find potential getters/setters for each field
private void findUses(MethodContext mctx) {
    for (InstructionContext ctx : mctx.getInstructionContexts()) {
        if (ctx.getInstruction() instanceof IMul || ctx.getInstruction() instanceof LMul) {
            Instruction one = ctx.getPops().get(0).getPushed().getInstruction();
            Instruction two = ctx.getPops().get(1).getPushed().getInstruction();
            PushConstantInstruction pc = null;
            GetFieldInstruction gf = null;
            if (one instanceof PushConstantInstruction && two instanceof GetFieldInstruction) {
                pc = (PushConstantInstruction) one;
                gf = (GetFieldInstruction) two;
            } else if (two instanceof PushConstantInstruction && one instanceof GetFieldInstruction) {
                pc = (PushConstantInstruction) two;
                gf = (GetFieldInstruction) one;
            }
            if (pc == null) {
                continue;
            }
            Field field = gf.getMyField();
            if (field == null) {
                continue;
            }
            FieldInfo fieldInfo = getFieldInfo(field);
            // parse the full multiplication expression to
            // get all associated constants
            List<InstructionContext> insInExpr = getInsInExpr(ctx, new HashSet(), true);
            for (InstructionContext ctx2 : insInExpr) {
                if (!(ctx2.getInstruction() instanceof PushConstantInstruction)) {
                    continue;
                }
                PushConstantInstruction pci3 = (PushConstantInstruction) ctx2.getInstruction();
                Number value = (Number) pci3.getConstant();
                // field * constant
                if (value instanceof Integer || value instanceof Long) {
                    fieldInfo.getters.add(value);
                }
            }
        } else if (ctx.getInstruction() instanceof SetFieldInstruction) {
            SetFieldInstruction sf = (SetFieldInstruction) ctx.getInstruction();
            Field field = sf.getMyField();
            if (field == null) {
                continue;
            }
            FieldInfo fieldInfo = getFieldInfo(field);
            // value being set
            InstructionContext pushedsfi = ctx.getPops().get(0).getPushed();
            pushedsfi = pushedsfi.resolve(ctx.getPops().get(0));
            if (!(pushedsfi.getInstruction() instanceof IMul) && !(pushedsfi.getInstruction() instanceof LMul) && !(pushedsfi.getInstruction() instanceof IAdd) && !(pushedsfi.getInstruction() instanceof LAdd) && !(pushedsfi.getInstruction() instanceof ISub) && !(pushedsfi.getInstruction() instanceof LSub)) {
                if (pushedsfi.getInstruction() instanceof LDC) {
                    PushConstantInstruction ldc = (PushConstantInstruction) pushedsfi.getInstruction();
                    if (ldc.getConstant() instanceof Integer || ldc.getConstant() instanceof Long) {
                        Number i = (Number) ldc.getConstant();
                        // field = constant
                        fieldInfo.setters.add(i);
                    }
                }
                continue;
            }
            Instruction one = pushedsfi.getPops().get(0).getPushed().getInstruction();
            Instruction two = pushedsfi.getPops().get(1).getPushed().getInstruction();
            // field = field + imul
            if (pushedsfi.getInstruction() instanceof IAdd) {
                if (one instanceof IMul && two instanceof GetFieldInstruction) {
                    one = pushedsfi.getPops().get(0).getPushed().getPops().get(0).getPushed().getInstruction();
                    two = pushedsfi.getPops().get(0).getPushed().getPops().get(1).getPushed().getInstruction();
                }
            }
            // if both one and two are constants then one of them must not be a setter
            PushConstantInstruction pc = null;
            if (one instanceof PushConstantInstruction && !(two instanceof PushConstantInstruction)) {
                pc = (PushConstantInstruction) one;
            } else if (two instanceof PushConstantInstruction && !(one instanceof PushConstantInstruction)) {
                pc = (PushConstantInstruction) two;
            }
            if (pc == null) {
                continue;
            }
            Number value2 = (Number) pc.getConstant();
            // field = something * constant
            if (value2 instanceof Integer || value2 instanceof Long) {
                fieldInfo.setters.add(value2);
            }
        }
    }
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) LDC(net.runelite.asm.attributes.code.instructions.LDC) DivisionInstruction(net.runelite.asm.attributes.code.instruction.types.DivisionInstruction) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) ArrayStoreInstruction(net.runelite.asm.attributes.code.instruction.types.ArrayStoreInstruction) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) Field(net.runelite.asm.Field) ISub(net.runelite.asm.attributes.code.instructions.ISub) LAdd(net.runelite.asm.attributes.code.instructions.LAdd) LSub(net.runelite.asm.attributes.code.instructions.LSub) IMul(net.runelite.asm.attributes.code.instructions.IMul) IAdd(net.runelite.asm.attributes.code.instructions.IAdd) LMul(net.runelite.asm.attributes.code.instructions.LMul) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) HashSet(java.util.HashSet)

Example 9 with SetFieldInstruction

use of net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction in project runelite by runelite.

the class ModArith method findConstants.

// find associated constants with each field
private void findConstants(MethodContext mctx) {
    for (InstructionContext ctx : mctx.getInstructionContexts()) {
        if (ctx.getInstruction() instanceof FieldInstruction) {
            FieldInstruction fi = (FieldInstruction) ctx.getInstruction();
            if (fi.getMyField() == null) {
                continue;
            }
            if ((!fi.getField().getType().equals(Type.INT) && !fi.getField().getType().equals(Type.LONG)) || fi.getField().getType().isArray()) {
                continue;
            }
            FieldInfo fieldInfo = getFieldInfo(fi.getMyField());
            List<InstructionContext> l = getInsInExpr(ctx, new HashSet(), false);
            // check if this contains another field
            boolean other = false;
            boolean getter = false, setter = false;
            for (InstructionContext i : l) {
                if (i.getInstruction() instanceof FieldInstruction) {
                    FieldInstruction fi2 = (FieldInstruction) i.getInstruction();
                    Field myField = fi2.getMyField();
                    if (myField != null && myField != fi.getMyField()) {
                        Type t = myField.getType();
                        if (t.equals(fi.getMyField().getType())) {
                            other = true;
                        }
                    } else if (myField != null && myField == fi.getMyField()) {
                        if (fi2 instanceof SetFieldInstruction) {
                            setter = true;
                        } else {
                            getter = true;
                        }
                    }
                }
            }
            // check if this is a constant assignment
            boolean constant = false;
            if (fi instanceof SetFieldInstruction) {
                // value being set
                InstructionContext pushedsfi = ctx.getPops().get(0).getPushed();
                pushedsfi = pushedsfi.resolve(ctx.getPops().get(0));
                if (pushedsfi.getInstruction() instanceof LDC) {
                    constant = true;
                }
            }
            for (InstructionContext i : l) {
                if (i.getInstruction() instanceof LDC) {
                    PushConstantInstruction w = (PushConstantInstruction) i.getInstruction();
                    if (w.getConstant() instanceof Integer || w.getConstant() instanceof Long) {
                        AssociatedConstant n = new AssociatedConstant();
                        n.value = (Number) w.getConstant();
                        n.other = other;
                        n.constant = constant;
                        n.getter = getter;
                        n.setter = setter;
                        fieldInfo.constants.add(n);
                    }
                }
            }
        }
    }
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) LDC(net.runelite.asm.attributes.code.instructions.LDC) Field(net.runelite.asm.Field) Type(net.runelite.asm.Type) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) HashSet(java.util.HashSet)

Example 10 with SetFieldInstruction

use of net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction 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)

Aggregations

SetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction)10 Field (net.runelite.asm.Field)7 Instruction (net.runelite.asm.attributes.code.Instruction)7 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)6 Instructions (net.runelite.asm.attributes.code.Instructions)5 GetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction)5 InvokeInstruction (net.runelite.asm.attributes.code.instruction.types.InvokeInstruction)5 LDC (net.runelite.asm.attributes.code.instructions.LDC)5 InstructionContext (net.runelite.asm.execution.InstructionContext)5 Method (net.runelite.asm.Method)4 FieldInstruction (net.runelite.asm.attributes.code.instruction.types.FieldInstruction)4 LVTInstruction (net.runelite.asm.attributes.code.instruction.types.LVTInstruction)4 HashSet (java.util.HashSet)3 ClassFile (net.runelite.asm.ClassFile)3 Type (net.runelite.asm.Type)3 Code (net.runelite.asm.attributes.Code)3 DupInstruction (net.runelite.asm.attributes.code.instruction.types.DupInstruction)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Collectors (java.util.stream.Collectors)2