use of org.mapleir.ir.code.CodeUnit in project maple-ir by LLVM-but-worse.
the class ConstantParameterPass method inlineConstant.
private void inlineConstant(ControlFlowGraph cfg, int argLocalIndex, Object o) {
/* we don't actually demote the synthetic copy
* here as we would also need to change the
* method desc and we can't do that until
* later so we defer it. */
LocalsPool pool = cfg.getLocals();
/* create the spill variable but not the
* actual definition yet. */
VersionedLocal argLocal = pool.get(argLocalIndex, 0, false);
VersionedLocal spill = pool.makeLatestVersion(argLocal);
AbstractCopyStmt synthParamCopy = pool.defs.get(argLocal);
ConstantExpr rhsVal = new ConstantExpr(o, synthParamCopy.getType() == Type.BOOLEAN_TYPE ? Type.BYTE_TYPE : synthParamCopy.getType());
/* we have to maintain local references in
* phis as opposed to direct constant refs,
* so we go through every use of the argLocal
* and either replace it with the constant or
* a reference to the spill local if it is in
* a phi. */
Set<VarExpr> spillUses = new HashSet<>();
boolean requireSpill = false;
Iterator<VarExpr> it = pool.uses.get(argLocal).iterator();
while (it.hasNext()) {
VarExpr v = it.next();
if (v.getParent() == null) {
/* the use is in a phi, we can't
* remove the def.
*
* we also replace the old var
* with the new spill one so we
* have to add this as a use of
* the new spill local. */
spillUses.add(v);
v.setLocal(spill);
requireSpill = true;
} else {
CodeUnit par = v.getParent();
par.writeAt(rhsVal.copy(), par.indexOf(v));
}
/* this use is no longer associated
* with the old argLocal. */
it.remove();
}
if (pool.uses.get(argLocal).size() != 0) {
throw new IllegalStateException(String.format("l:%s, uses:%s", argLocal, pool.uses.get(argLocal)));
}
if (requireSpill) {
/* generate the copy for the spill (v = const) */
CopyVarStmt spillCopy = new CopyVarStmt(new VarExpr(spill, synthParamCopy.getVariable().getType()), rhsVal);
synthParamCopy.getBlock().add(spillCopy);
/* initialise data entries for the new spill
* variable. */
pool.defs.put(spill, spillCopy);
pool.uses.put(spill, spillUses);
}
}
use of org.mapleir.ir.code.CodeUnit in project maple-ir by LLVM-but-worse.
the class ConstantParameterPass method patchCall.
private void patchCall(String newDesc, Expr call, boolean[] dead) {
if (call.getOpcode() == Opcode.INIT_OBJ) {
InitialisedObjectExpr init = (InitialisedObjectExpr) call;
CodeUnit parent = init.getParent();
Expr[] newArgs = buildArgs(init.getArgumentExprs(), false, dead);
InitialisedObjectExpr init2 = new InitialisedObjectExpr(init.getOwner(), newDesc, newArgs);
parent.writeAt(init2, parent.indexOf(init));
} else if (call.getOpcode() == Opcode.INVOKE) {
InvocationExpr invoke = (InvocationExpr) call;
if (invoke.isDynamic())
throw new UnsupportedOperationException(call.toString());
CodeUnit parent = invoke.getParent();
Expr[] newArgs = buildArgs(invoke.getArgumentExprs(), invoke.getCallType() != InvocationExpr.CallType.STATIC, dead);
InvocationExpr invoke2 = invoke.copy();
parent.writeAt(invoke2, parent.indexOf(invoke));
} else {
throw new UnsupportedOperationException(call.toString());
}
}
use of org.mapleir.ir.code.CodeUnit in project maple-ir by LLVM-but-worse.
the class FieldRSADecryptionPass method getInsns.
private List<CodeUnit> getInsns(CodeUnit u, Set<CodeUnit> vis) {
List<CodeUnit> list = new ArrayList<>();
if (vis.contains(u)) {
return list;
}
int op = u.getOpcode();
switch(op) {
case INVOKE:
case ARRAY_LOAD:
case ARRAY_STORE:
case ALLOC_OBJ:
case INIT_OBJ:
case COMPARE:
return list;
}
if (Opcode.opclass(op) == CLASS_JUMP) {
return list;
}
list.add(u);
vis.add(u);
for (Expr e : u.getChildren()) {
list.addAll(getInsns(e, vis));
}
if (!u.isFlagSet(Stmt.FLAG_STMT)) {
Expr e = (Expr) u;
CodeUnit par = e.getParent();
list.addAll(getInsns(par, vis));
}
return list;
}
use of org.mapleir.ir.code.CodeUnit in project maple-ir by LLVM-but-worse.
the class FieldRSADecryptionPass method transform.
private void transform(AnalysisContext cxt) {
for (ClassNode cn : cxt.getApplication().iterate()) {
for (MethodNode m : cn.getMethods()) {
ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
for (BasicBlock b : cfg.vertices()) {
for (Stmt stmt : b) {
// String fsKey = "";
if (stmt.getOpcode() == Opcode.FIELD_STORE) {
FieldStoreStmt fs = (FieldStoreStmt) stmt;
// [enc, dec]
Number[] p = pairs.get(key(fs));
if (p != null) {
Expr e = fs.getValueExpression();
e.unlink();
ArithmeticExpr ae = new ArithmeticExpr(new ConstantExpr(p[1], ConstantExpr.computeType(p[1])), e, Operator.MUL);
fs.setValueExpression(ae);
// fsKey = key(fs);
}
}
for (Expr e : stmt.enumerateOnlyChildren()) {
if (e.getOpcode() == FIELD_LOAD) {
CodeUnit par = e.getParent();
FieldLoadExpr fl = (FieldLoadExpr) e;
// [enc, dec]
Number[] p = pairs.get(key(fl));
if (p == null) {
continue;
}
if (par.getOpcode() == ARITHMETIC) {
ArithmeticExpr ae = (ArithmeticExpr) par;
if (ae.getRight().getOpcode() == CONST_LOAD) {
ConstantExpr ce = (ConstantExpr) ae.getRight();
Number cst = (Number) ce.getConstant();
Number res = __mul(cst, p[0], p[0].getClass().equals(Long.class));
// if(!__eq(res, 1, p[0].getClass().equals(Long.class))) {
// System.out.println(cst + " -> " + res);
// System.out.println(" expr: " + fl.getRootParent());
// }
par.writeAt(new ConstantExpr(res, ConstantExpr.computeType(res)), par.indexOf(ce));
continue;
}
}
ArithmeticExpr ae = new ArithmeticExpr(new ConstantExpr(p[0], ConstantExpr.computeType(p[0])), fl.copy(), Operator.MUL);
par.writeAt(ae, par.indexOf(fl));
}
}
}
}
}
}
// for(ClassNode cn : cxt.getClassTree().getClasses().values()) {
// for(MethodNode m : cn.getMethods()) {
// ControlFlowGraph cfg = cxt.getCFGS().getIR(m);
//
// for(BasicBlock b : cfg.vertices()) {
// for(Stmt stmt : b) {
// for(Expr e : stmt.enumerateOnlyChildren()) {
// if(e.getOpcode() == Opcode.ARITHMETIC) {
// ArithmeticExpr ae = (ArithmeticExpr) e;
// if(ae.getRight().getOpcode() == Opcode.CONST_LOAD) {
// ConstantExpr c = (ConstantExpr) ae.getRight();
// Object o = c.getConstant();
//
// if(o instanceof Long || o instanceof Integer) {
// Number n = (Number) o;
// if(__eq(n, 1, ae.getType().equals(DescType.LONG_TYPE))) {
// Expr l = ae.getLeft();
// l.unlink();
//
// CodeUnit aePar = ae.getParent();
// aePar.writeAt(l, aePar.indexOf(ae));
// } else if(__eq(n, 0, ae.getType().equals(DescType.LONG_TYPE))) {
// c.unlink();
//
// CodeUnit aePar = ae.getParent();
// aePar.writeAt(c, aePar.indexOf(ae));
// }
// }
// }
// }
// }
// }
// }
// }
// }
}
use of org.mapleir.ir.code.CodeUnit in project maple-ir by LLVM-but-worse.
the class ConstantExpressionEvaluatorPass method processMethod.
public void processMethod(MethodNode m, IPConstAnalysisVisitor vis, ControlFlowGraph cfg) {
for (BasicBlock b : new HashSet<>(cfg.vertices())) {
for (int i = 0; i < b.size(); i++) {
Stmt stmt = b.get(i);
// simplify conditional branches.
if (stmt.getOpcode() == COND_JUMP) {
// todo: satisfiability analysis
ConditionalJumpStmt cond = (ConditionalJumpStmt) stmt;
Boolean result = evaluateConditional(vis, cfg, cond);
if (result != null) {
eliminateBranch(cfg, cond.getBlock(), cond, i, result);
branchesEvaluated++;
}
}
// evaluate arithmetic.
for (CodeUnit cu : stmt.enumerateExecutionOrder()) {
if (cu instanceof Expr) {
Expr e = (Expr) cu;
CodeUnit par = e.getParent();
if (par != null) {
Expr val = simplifyArithmetic(cfg.getLocals(), e);
if (val != null) {
exprsEvaluated++;
cfg.writeAt(par, e, val);
}
}
}
}
}
}
}
Aggregations