Search in sources :

Example 1 with ArithmeticExpr

use of org.mapleir.ir.code.expr.ArithmeticExpr in project maple-ir by LLVM-but-worse.

the class ConstantExpressionReorderPass method transform.

private int transform(ControlFlowGraph ir) {
    int i = 0;
    for (BasicBlock b : ir.vertices()) {
        for (Stmt stmt : b) {
            if (stmt.getOpcode() == COND_JUMP) {
                ConditionalJumpStmt cjs = (ConditionalJumpStmt) stmt;
                Expr r = cjs.getRight();
                Expr l = cjs.getLeft();
                ComparisonType type = cjs.getComparisonType();
                if (type == ComparisonType.EQ || type == ComparisonType.NE) {
                    if (shouldReorder(r, l)) {
                        cjs.setRight(null);
                        cjs.setLeft(null);
                        cjs.setLeft(r);
                        cjs.setRight(l);
                        i++;
                    }
                }
            }
            for (Expr e : stmt.enumerateOnlyChildren()) {
                if (e.getOpcode() == ARITHMETIC) {
                    ArithmeticExpr arith = (ArithmeticExpr) e;
                    Expr r = arith.getRight();
                    Expr l = arith.getLeft();
                    Operator op = arith.getOperator();
                    if (!op.doesOrderMatter()) {
                        if (shouldReorder(r, l)) {
                            arith.setRight(null);
                            arith.setLeft(null);
                            arith.setLeft(r);
                            arith.setRight(l);
                            i++;
                        }
                    }
                }
            }
        }
    }
    return i;
}
Also used : ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) Operator(org.mapleir.ir.code.expr.ArithmeticExpr.Operator) ComparisonType(org.mapleir.ir.code.stmt.ConditionalJumpStmt.ComparisonType) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) Expr(org.mapleir.ir.code.Expr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) BasicBlock(org.mapleir.ir.cfg.BasicBlock) Stmt(org.mapleir.ir.code.Stmt) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt)

Example 2 with ArithmeticExpr

use of org.mapleir.ir.code.expr.ArithmeticExpr in project maple-ir by LLVM-but-worse.

the class FieldRSADecryptionPass method bcheck1.

static boolean bcheck1(Expr e) {
    if (e.getOpcode() == ARITHMETIC) {
        ArithmeticExpr ar = (ArithmeticExpr) e;
        Operator op = ar.getOperator();
        return op != Operator.MUL && op != Operator.ADD;
    } else {
        return true;
    }
}
Also used : Operator(org.mapleir.ir.code.expr.ArithmeticExpr.Operator) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr)

Example 3 with ArithmeticExpr

use of org.mapleir.ir.code.expr.ArithmeticExpr in project maple-ir by LLVM-but-worse.

the class ExpressionEvaluator method evalPossibleValues0.

private TaintableSet<ConstantExpr> evalPossibleValues0(NullPermeableHashMap<ControlFlowGraph, Set<Local>> visited, LocalValueResolver resolver, Expr e) {
    if (e.getOpcode() == CONST_LOAD) {
        TaintableSet<ConstantExpr> set = new TaintableSet<>();
        set.add((ConstantExpr) e);
        return set;
    } else /*else if(e.getOpcode() == PHI) {
			PhiExpr phi = (PhiExpr) e;
			
			TaintableSet<ConstantExpr> set = new HashSet<>();
			
			for(Expr pA : phi.getArguments().values()) {
				TaintableSet<ConstantExpr> s = evalPossibleValues(resolver, pA);
				set.union(s);
			}
			
			return set;
		}*/
    if (e.getOpcode() == ARITHMETIC) {
        ArithmeticExpr ae = (ArithmeticExpr) e;
        Expr l = ae.getLeft();
        Expr r = ae.getRight();
        TaintableSet<ConstantExpr> le = evalPossibleValues0(visited, resolver, l);
        TaintableSet<ConstantExpr> re = evalPossibleValues0(visited, resolver, r);
        TaintableSet<ConstantExpr> results = new TaintableSet<>(le.isTainted() | re.isTainted());
        for (Iterator<Pair<ConstantExpr, ConstantExpr>> it = le.product(re); it.hasNext(); ) {
            Pair<ConstantExpr, ConstantExpr> lcrc = it.next();
            ConstantExpr lc = lcrc.getKey();
            ConstantExpr rc = lcrc.getValue();
            EvaluationFunctor<Number> b = factory.arithmetic(lc.getType(), rc.getType(), ae.getType(), ae.getOperator());
            results.add(new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant())));
        }
        return results;
    } else if (e.getOpcode() == NEGATE) {
        NegationExpr neg = (NegationExpr) e;
        TaintableSet<ConstantExpr> inputs = evalPossibleValues0(visited, resolver, neg.getExpression());
        TaintableSet<ConstantExpr> outputs = new TaintableSet<>(inputs.isTainted());
        for (ConstantExpr c : inputs) {
            EvaluationFunctor<Number> b = factory.negate(c.getType());
            outputs.add(new ConstantExpr(b.eval(c.getConstant())));
        }
        return outputs;
    } else if (e.getOpcode() == LOCAL_LOAD) {
        VarExpr v = (VarExpr) e;
        Local l = v.getLocal();
        ControlFlowGraph g = e.getBlock().getGraph();
        visited.getNonNull(g).add(l);
        TaintableSet<Expr> defExprs = resolver.getValues(g, l);
        TaintableSet<ConstantExpr> vals = new TaintableSet<>(defExprs.isTainted());
        for (Expr defE : defExprs) {
            if (defE.getOpcode() == LOCAL_LOAD) {
                VarExpr v2 = (VarExpr) defE;
                Local l2 = v2.getLocal();
                if (visited.getNonNull(g).contains(l2)) {
                    continue;
                }
                visited.getNonNull(g).add(l2);
            }
            TaintableSet<ConstantExpr> defConstVals = evalPossibleValues0(visited, resolver, defE);
            vals.union(defConstVals);
        }
        return vals;
    } else if (e.getOpcode() == CAST) {
        CastExpr cast = (CastExpr) e;
        TaintableSet<ConstantExpr> inputs = evalPossibleValues0(visited, resolver, cast.getExpression());
        TaintableSet<ConstantExpr> outputs = new TaintableSet<>(inputs.isTainted());
        for (ConstantExpr ce : inputs) {
            // TODO: czech out::
            // can get expressions like (double)({lvar7_1 * 4})
            // where {lvar7_1 * 4} has type INT but the real
            // eval consts are all bytes or shorts etc
            /*if(!ce.getType().equals(cast.getExpression().getType())) {
					System.err.printf("want to cast %s%n", cast);
					System.err.printf(" in: %s, death: %s%n", set, ce);
					throw new IllegalStateException(ce.getType() + " : " + cast.getExpression().getType());
				}*/
            Type from = ce.getType();
            Type to = cast.getType();
            boolean p1 = TypeUtils.isPrimitive(from);
            boolean p2 = TypeUtils.isPrimitive(to);
            if (p1 != p2) {
                throw new IllegalStateException(from + " to " + to);
            }
            if (!p1 && !p2) {
                throw new IllegalStateException(from + " to " + to);
            // return new TaintableSet<>();
            }
            EvaluationFunctor<Number> b = factory.cast(from, to);
            outputs.add(new ConstantExpr(b.eval(ce.getConstant())));
        }
        return outputs;
    } else if (e.getOpcode() == COMPARE) {
    // throw new UnsupportedOperationException("todo lmao");
    // ComparisonExpr comp = (ComparisonExpr) e;
    // Expr l = comp.getLeft();
    // Expr r = comp.getRight();
    // 
    // Expr le = eval(pool, l);
    // Expr re = eval(pool, r);
    // 
    // if(le != null && re != null) {
    // ConstantExpr lc = (ConstantExpr) le;
    // ConstantExpr rc = (ConstantExpr) re;
    // 
    // Bridge b = getComparisonBridge(lc.getType(), rc.getType(), comp.getComparisonType());
    // 
    // System.out.println(b.method);
    // System.out.println(comp + " -> " + b.eval(lc.getConstant(), rc.getConstant()));
    // ConstantExpr cr = new ConstantExpr((int)b.eval(lc.getConstant(), rc.getConstant()));
    // return cr;
    // }
    }
    /* uncomputable value, i.e. non const. */
    return new TaintableSet<>(true);
}
Also used : ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) Local(org.mapleir.ir.locals.Local) Type(org.objectweb.asm.Type) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) CastExpr(org.mapleir.ir.code.expr.CastExpr) ComparisonExpr(org.mapleir.ir.code.expr.ComparisonExpr) NegationExpr(org.mapleir.ir.code.expr.NegationExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) Iterator(java.util.Iterator) CastExpr(org.mapleir.ir.code.expr.CastExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) TaintableSet(org.mapleir.stdlib.collections.taint.TaintableSet) Pair(javafx.util.Pair) NegationExpr(org.mapleir.ir.code.expr.NegationExpr)

Example 4 with ArithmeticExpr

use of org.mapleir.ir.code.expr.ArithmeticExpr in project maple-ir by LLVM-but-worse.

the class ExpressionEvaluator method eval.

public ConstantExpr eval(LocalsPool pool, Expr e) {
    if (e.getOpcode() == CONST_LOAD) {
        return ((ConstantExpr) e).copy();
    } else if (e.getOpcode() == ARITHMETIC) {
        ArithmeticExpr ae = (ArithmeticExpr) e;
        Expr l = ae.getLeft();
        Expr r = ae.getRight();
        Expr le = eval(pool, l);
        Expr re = eval(pool, r);
        if (le != null && re != null) {
            ConstantExpr lc = (ConstantExpr) le;
            ConstantExpr rc = (ConstantExpr) re;
            EvaluationFunctor<Number> b = factory.arithmetic(lc.getType(), rc.getType(), ae.getType(), ae.getOperator());
            return new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant()));
        }
    } else if (e.getOpcode() == NEGATE) {
        NegationExpr neg = (NegationExpr) e;
        Expr e2 = eval(pool, neg.getExpression());
        if (e2 != null) {
            ConstantExpr ce = (ConstantExpr) e2;
            EvaluationFunctor<Number> b = factory.negate(e2.getType());
            return new ConstantExpr(b.eval(ce.getConstant()));
        }
    } else if (e.getOpcode() == LOCAL_LOAD) {
        VarExpr v = (VarExpr) e;
        Local l = v.getLocal();
        AbstractCopyStmt def = pool.defs.get(l);
        Expr rhs = def.getExpression();
        if (rhs.getOpcode() == LOCAL_LOAD) {
            VarExpr v2 = (VarExpr) rhs;
            // synthetic copies lhs = rhs;
            if (v2.getLocal() == l) {
                return null;
            }
        }
        return eval(pool, rhs);
    } else if (e.getOpcode() == CAST) {
        CastExpr cast = (CastExpr) e;
        Expr e2 = eval(pool, cast.getExpression());
        if (e2 != null) {
            ConstantExpr ce = (ConstantExpr) e2;
            if (!ce.getType().equals(cast.getExpression().getType())) {
                throw new IllegalStateException(ce.getType() + " : " + cast.getExpression().getType());
            }
            Type from = ce.getType();
            Type to = cast.getType();
            boolean p1 = TypeUtils.isPrimitive(from);
            boolean p2 = TypeUtils.isPrimitive(to);
            if (p1 != p2) {
                throw new IllegalStateException(from + " to " + to);
            }
            if (!p1 && !p2) {
                return null;
            }
            EvaluationFunctor<Number> b = factory.cast(from, to);
            return new ConstantExpr(b.eval(ce.getConstant()), to);
        }
    } else if (e.getOpcode() == COMPARE) {
        ComparisonExpr comp = (ComparisonExpr) e;
        Expr l = comp.getLeft();
        Expr r = comp.getRight();
        Expr le = eval(pool, l);
        Expr re = eval(pool, r);
        if (le != null && re != null) {
            ConstantExpr lc = (ConstantExpr) le;
            ConstantExpr rc = (ConstantExpr) re;
            EvaluationFunctor<Number> b = factory.compare(lc.getType(), rc.getType(), comp.getComparisonType());
            return new ConstantExpr(b.eval(lc.getConstant(), rc.getConstant()), Type.INT_TYPE);
        }
    }
    return null;
}
Also used : ComparisonExpr(org.mapleir.ir.code.expr.ComparisonExpr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) Local(org.mapleir.ir.locals.Local) Type(org.objectweb.asm.Type) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) CastExpr(org.mapleir.ir.code.expr.CastExpr) ComparisonExpr(org.mapleir.ir.code.expr.ComparisonExpr) NegationExpr(org.mapleir.ir.code.expr.NegationExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) CastExpr(org.mapleir.ir.code.expr.CastExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) NegationExpr(org.mapleir.ir.code.expr.NegationExpr)

Example 5 with ArithmeticExpr

use of org.mapleir.ir.code.expr.ArithmeticExpr in project maple-ir by LLVM-but-worse.

the class ExpressionEvaluator method reassociate.

private ArithmeticExpr reassociate(LocalsPool pool, ArithmeticExpr ae) {
    ArithmeticExpr leftAe = (ArithmeticExpr) ae.getLeft();
    Operator operatorA = leftAe.getOperator();
    Operator operatorB = ae.getOperator();
    Expr r1 = eval(pool, leftAe.getRight());
    Expr r2 = eval(pool, ae.getRight());
    if (r1 != null && r2 != null) {
        ConstantExpr cr1 = (ConstantExpr) r1;
        ConstantExpr cr2 = (ConstantExpr) r2;
        int sign = 0;
        if ((operatorA == MUL && operatorB == MUL)) {
            sign = 1;
        } else if (operatorA == ADD && (operatorB == ADD || operatorB == SUB)) {
            // what about overflow?? integers mod 2^32 forms a group over addition...should be ok?
            sign = 1;
        } else if (operatorA == SUB && (operatorB == ADD || operatorB == SUB)) {
            sign = -1;
        }
        if (sign != 0) {
            ConstantExpr cr1r2 = eval(pool, new ArithmeticExpr(sign > 0 ? cr2 : new NegationExpr(cr2), cr1, operatorB));
            Object associated = cr1r2.getConstant();
            return new ArithmeticExpr(new ConstantExpr(associated, cr1r2.getType()), leftAe.getLeft().copy(), operatorA);
        }
    }
    return null;
}
Also used : Operator(org.mapleir.ir.code.expr.ArithmeticExpr.Operator) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) CastExpr(org.mapleir.ir.code.expr.CastExpr) ComparisonExpr(org.mapleir.ir.code.expr.ComparisonExpr) NegationExpr(org.mapleir.ir.code.expr.NegationExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) NegationExpr(org.mapleir.ir.code.expr.NegationExpr)

Aggregations

ArithmeticExpr (org.mapleir.ir.code.expr.ArithmeticExpr)8 Expr (org.mapleir.ir.code.Expr)7 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)6 CastExpr (org.mapleir.ir.code.expr.CastExpr)4 ComparisonExpr (org.mapleir.ir.code.expr.ComparisonExpr)4 NegationExpr (org.mapleir.ir.code.expr.NegationExpr)4 VarExpr (org.mapleir.ir.code.expr.VarExpr)4 BasicBlock (org.mapleir.ir.cfg.BasicBlock)3 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)3 Stmt (org.mapleir.ir.code.Stmt)3 Operator (org.mapleir.ir.code.expr.ArithmeticExpr.Operator)3 FieldLoadExpr (org.mapleir.ir.code.expr.FieldLoadExpr)2 FieldStoreStmt (org.mapleir.ir.code.stmt.FieldStoreStmt)2 Local (org.mapleir.ir.locals.Local)2 Type (org.objectweb.asm.Type)2 MethodNode (org.objectweb.asm.tree.MethodNode)2 BigInteger (java.math.BigInteger)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 Pair (javafx.util.Pair)1