Search in sources :

Example 1 with ISub

use of net.runelite.asm.attributes.code.instructions.ISub in project runelite by runelite.

the class MultiplicationDeobfuscator method parseExpression.

public static MultiplicationExpression parseExpression(InstructionContext ctx, Class want) {
    MultiplicationExpression me = new MultiplicationExpression();
    if (ctx.getInstruction() instanceof LVTInstruction) {
        LVTInstruction lvt = (LVTInstruction) ctx.getInstruction();
        // loading a variable
        if (!lvt.store()) {
            // var index
            int idx = lvt.getVariableIndex();
            // variables at time of execution
            Variables vars = ctx.getVariables();
            // get the variable
            VariableContext vctx = vars.get(idx);
            if (// ?
            vctx.getRead().size() == 1) {
                // this is an istore
                InstructionContext storeCtx = vctx.getInstructionWhichStored();
                if (storeCtx.getInstruction() instanceof LVTInstruction) {
                    // invoking funcs can put stuff in lvt
                    LVTInstruction storelvt = (LVTInstruction) storeCtx.getInstruction();
                    if (storelvt instanceof IInc)
                        throw new IllegalStateException();
                    assert storelvt.store();
                    InstructionContext pushed = storeCtx.getPops().get(0).getPushed();
                    return parseExpression(pushed, want);
                }
            }
        }
    }
    if (ctx.getInstruction() instanceof PushConstantInstruction) {
        if (ctx.getInstruction() instanceof BiPush || ctx.getInstruction() instanceof SiPush) {
            throw new IllegalStateException();
        }
        me.instructions.add(ctx);
        return me;
    }
    for (StackContext sctx : ctx.getPops()) {
        if (ctx.getInstruction().getClass() == want) {
            if (!isOnlyPath(ctx, sctx))
                continue;
        }
        InstructionContext i = sctx.getPushed();
        // if this instruction is imul, look at pops
        if (ctx.getInstruction().getClass() == want) {
            if (i.getInstruction() instanceof Swap) {
                logger.debug("Resolving swap");
                Swap swap = (Swap) i.getInstruction();
                sctx = swap.getOriginal(sctx);
                i = sctx.getPushed();
            }
            if (i.getInstruction() instanceof PushConstantInstruction) {
                // bipush/sipush are always not obfuscated
                if (i.getInstruction() instanceof BiPush || i.getInstruction() instanceof SiPush)
                    continue;
                // a constant of imul
                me.instructions.add(i);
            } else if (i.getInstruction().getClass() == want) {
                // chained imul, append to me
                try {
                    MultiplicationExpression other = parseExpression(i, want);
                    if (other.dupmagic != null) {
                        assert me.dupmagic == null;
                        me.dupmagic = other.dupmagic;
                    }
                    me.instructions.addAll(other.instructions);
                    me.dupedInstructions.addAll(other.dupedInstructions);
                    me.subexpressions.addAll(other.subexpressions);
                } catch (IllegalStateException ex) {
                // this is ok? just don't include it?
                }
            } else if (i.getInstruction() instanceof IAdd || i.getInstruction() instanceof ISub || i.getInstruction() instanceof LAdd || i.getInstruction() instanceof LSub) {
                // imul using result of iadd or isub. evaluate expression
                try {
                    MultiplicationExpression other = parseExpression(i, want);
                    assert other.dupmagic == null;
                    // subexpr
                    me.subexpressions.add(other);
                } catch (IllegalStateException ex) {
                    assert me.subexpressions.isEmpty();
                // subexpression is too complex. we can still simplify the top level though
                }
            } else if (i.getInstruction() instanceof DupInstruction) {
                DupInstruction dup = (DupInstruction) i.getInstruction();
                // find other branch of the dup instruction
                // sctx = what dup pushed, find other
                // other side of dup
                StackContext otherCtx = dup.getOtherBranch(sctx);
                // what popped other side of dup. is this right?
                InstructionContext otherCtxI = otherCtx.getPopped().get(0);
                if (otherCtxI.getInstruction().getClass() == want) {
                    // assert otherCtxI.getInstruction() instanceof IMul;
                    // other side of that imul
                    InstructionContext pushConstant = otherCtxI.getPops().get(0).getPushed();
                    assert pushConstant.getInstruction() instanceof LDC;
                    me.dupmagic = pushConstant;
                    // original
                    StackContext orig = dup.getOriginal(sctx);
                    try {
                        MultiplicationExpression other = parseExpression(orig.getPushed(), want);
                        // done to it affect that, too. so multiply it by existing values?
                        if (orig.getPushed().getInstruction() instanceof IAdd || orig.getPushed().getInstruction() instanceof ISub || orig.getPushed().getInstruction() instanceof LAdd || orig.getPushed().getInstruction() instanceof LSub) {
                            me.subexpressions.add(other);
                        } else {
                            assert other.dupmagic == null;
                            me.instructions.addAll(other.instructions);
                            me.dupedInstructions.addAll(other.instructions);
                            me.subexpressions.addAll(other.subexpressions);
                        }
                    } catch (IllegalStateException ex) {
                        assert me.subexpressions.isEmpty();
                    }
                }
            } else if (i.getInstruction() instanceof GetFieldInstruction) {
                me.fieldInstructions.add(i);
            // non constant, ignore
            } else {
            // System.out.println("imul pops something I don't know " + i.getInstruction());
            }
        } else // this is an iadd/sub
        if (ctx.getInstruction() instanceof IAdd || ctx.getInstruction() instanceof ISub || ctx.getInstruction() instanceof LAdd || ctx.getInstruction() instanceof LSub) {
            // parse this side of the add/sub
            MultiplicationExpression other = parseExpression(i, want);
            me.subexpressions.add(other);
        } else {
        // System.out.println(ctx.getInstruction() + " pops something I dont know " + i.getInstruction());
        }
    }
    if (me.instructions.isEmpty() && me.subexpressions.isEmpty())
        throw new IllegalStateException();
    return me;
}
Also used : SiPush(net.runelite.asm.attributes.code.instructions.SiPush) InstructionContext(net.runelite.asm.execution.InstructionContext) PushConstantInstruction(net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction) DupInstruction(net.runelite.asm.attributes.code.instruction.types.DupInstruction) LDC(net.runelite.asm.attributes.code.instructions.LDC) LVTInstruction(net.runelite.asm.attributes.code.instruction.types.LVTInstruction) VariableContext(net.runelite.asm.execution.VariableContext) BiPush(net.runelite.asm.attributes.code.instructions.BiPush) Variables(net.runelite.asm.execution.Variables) Swap(net.runelite.asm.attributes.code.instructions.Swap) ISub(net.runelite.asm.attributes.code.instructions.ISub) StackContext(net.runelite.asm.execution.StackContext) LAdd(net.runelite.asm.attributes.code.instructions.LAdd) IInc(net.runelite.asm.attributes.code.instructions.IInc) LSub(net.runelite.asm.attributes.code.instructions.LSub) IAdd(net.runelite.asm.attributes.code.instructions.IAdd) GetFieldInstruction(net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction)

Example 2 with ISub

use of net.runelite.asm.attributes.code.instructions.ISub 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)

Aggregations

GetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction)2 PushConstantInstruction (net.runelite.asm.attributes.code.instruction.types.PushConstantInstruction)2 IAdd (net.runelite.asm.attributes.code.instructions.IAdd)2 ISub (net.runelite.asm.attributes.code.instructions.ISub)2 LAdd (net.runelite.asm.attributes.code.instructions.LAdd)2 LDC (net.runelite.asm.attributes.code.instructions.LDC)2 LSub (net.runelite.asm.attributes.code.instructions.LSub)2 InstructionContext (net.runelite.asm.execution.InstructionContext)2 HashSet (java.util.HashSet)1 Field (net.runelite.asm.Field)1 Instruction (net.runelite.asm.attributes.code.Instruction)1 ArrayStoreInstruction (net.runelite.asm.attributes.code.instruction.types.ArrayStoreInstruction)1 DivisionInstruction (net.runelite.asm.attributes.code.instruction.types.DivisionInstruction)1 DupInstruction (net.runelite.asm.attributes.code.instruction.types.DupInstruction)1 FieldInstruction (net.runelite.asm.attributes.code.instruction.types.FieldInstruction)1 InvokeInstruction (net.runelite.asm.attributes.code.instruction.types.InvokeInstruction)1 LVTInstruction (net.runelite.asm.attributes.code.instruction.types.LVTInstruction)1 SetFieldInstruction (net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction)1 BiPush (net.runelite.asm.attributes.code.instructions.BiPush)1 IInc (net.runelite.asm.attributes.code.instructions.IInc)1