Search in sources :

Example 86 with StackContext

use of net.runelite.asm.execution.StackContext in project runelite by runelite.

the class ExprArgOrder method hash.

private static void hash(Method method, MessageDigest sha256, InstructionContext ic) {
    Instruction i = ic.getInstruction();
    // this relies on all push constants are converted to ldc..
    sha256.update((byte) i.getType().getCode());
    if (i instanceof PushConstantInstruction) {
        PushConstantInstruction pci = (PushConstantInstruction) i;
        Object constant = pci.getConstant();
        if (constant instanceof Number) {
            long l = ((Number) constant).longValue();
            sha256.update(Longs.toByteArray(l));
        }
    } else if (i instanceof LVTInstruction) {
        int idx = ((LVTInstruction) i).getVariableIndex();
        Signature signature = method.getDescriptor();
        int lvt = method.isStatic() ? 0 : 1;
        for (Type type : signature.getArguments()) {
            if (idx == lvt) {
                // Accessing a method parameter
                sha256.update(Ints.toByteArray(idx));
                break;
            }
            lvt += type.getSize();
        }
    }
    for (StackContext sctx : ic.getPops()) {
        hash(method, sha256, sctx.getPushed());
    }
}
Also used : InstructionType(net.runelite.asm.attributes.code.InstructionType) Type(net.runelite.asm.Type) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) StackContext(net.runelite.asm.execution.StackContext) Signature(net.runelite.asm.signature.Signature) 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) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction)

Example 87 with StackContext

use of net.runelite.asm.execution.StackContext in project runelite by runelite.

the class InjectHook method recursivelyPush.

private int recursivelyPush(Instructions ins, int idx, StackContext sctx) {
    InstructionContext ctx = sctx.getPushed();
    if (ctx.getInstruction() instanceof DupInstruction) {
        DupInstruction dupInstruction = (DupInstruction) ctx.getInstruction();
        sctx = dupInstruction.getOriginal(sctx);
        ctx = sctx.getPushed();
    }
    for (StackContext s : Lists.reverse(ctx.getPops())) {
        idx = recursivelyPush(ins, idx, s);
    }
    ins.getInstructions().add(idx++, ctx.getInstruction().clone());
    return idx;
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) StackContext(net.runelite.asm.execution.StackContext) DupInstruction(net.runelite.asm.attributes.code.instruction.types.DupInstruction)

Example 88 with StackContext

use of net.runelite.asm.execution.StackContext in project runelite by runelite.

the class InjectHook method run.

public void run() {
    Execution e = new Execution(inject.getVanilla());
    e.populateInitialMethods();
    Set<Instruction> done = new HashSet<>();
    Set<Instruction> doneIh = new HashSet<>();
    e.addExecutionVisitor((InstructionContext ic) -> {
        Instruction i = ic.getInstruction();
        Instructions ins = i.getInstructions();
        Code code = ins.getCode();
        Method method = code.getMethod();
        if (method.getName().equals(CLINIT)) {
            return;
        }
        if (!(i instanceof SetFieldInstruction)) {
            return;
        }
        if (!done.add(i)) {
            return;
        }
        SetFieldInstruction sfi = (SetFieldInstruction) i;
        Field fieldBeingSet = sfi.getMyField();
        if (fieldBeingSet == null) {
            return;
        }
        HookInfo hookInfo = hooked.get(fieldBeingSet);
        if (hookInfo == null) {
            return;
        }
        String hookName = hookInfo.fieldName;
        assert hookName != null;
        logger.trace("Found injection location for hook {} at instruction {}", hookName, sfi);
        ++injectedHooks;
        Instruction objectInstruction = new AConstNull(ins);
        StackContext objectStackContext = null;
        if (sfi instanceof PutField) {
            // Object being set on
            StackContext objectStack = ic.getPops().get(1);
            objectStackContext = objectStack;
        }
        int idx = ins.getInstructions().indexOf(sfi);
        assert idx != -1;
        try {
            // idx + 1 to insert after the set
            injectCallback(ins, idx + 1, hookInfo, null, objectStackContext);
        } catch (InjectionException ex) {
            throw new RuntimeException(ex);
        }
    });
    // these look like:
    // getfield
    // iload_0
    // iconst_0
    // iastore
    e.addExecutionVisitor((InstructionContext ic) -> {
        Instruction i = ic.getInstruction();
        Instructions ins = i.getInstructions();
        Code code = ins.getCode();
        Method method = code.getMethod();
        if (method.getName().equals(CLINIT)) {
            return;
        }
        if (!(i instanceof ArrayStore)) {
            return;
        }
        if (!doneIh.add(i)) {
            return;
        }
        ArrayStore as = (ArrayStore) i;
        Field fieldBeingSet = as.getMyField(ic);
        if (fieldBeingSet == null) {
            return;
        }
        HookInfo hookInfo = hooked.get(fieldBeingSet);
        if (hookInfo == null) {
            return;
        }
        String hookName = hookInfo.fieldName;
        // assume this is always at index 1
        StackContext index = ic.getPops().get(1);
        StackContext arrayReference = ic.getPops().get(2);
        InstructionContext arrayReferencePushed = arrayReference.getPushed();
        StackContext objectStackContext = null;
        if (arrayReferencePushed.getInstruction().getType() == InstructionType.GETFIELD) {
            StackContext objectReference = arrayReferencePushed.getPops().get(0);
            objectStackContext = objectReference;
        }
        // inject hook after 'i'
        logger.info("Found array injection location for hook {} at instruction {}", hookName, i);
        ++injectedHooks;
        int idx = ins.getInstructions().indexOf(i);
        assert idx != -1;
        try {
            injectCallback(ins, idx + 1, hookInfo, index, objectStackContext);
        } catch (InjectionException ex) {
            throw new RuntimeException(ex);
        }
    });
    e.run();
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) Instructions(net.runelite.asm.attributes.code.Instructions) AConstNull(net.runelite.asm.attributes.code.instructions.AConstNull) Method(net.runelite.asm.Method) DupInstruction(net.runelite.asm.attributes.code.instruction.types.DupInstruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) Instruction(net.runelite.asm.attributes.code.Instruction) ArrayStore(net.runelite.asm.attributes.code.instructions.ArrayStore) Code(net.runelite.asm.attributes.Code) Field(net.runelite.asm.Field) PutField(net.runelite.asm.attributes.code.instructions.PutField) Execution(net.runelite.asm.execution.Execution) StackContext(net.runelite.asm.execution.StackContext) HashSet(java.util.HashSet) PutField(net.runelite.asm.attributes.code.instructions.PutField)

Example 89 with StackContext

use of net.runelite.asm.execution.StackContext in project runelite by runelite.

the class PutField method isSame.

@Override
public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) {
    if (thisIc.getInstruction().getClass() != otherIc.getInstruction().getClass()) {
        return false;
    }
    PutField thisPf = (PutField) thisIc.getInstruction(), otherPf = (PutField) otherIc.getInstruction();
    net.runelite.asm.Field f1 = thisPf.getMyField();
    net.runelite.asm.Field f2 = otherPf.getMyField();
    if ((f1 != null) != (f2 != null)) {
        return false;
    }
    if (!MappingExecutorUtil.isMaybeEqual(f1.getClassFile(), f2.getClassFile()) || !MappingExecutorUtil.isMaybeEqual(f1.getType(), f2.getType())) {
        return false;
    }
    // check assignment
    StackContext object1 = thisIc.getPops().get(1), object2 = otherIc.getPops().get(1);
    InstructionContext base1 = MappingExecutorUtil.resolve(object1.getPushed(), object1);
    InstructionContext base2 = MappingExecutorUtil.resolve(object2.getPushed(), object2);
    if (!isMaybeEqual(base1, base2)) {
        return false;
    }
    // check value
    object1 = thisIc.getPops().get(0);
    object2 = otherIc.getPops().get(0);
    base1 = MappingExecutorUtil.resolve(object1.getPushed(), object1);
    base2 = MappingExecutorUtil.resolve(object2.getPushed(), object2);
    if (!isMaybeEqual(base1, base2)) {
        return false;
    }
    return true;
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) StackContext(net.runelite.asm.execution.StackContext)

Example 90 with StackContext

use of net.runelite.asm.execution.StackContext in project runelite by runelite.

the class Return method execute.

@Override
public InstructionContext execute(Frame frame) {
    InstructionContext ins = new InstructionContext(this, frame);
    Stack stack = frame.getStack();
    StackContext object = stack.pop();
    ins.pop(object);
    frame.stop();
    return ins;
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) StackContext(net.runelite.asm.execution.StackContext) Stack(net.runelite.asm.execution.Stack)

Aggregations

StackContext (net.runelite.asm.execution.StackContext)162 InstructionContext (net.runelite.asm.execution.InstructionContext)153 Stack (net.runelite.asm.execution.Stack)119 Value (net.runelite.asm.execution.Value)47 Field (net.runelite.asm.Field)15 Variables (net.runelite.asm.execution.Variables)14 VariableContext (net.runelite.asm.execution.VariableContext)13 Instruction (net.runelite.asm.attributes.code.Instruction)12 GetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction)12 Instructions (net.runelite.asm.attributes.code.Instructions)8 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)8 LVTInstruction (net.runelite.asm.attributes.code.instruction.types.LVTInstruction)7 Execution (net.runelite.asm.execution.Execution)7 Frame (net.runelite.asm.execution.Frame)7 DupInstruction (net.runelite.asm.attributes.code.instruction.types.DupInstruction)6 InvokeInstruction (net.runelite.asm.attributes.code.instruction.types.InvokeInstruction)6 Method (net.runelite.asm.pool.Method)5 ClassFile (net.runelite.asm.ClassFile)4 Method (net.runelite.asm.Method)4 Type (net.runelite.asm.Type)4