Search in sources :

Example 1 with SetFieldInstruction

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

the class MappingExecutorUtil method resolve.

public static InstructionContext resolve(InstructionContext ctx, // pushed from ctx
StackContext from) {
    if (ctx.getInstruction() instanceof SetFieldInstruction) {
        StackContext s = ctx.getPops().get(0);
        return resolve(s.getPushed(), s);
    }
    if (ctx.getInstruction() instanceof ConversionInstruction) {
        // assume it pops one and pushes one
        StackContext s = ctx.getPops().get(0);
        return resolve(s.getPushed(), s);
    }
    if (ctx.getInstruction() instanceof DupInstruction) {
        DupInstruction d = (DupInstruction) ctx.getInstruction();
        StackContext s = d.getOriginal(from);
        return resolve(s.getPushed(), s);
    }
    if (ctx.getInstruction() instanceof ArrayLoad) {
        // might be multidimensional array
        // the array
        StackContext s = ctx.getPops().get(1);
        return resolve(s.getPushed(), s);
    }
    if (ctx.getInstruction() instanceof LVTInstruction) {
        LVTInstruction lvt = (LVTInstruction) ctx.getInstruction();
        Variables variables = ctx.getVariables();
        if (lvt.store()) {
            // is this right?
            StackContext s = ctx.getPops().get(0);
            return resolve(s.getPushed(), s);
        } else {
            // variable being loaded
            VariableContext vctx = variables.get(lvt.getVariableIndex());
            assert vctx != null;
            InstructionContext storedCtx = vctx.getInstructionWhichStored();
            if (storedCtx == null)
                // initial parameter
                return ctx;
            if (vctx.isIsParameter()) {
                // this storedCtx is the invoke instruction which called this method.
                assert storedCtx.getInstruction() instanceof InvokeInstruction;
                // In PME non static functions are never stepped into/aren't inline obfuscated
                assert storedCtx.getInstruction() instanceof InvokeStatic;
                // Figure out parameter index from variable index.
                // signature of current method
                Signature sig = ctx.getFrame().getMethod().getDescriptor();
                int paramIndex = 0;
                for (int lvtIndex = 0; /* static */
                paramIndex < sig.size(); lvtIndex += sig.getTypeOfArg(paramIndex++).getSize()) if (lvtIndex == lvt.getVariableIndex())
                    break;
                assert paramIndex < sig.size();
                // Get stack context that was popped by the invoke
                // pops[0] is the first thing popped, which is the last parameter.
                StackContext sctx = storedCtx.getPops().get(sig.size() - 1 - paramIndex);
                return resolve(sctx.getPushed(), sctx);
            }
            return resolve(storedCtx, null);
        }
    }
    if (ctx.getInstruction() instanceof InvokeStatic) {
        if (from.returnSource != null) {
            return resolve(from.returnSource.getPushed(), from.returnSource);
        }
    }
    return ctx;
}
Also used : ArrayLoad(net.runelite.asm.attributes.code.instruction.types.ArrayLoad) InstructionContext(net.runelite.asm.execution.InstructionContext) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) ConversionInstruction(net.runelite.asm.attributes.code.instruction.types.ConversionInstruction) DupInstruction(net.runelite.asm.attributes.code.instruction.types.DupInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) VariableContext(net.runelite.asm.execution.VariableContext) Variables(net.runelite.asm.execution.Variables) InvokeInstruction(net.runelite.asm.attributes.code.instruction.types.InvokeInstruction) StackContext(net.runelite.asm.execution.StackContext) Signature(net.runelite.asm.signature.Signature) InvokeStatic(net.runelite.asm.attributes.code.instructions.InvokeStatic)

Example 2 with SetFieldInstruction

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

the class ModArith method insertGetterSetterMuls.

private void insertGetterSetterMuls(Encryption encr) {
    // before setfield insert imul * getter
    for (ClassFile cf : group.getClasses()) {
        for (Method m : cf.getMethods()) {
            Code code = m.getCode();
            if (code == null) {
                continue;
            }
            Instructions ins = code.getInstructions();
            List<Instruction> ilist = ins.getInstructions();
            for (int i = 0; i < ilist.size(); ++i) {
                Instruction in = ilist.get(i);
                if (in instanceof SetFieldInstruction) {
                    SetFieldInstruction sfi = (SetFieldInstruction) in;
                    Field f = sfi.getMyField();
                    if (f == null) {
                        continue;
                    }
                    Pair p = encr.getField(f.getPoolField());
                    if (p == null) {
                        continue;
                    }
                    // insert imul
                    if (p.getType() == Integer.class) {
                        ilist.add(i++, new LDC(ins, (int) p.getter));
                        ilist.add(i++, new IMul(ins));
                    } else if (p.getType() == Long.class) {
                        ilist.add(i++, new LDC(ins, (long) p.getter));
                        ilist.add(i++, new LMul(ins));
                    } else {
                        throw new IllegalStateException();
                    }
                } else if (in instanceof GetFieldInstruction) {
                    GetFieldInstruction sfi = (GetFieldInstruction) in;
                    Field f = sfi.getMyField();
                    if (f == null) {
                        continue;
                    }
                    Pair p = encr.getField(f.getPoolField());
                    if (p == null) {
                        continue;
                    }
                    // imul
                    if (p.getType() == Integer.class) {
                        ilist.add(++i, new LDC(ins, (int) p.setter));
                        ilist.add(++i, new IMul(ins));
                    } else if (p.getType() == Long.class) {
                        ilist.add(++i, new LDC(ins, (long) p.setter));
                        ilist.add(++i, new LMul(ins));
                    } else {
                        throw new IllegalStateException();
                    }
                }
            }
        }
    }
}
Also used : SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) ClassFile(net.runelite.asm.ClassFile) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) Method(net.runelite.asm.Method) 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) Code(net.runelite.asm.attributes.Code) Field(net.runelite.asm.Field) IMul(net.runelite.asm.attributes.code.instructions.IMul) LMul(net.runelite.asm.attributes.code.instructions.LMul) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction)

Example 3 with SetFieldInstruction

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

the class InstructionContext method resolve.

public InstructionContext resolve(// pushed from this
StackContext from) {
    InstructionContext ctx = this;
    if (ctx.getInstruction() instanceof SetFieldInstruction) {
        StackContext s = ctx.getPops().get(0);
        return s.getPushed().resolve(s);
    }
    if (ctx.getInstruction() instanceof DupInstruction) {
        DupInstruction d = (DupInstruction) ctx.getInstruction();
        StackContext s = d.getOriginal(from);
        return s.getPushed().resolve(s);
    }
    if (ctx.getInstruction() instanceof LVTInstruction) {
        LVTInstruction lvt = (LVTInstruction) ctx.getInstruction();
        Variables variables = ctx.getVariables();
        if (lvt.store()) {
            // is this right?
            StackContext s = ctx.getPops().get(0);
            return s.getPushed().resolve(s);
        } else {
            // variable being loaded
            VariableContext vctx = variables.get(lvt.getVariableIndex());
            assert vctx != null;
            InstructionContext storedCtx = vctx.getInstructionWhichStored();
            if (storedCtx == null)
                // initial parameter
                return ctx;
            if (vctx.isIsParameter())
                // parameter (storedCtx is invoking instruction in another frame). this lvt index is fixed.
                return ctx;
            return storedCtx.resolve(null);
        }
    }
    if (ctx.getInstruction() instanceof Swap) {
        Swap swap = (Swap) ctx.getInstruction();
        StackContext s = swap.getOriginal(from);
        return s.getPushed().resolve(s);
    }
    return ctx;
}
Also used : SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) Swap(net.runelite.asm.attributes.code.instructions.Swap) DupInstruction(net.runelite.asm.attributes.code.instruction.types.DupInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction)

Example 4 with SetFieldInstruction

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

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

the class FieldInliner method makeConstantValues.

private void makeConstantValues() {
    for (ClassFile cf : group.getClasses()) {
        for (Field f : cf.getFields()) {
            if (!f.isStatic() || !f.getType().equals(Type.STRING))
                continue;
            Object constantValue = f.getValue();
            if (constantValue != null)
                continue;
            List<FieldInstruction> sfis = fieldInstructions.get(f).stream().filter(f2 -> f2 instanceof SetFieldInstruction).collect(Collectors.toList());
            if (sfis.size() != 1)
                continue;
            SetFieldInstruction sfi = (SetFieldInstruction) sfis.get(0);
            Instruction ins = (Instruction) sfi;
            Method mOfSet = ins.getInstructions().getCode().getMethod();
            if (!mOfSet.getName().equals("<clinit>"))
                continue;
            // get prev instruction and change to a constant value
            Instructions instructions = mOfSet.getCode().getInstructions();
            int idx = instructions.getInstructions().indexOf(ins);
            assert idx != -1;
            Instruction prev = instructions.getInstructions().get(idx - 1);
            if (!(prev instanceof PushConstantInstruction))
                continue;
            PushConstantInstruction pci = (PushConstantInstruction) prev;
            constantValue = pci.getConstant();
            f.setValue(constantValue);
            fields.add(f);
            boolean b = instructions.getInstructions().remove(prev);
            assert b;
            b = instructions.getInstructions().remove(ins);
            assert b;
        }
    }
}
Also used : Logger(org.slf4j.Logger) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Field(net.runelite.asm.Field) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) LoggerFactory(org.slf4j.LoggerFactory) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction) Code(net.runelite.asm.attributes.Code) Multimap(com.google.common.collect.Multimap) Type(net.runelite.asm.Type) Deobfuscator(net.runelite.deob.Deobfuscator) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) ClassGroup(net.runelite.asm.ClassGroup) List(java.util.List) ClassFile(net.runelite.asm.ClassFile) HashMultimap(com.google.common.collect.HashMultimap) Method(net.runelite.asm.Method) LDC(net.runelite.asm.attributes.code.instructions.LDC) Instructions(net.runelite.asm.attributes.code.Instructions) Instruction(net.runelite.asm.attributes.code.Instruction) SetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction) 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) FieldInstruction(net.runelite.asm.attributes.code.instruction.types.FieldInstruction) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) 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) 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)

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