Search in sources :

Example 11 with PushConstantInstruction

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

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

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

the class MultiplyOneDeobfuscator method visit.

private void visit(MethodContext mctx) {
    for (InstructionContext ictx : mctx.getInstructionContexts()) {
        Instruction instruction = ictx.getInstruction();
        if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
            continue;
        }
        Instructions ins = ictx.getInstruction().getInstructions();
        if (ins == null) {
            continue;
        }
        List<Instruction> ilist = ins.getInstructions();
        if (!ilist.contains(ictx.getInstruction())) {
            // already done
            continue;
        }
        StackContext one = ictx.getPops().get(0);
        StackContext two = ictx.getPops().get(1);
        StackContext other = null;
        int removeIdx = -1;
        if (one.getPushed().getInstruction() instanceof PushConstantInstruction && DMath.equals((Number) ((PushConstantInstruction) one.getPushed().getInstruction()).getConstant(), 1)) {
            removeIdx = 0;
            other = two;
        } else if (two.getPushed().getInstruction() instanceof PushConstantInstruction && DMath.equals((Number) ((PushConstantInstruction) two.getPushed().getInstruction()).getConstant(), 1)) {
            removeIdx = 1;
            other = one;
        }
        if (removeIdx == -1) {
            continue;
        }
        if (onlyConstants && !(other.getPushed().getInstruction() instanceof PushConstantInstruction)) {
            continue;
        }
        if (!MultiplicationDeobfuscator.isOnlyPath(ictx, removeIdx == 0 ? one : two)) {
            continue;
        }
        // remove 1
        ictx.removeStack(removeIdx);
        // remove mul
        ins.remove(instruction);
        ++count;
    }
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) StackContext(net.runelite.asm.execution.StackContext) IMul(net.runelite.asm.attributes.code.instructions.IMul) Instructions(net.runelite.asm.attributes.code.Instructions) LMul(net.runelite.asm.attributes.code.instructions.LMul) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instruction(net.runelite.asm.attributes.code.Instruction)

Example 14 with PushConstantInstruction

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

the class MultiplyZeroDeobfuscator method visit.

private void visit(MethodContext mctx) {
    for (InstructionContext ictx : mctx.getInstructionContexts()) {
        Instruction instruction = ictx.getInstruction();
        Instructions ins = instruction.getInstructions();
        if (ins == null) {
            continue;
        }
        if (!(instruction instanceof IMul) && !(instruction instanceof LMul)) {
            continue;
        }
        List<Instruction> ilist = ins.getInstructions();
        StackContext one = ictx.getPops().get(0);
        StackContext two = ictx.getPops().get(1);
        Instruction ione = one.getPushed().getInstruction(), itwo = two.getPushed().getInstruction();
        boolean remove = false;
        if (ione instanceof PushConstantInstruction) {
            PushConstantInstruction pci = (PushConstantInstruction) ione;
            Number value = (Number) pci.getConstant();
            if (DMath.equals(value, 0)) {
                remove = true;
            }
        }
        if (itwo instanceof PushConstantInstruction) {
            PushConstantInstruction pci = (PushConstantInstruction) itwo;
            Number value = (Number) pci.getConstant();
            if (DMath.equals(value, 0)) {
                remove = true;
            }
        }
        if (remove == false) {
            continue;
        }
        if (!ilist.contains(instruction)) {
            // already done
            continue;
        }
        if (!MultiplicationDeobfuscator.isOnlyPath(ictx, null)) {
            continue;
        }
        // remove both, remove imul, push 0
        ictx.removeStack(1);
        ictx.removeStack(0);
        if (instruction instanceof IMul) {
            ins.replace(instruction, new LDC(ins, 0));
        } else if (instruction instanceof LMul) {
            ins.replace(instruction, new LDC(ins, 0L));
        } else {
            throw new IllegalStateException();
        }
        ++count;
    }
}
Also used : InstructionContext(net.runelite.asm.execution.InstructionContext) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) StackContext(net.runelite.asm.execution.StackContext) IMul(net.runelite.asm.attributes.code.instructions.IMul) Instructions(net.runelite.asm.attributes.code.Instructions) LDC(net.runelite.asm.attributes.code.instructions.LDC) LMul(net.runelite.asm.attributes.code.instructions.LMul) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) Instruction(net.runelite.asm.attributes.code.Instruction)

Example 15 with PushConstantInstruction

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

the class ConstantParameter method findDeadParameters.

private void findDeadParameters(InstructionContext ins) {
    List<ConstantMethodParameter> parameters = this.findParametersForMethod(ins.getFrame().getMethod());
    for (ConstantMethodParameter parameter : parameters) {
        int lvtIndex = parameter.lvtIndex;
        if (parameter.invalid) {
            continue;
        }
        if (ins.getInstruction() instanceof LVTInstruction) {
            LVTInstruction lvt = (LVTInstruction) ins.getInstruction();
            if (lvt.getVariableIndex() != lvtIndex) {
                continue;
            }
            if (lvt.store() || ins.getInstruction().getType() == InstructionType.IINC) {
                parameter.invalid = true;
                // value changes at some point, parameter is used
                continue;
            }
            // check what pops the parameter is a comparison
            assert ins.getPushes().size() == 1;
            StackContext sctx = ins.getPushes().get(0);
            if (sctx.getPopped().size() != 1 || !(sctx.getPopped().get(0).getInstruction() instanceof ComparisonInstruction)) {
                parameter.invalid = true;
                continue;
            }
        }
        if (!(ins.getInstruction() instanceof ComparisonInstruction)) {
            continue;
        }
        // assume that this will always be variable index #paramIndex comp with a constant.
        ComparisonInstruction comp = (ComparisonInstruction) ins.getInstruction();
        StackContext one, two = null;
        if (comp instanceof If0) {
            one = ins.getPops().get(0);
        } else if (comp instanceof If) {
            one = ins.getPops().get(0);
            two = ins.getPops().get(1);
        } else {
            throw new RuntimeException("Unknown comp ins");
        }
        // find if one is a lvt ins
        LVTInstruction lvt = null;
        StackContext other = null;
        if (one.getPushed().getInstruction() instanceof LVTInstruction) {
            lvt = (LVTInstruction) one.getPushed().getInstruction();
            other = two;
        } else if (two != null && two.getPushed().getInstruction() instanceof LVTInstruction) {
            lvt = (LVTInstruction) two.getPushed().getInstruction();
            other = one;
        }
        assert lvt == null || !lvt.store();
        if (lvt == null || lvt.getVariableIndex() != lvtIndex) {
            continue;
        }
        Number otherValue = null;
        if (// two is null for if0
        two != null) {
            if (!(other.getPushed().getInstruction() instanceof PushConstantInstruction)) {
                parameter.invalid = true;
                continue;
            }
            PushConstantInstruction pc = (PushConstantInstruction) other.getPushed().getInstruction();
            otherValue = (Number) pc.getConstant();
        }
        for (Number value : parameter.values) {
            // the result of the comparison doesn't matter, only that it always goes the same direction for every invocation
            boolean result = doLogicalComparison(value, comp, otherValue);
            // not that all ifs for a specific parameter always take the same path
            if (parameter.result != null && parameter.result != result) {
                parameter.invalid = true;
            } else {
                parameter.operations.add(ins.getInstruction());
                parameter.result = result;
            }
        }
    }
}
Also used : If0(net.runelite.asm.attributes.code.instructions.If0) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) StackContext(net.runelite.asm.execution.StackContext) ComparisonInstruction(net.runelite.asm.attributes.code.instruction.types.ComparisonInstruction) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) If(net.runelite.asm.attributes.code.instructions.If)

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