Search in sources :

Example 16 with PushConstantInstruction

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

the class ConstantParameter method findConstantParameter.

// find constant values passed as parameters
private void findConstantParameter(List<Method> methods, InstructionContext invokeCtx) {
    checkMethodsAreConsistent(methods);
    // all methods must have the same signature etc
    Method method = methods.get(0);
    int offset = method.isStatic() ? 0 : 1;
    List<StackContext> pops = invokeCtx.getPops();
    outer: // object is popped first, then param 1, 2, 3, etc. double and long take two slots.
    for (int lvtOffset = offset, parameterIndex = 0; parameterIndex < method.getDescriptor().size(); lvtOffset += method.getDescriptor().getTypeOfArg(parameterIndex++).getSize()) {
        // get(0) == first thing popped which is the last parameter,
        // get(descriptor.size() - 1) == first parameter
        StackContext ctx = pops.get(method.getDescriptor().size() - 1 - parameterIndex);
        ConstantMethodParameter cmp = getCMPFor(methods, parameterIndex, lvtOffset);
        if (cmp.invalid) {
            continue;
        }
        if (ctx.getPushed().getInstruction() instanceof PushConstantInstruction) {
            PushConstantInstruction pc = (PushConstantInstruction) ctx.getPushed().getInstruction();
            if (!(pc.getConstant() instanceof Number)) {
                cmp.invalid = true;
                continue;
            }
            Number number = (Number) pc.getConstant();
            if (!cmp.values.contains(number)) {
                cmp.values.add((Number) pc.getConstant());
            }
        } else {
            cmp.invalid = true;
        }
    }
}
Also used : PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) StackContext(net.runelite.asm.execution.StackContext) Method(net.runelite.asm.Method)

Example 17 with PushConstantInstruction

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

the class ExprArgOrder method compare.

public static int compare(Method method, InstructionType type, Expression expr1, Expression expr2) {
    Instruction i1 = expr1.getHead().getInstruction();
    Instruction i2 = expr2.getHead().getInstruction();
    if (type == IF_ICMPEQ || type == IF_ICMPNE || type == IADD || type == IMUL) {
        if (!(i1 instanceof PushConstantInstruction) && (i2 instanceof PushConstantInstruction)) {
            return 1;
        }
        if (i1 instanceof PushConstantInstruction && !(i2 instanceof PushConstantInstruction)) {
            return -1;
        }
    }
    if (type == IF_ACMPEQ || type == IF_ACMPNE) {
        if (!(i1 instanceof AConstNull) && (i2 instanceof AConstNull)) {
            return 1;
        }
        if (i1 instanceof AConstNull && !(i2 instanceof AConstNull)) {
            return -1;
        }
    }
    int hash1 = hash(method, expr1.getHead());
    int hash2 = hash(method, expr2.getHead());
    if (hash1 == hash2) {
        logger.debug("Unable to differentiate {} from {}", expr1.getHead(), expr2.getHead());
    }
    return Integer.compare(hash1, hash2);
}
Also used : PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) AConstNull(net.runelite.asm.attributes.code.instructions.AConstNull) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) Instruction(net.runelite.asm.attributes.code.Instruction)

Example 18 with PushConstantInstruction

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

the class HandlerFinder method findHandlers.

private List<PacketHandler> findHandlers(Method process, Field packetOpcode) {
    List<PacketHandler> handlers = new ArrayList<>();
    Instructions ins = process.getCode().getInstructions();
    for (int j = 0; j < ins.getInstructions().size(); ++j) {
        Instruction i = ins.getInstructions().get(j);
        if (i.getType() != InstructionType.GETSTATIC) {
            continue;
        }
        GetStatic gs = (GetStatic) i;
        if (gs.getMyField() != packetOpcode) {
            continue;
        }
        Instruction push = ins.getInstructions().get(j + 1);
        if (!(push instanceof PushConstantInstruction)) {
            continue;
        }
        PushConstantInstruction pci = (PushConstantInstruction) push;
        if (!(pci.getConstant() instanceof Number)) {
            continue;
        }
        int opcode = ((Number) pci.getConstant()).intValue();
        if (opcode == -1) {
            continue;
        }
        Instruction jump = ins.getInstructions().get(j + 2);
        if (jump.getType() != InstructionType.IF_ICMPEQ && jump.getType() != InstructionType.IF_ICMPNE) {
            continue;
        }
        Instruction start, end;
        if (jump.getType() == InstructionType.IF_ICMPEQ) {
            // this seems to not ever happen
            start = ((If) jump).getJumps().get(0);
            // end = ins.getInstructions().get(j + 3);
            end = null;
        } else {
            start = ins.getInstructions().get(j + 3);
            end = ((If) jump).getJumps().get(0);
        }
        PacketHandler handler = new PacketHandler(process, jump, start, push, opcode);
        handlers.add(handler);
        if (end != null) {
            // Anything else which jumps to here instead needs to return.
            insertReturn(ins, jump, end);
        }
        logger.info("Found packet handler {} opcode {}", handler, handler.getOpcode());
    }
    return handlers;
}
Also used : GetStatic(net.runelite.asm.attributes.code.instructions.GetStatic) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) ArrayList(java.util.ArrayList) Instructions(net.runelite.asm.attributes.code.Instructions) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) JumpingInstruction(net.runelite.asm.attributes.code.instruction.types.JumpingInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) If(net.runelite.asm.attributes.code.instructions.If)

Example 19 with PushConstantInstruction

use of net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction 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 20 with PushConstantInstruction

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

Aggregations

PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)21 Instruction (net.runelite.asm.attributes.code.Instruction)16 Instructions (net.runelite.asm.attributes.code.Instructions)9 LVTInstruction (net.runelite.asm.attributes.code.instruction.types.LVTInstruction)8 InstructionContext (net.runelite.asm.execution.InstructionContext)8 Field (net.runelite.asm.Field)7 Method (net.runelite.asm.Method)7 StackContext (net.runelite.asm.execution.StackContext)7 GetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction)6 InvokeInstruction (net.runelite.asm.attributes.code.instruction.types.InvokeInstruction)6 SetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction)6 LDC (net.runelite.asm.attributes.code.instructions.LDC)6 ClassFile (net.runelite.asm.ClassFile)5 FieldInstruction (net.runelite.asm.attributes.code.instruction.types.FieldInstruction)5 ArrayList (java.util.ArrayList)4 Type (net.runelite.asm.Type)4 GetStatic (net.runelite.asm.attributes.code.instructions.GetStatic)4 Logger (org.slf4j.Logger)4 LoggerFactory (org.slf4j.LoggerFactory)4 HashSet (java.util.HashSet)3