Search in sources :

Example 6 with ConstantExpr

use of org.mapleir.ir.code.expr.ConstantExpr 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 7 with ConstantExpr

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

the class SSAGenPass method makeValue.

private void makeValue(AbstractCopyStmt copy, VersionedLocal ssaL) {
    /* Attempts to find the 'value' of a local.
		 * The value can be the following types:
		 *   param - assigned by caller method
		 *   phi - set by a phi node
		 *   const - compiletime constant
		 *   var - runtime computed
		 *   
		 * when a copy x = y, is visited,
		 * if y is a var, x inherits
		 * the value and value type.
		 * */
    Expr e = copy.getExpression();
    int opcode = e.getOpcode();
    if (opcode == Opcode.LOCAL_LOAD) {
        if (copy.isSynthetic()) {
            /* equals itself (pure value).*/
            LatestValue value = new LatestValue(builder.graph, LatestValue.PARAM, ssaL, null);
            latest.put(ssaL, value);
        } else {
            /* i.e. x = y, where x and y are both variables.
				 * 
				 * It is expected that the local uses of the copy 
				 * (rhs) are visited before the target is.
				 */
            VarExpr rhs = (VarExpr) e;
            VersionedLocal rhsL = (VersionedLocal) rhs.getLocal();
            /* the rhsL must have been visited already
				 * and the lhsL must not have been.*/
            if (!latest.containsKey(ssaL)) {
                if (latest.containsKey(rhsL)) {
                    LatestValue anc = latest.get(rhsL);
                    // TODO: maybe advance the src local if we
                    // can validate an expr propagation to the
                    // new copy dst.
                    LatestValue value = new LatestValue(builder.graph, anc.getType(), rhsL, anc.getSuggestedValue(), anc.getSource());
                    value.importConstraints(anc);
                    latest.put(ssaL, value);
                } else {
                    throw new IllegalStateException("Non anc parent: " + ssaL + " = " + rhsL + " (def: " + pool.defs.get(rhsL) + ")");
                }
            } else {
                throw new IllegalStateException("Revisit def " + ssaL + " ( = " + rhsL + ")");
            }
        }
    } else {
        LatestValue value;
        if (opcode == Opcode.CONST_LOAD) {
            ConstantExpr ce = (ConstantExpr) e;
            value = new LatestValue(builder.graph, LatestValue.CONST, ce, null);
        } else if ((opcode & Opcode.CLASS_PHI) == Opcode.CLASS_PHI) {
            value = new LatestValue(builder.graph, LatestValue.PHI, ssaL, null);
        } else {
            if (e.getOpcode() == Opcode.LOCAL_LOAD) {
                throw new RuntimeException(copy + "    " + e);
            }
            value = new LatestValue(builder.graph, LatestValue.VAR, e, ssaL);
            value.makeConstraints(e);
        }
        latest.put(ssaL, value);
    }
// System.out.println("made val " + ssaL + " -> " + latest.get(ssaL));
}
Also used : LatestValue(org.mapleir.ir.cfg.builder.ssaopt.LatestValue) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) PhiExpr(org.mapleir.ir.code.expr.PhiExpr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint)

Example 8 with ConstantExpr

use of org.mapleir.ir.code.expr.ConstantExpr 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 9 with ConstantExpr

use of org.mapleir.ir.code.expr.ConstantExpr 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)

Example 10 with ConstantExpr

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

the class ExpressionEvaluator method simplifyMultiplication.

private Expr simplifyMultiplication(LocalsPool pool, ArithmeticExpr e) {
    if (e.getOperator() != Operator.MUL)
        throw new IllegalArgumentException("Only works on multiplication exprs");
    Expr r = e.getRight();
    ConstantExpr re = eval(pool, r);
    if (re != null) {
        Object o = re.getConstant();
        if (o instanceof Integer || o instanceof Long) {
            if (FieldRSADecryptionPass.__eq((Number) o, 1, o instanceof Long)) {
                return e.getLeft().copy();
            } else if (FieldRSADecryptionPass.__eq((Number) o, 0, o instanceof Long)) {
                return new ConstantExpr(0, re.getType());
            }
        }
    }
    return null;
}
Also used : 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) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr)

Aggregations

ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)14 Expr (org.mapleir.ir.code.Expr)9 VarExpr (org.mapleir.ir.code.expr.VarExpr)8 ArithmeticExpr (org.mapleir.ir.code.expr.ArithmeticExpr)7 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)4 CodeUnit (org.mapleir.ir.code.CodeUnit)4 CastExpr (org.mapleir.ir.code.expr.CastExpr)4 ComparisonExpr (org.mapleir.ir.code.expr.ComparisonExpr)4 NegationExpr (org.mapleir.ir.code.expr.NegationExpr)4 Type (org.objectweb.asm.Type)4 BigInteger (java.math.BigInteger)3 HashSet (java.util.HashSet)3 MethodNode (org.objectweb.asm.tree.MethodNode)3 Pair (javafx.util.Pair)2 BasicBlock (org.mapleir.ir.cfg.BasicBlock)2 Stmt (org.mapleir.ir.code.Stmt)2 FieldLoadExpr (org.mapleir.ir.code.expr.FieldLoadExpr)2 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)2 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)2 FieldStoreStmt (org.mapleir.ir.code.stmt.FieldStoreStmt)2