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;
}
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;
}
}
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);
}
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;
}
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;
}
Aggregations