Search in sources :

Example 6 with CodeUnit

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);
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) LocalsPool(org.mapleir.ir.locals.LocalsPool) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) VarExpr(org.mapleir.ir.code.expr.VarExpr) HashSet(java.util.HashSet) CodeUnit(org.mapleir.ir.code.CodeUnit)

Example 7 with CodeUnit

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());
    }
}
Also used : 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) InitialisedObjectExpr(org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) CodeUnit(org.mapleir.ir.code.CodeUnit)

Example 8 with CodeUnit

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;
}
Also used : ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) Expr(org.mapleir.ir.code.Expr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) CodeUnit(org.mapleir.ir.code.CodeUnit)

Example 9 with CodeUnit

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));
// }
// }
// }
// }
// }
// }
// }
// }
// }
}
Also used : FieldStoreStmt(org.mapleir.ir.code.stmt.FieldStoreStmt) ClassNode(org.mapleir.asm.ClassNode) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) BasicBlock(org.mapleir.ir.cfg.BasicBlock) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) FieldStoreStmt(org.mapleir.ir.code.stmt.FieldStoreStmt) Stmt(org.mapleir.ir.code.Stmt) CodeUnit(org.mapleir.ir.code.CodeUnit) MethodNode(org.mapleir.asm.MethodNode) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) Expr(org.mapleir.ir.code.Expr) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph)

Example 10 with CodeUnit

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);
                        }
                    }
                }
            }
        }
    }
}
Also used : ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) VarExpr(org.mapleir.ir.code.expr.VarExpr) Expr(org.mapleir.ir.code.Expr) BasicBlock(org.mapleir.ir.cfg.BasicBlock) HashSet(java.util.HashSet) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt) Stmt(org.mapleir.ir.code.Stmt) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) CodeUnit(org.mapleir.ir.code.CodeUnit)

Aggregations

CodeUnit (org.mapleir.ir.code.CodeUnit)10 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)9 Expr (org.mapleir.ir.code.Expr)6 VarExpr (org.mapleir.ir.code.expr.VarExpr)6 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)5 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)4 Stmt (org.mapleir.ir.code.Stmt)3 ArithmeticExpr (org.mapleir.ir.code.expr.ArithmeticExpr)3 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)3 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)3 BigInteger (java.math.BigInteger)2 HashSet (java.util.HashSet)2 BasicBlock (org.mapleir.ir.cfg.BasicBlock)2 LatestValue (org.mapleir.ir.cfg.builder.ssaopt.LatestValue)2 FieldLoadExpr (org.mapleir.ir.code.expr.FieldLoadExpr)2 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)2 Local (org.mapleir.ir.locals.Local)2 Entry (java.util.Map.Entry)1 ClassNode (org.mapleir.asm.ClassNode)1 MethodNode (org.mapleir.asm.MethodNode)1