Search in sources :

Example 46 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class ConstantParameterPass method demoteDeadParamters.

private void demoteDeadParamters(IPAnalysis constAnalysis, ControlFlowGraph cfg, MethodNode n, boolean[] dead) {
    LocalsPool pool = cfg.getLocals();
    BasicBlock entry = cfg.getEntries().iterator().next();
    for (int i = 0; i < dead.length; i++) {
        if (dead[i]) {
            int localIndex = constAnalysis.getLocalIndex(n, i);
            VersionedLocal local = pool.get(localIndex, 0, false);
            AbstractCopyStmt copy = pool.defs.get(local);
            if (copy.getBlock() != entry) {
                System.err.printf("entry:%n%s%n", ControlFlowGraph.printBlock(entry));
                System.err.printf("block:%n%s%n", ControlFlowGraph.printBlock(copy.getBlock()));
                throw new IllegalStateException(String.format("See debug trace (entry vs block) in %s", n));
            }
            copy.delete();
            if (pool.uses.get(local).size() != 0) {
                throw new IllegalStateException(String.format("m: %s, l:%s, uses:%s", n, local, pool.uses.get(local)));
            }
            pool.defs.remove(local);
            pool.uses.remove(local);
        }
    }
}
Also used : VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) LocalsPool(org.mapleir.ir.locals.LocalsPool) BasicBlock(org.mapleir.ir.cfg.BasicBlock) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)

Example 47 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class DemoteRangesPass method process.

private void process(ApplicationClassSource app, ControlFlowGraph cfg, ExceptionAnalysis analysis) {
    TarjanSCC<BasicBlock> sccComputor = new TarjanSCC<>(cfg);
    for (BasicBlock b : cfg.vertices()) {
        if (sccComputor.low(b) == -1) {
            sccComputor.search(b);
        }
    }
    Map<BasicBlock, List<BasicBlock>> sccs = new HashMap<>();
    for (List<BasicBlock> l : sccComputor.getComponents()) {
        for (BasicBlock e : l) {
            if (sccs.containsKey(e)) {
                throw new IllegalStateException();
            } else {
                sccs.put(e, l);
            }
        }
    }
    for (ExceptionRange<BasicBlock> er : cfg.getRanges()) {
        /* if the handler catches */
        for (BasicBlock b : er.get()) {
            Set<Type> canThrow = new HashSet<>();
            List<BasicBlock> comp = new ArrayList<>();
            if (sccs.containsKey(b)) {
                comp.addAll(sccs.get(b));
            } else {
                comp.add(b);
            }
            for (BasicBlock e : comp) {
                for (Stmt stmt : e) {
                    canThrow.addAll(analysis.getPossibleUserThrowables(stmt));
                }
            }
            if (!catchesAny(app, er.getTypes(), canThrow)) {
                if (comp.size() > 1) {
                    System.out.println("promote: " + GraphUtils.toNodeArray(comp));
                    for (BasicBlock e : comp) {
                        System.out.println(ControlFlowGraph.printBlock(e));
                    }
                    System.out.println(" canThrow: " + canThrow);
                    System.out.println(" catching: " + er.getTypes());
                    System.out.println();
                    System.out.println();
                    System.out.println();
                    return;
                }
            } else {
                break;
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) BasicBlock(org.mapleir.ir.cfg.BasicBlock) ArrayList(java.util.ArrayList) Stmt(org.mapleir.ir.code.Stmt) Type(org.objectweb.asm.Type) TarjanSCC(org.mapleir.stdlib.collections.graph.algorithms.TarjanSCC) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 48 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock 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.methods) {
            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.overwrite(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.overwrite(ae, par.indexOf(fl));
                        }
                    }
                }
            }
        }
    }
// for(ClassNode cn : cxt.getClassTree().getClasses().values()) {
// for(MethodNode m : cn.methods) {
// 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(Type.LONG_TYPE))) {
// Expr l = ae.getLeft();
// l.unlink();
// 
// CodeUnit aePar = ae.getParent();
// aePar.overwrite(l, aePar.indexOf(ae));
// } else if(__eq(n, 0, ae.getType().equals(Type.LONG_TYPE))) {
// c.unlink();
// 
// CodeUnit aePar = ae.getParent();
// aePar.overwrite(c, aePar.indexOf(ae));
// }
// }
// }
// }
// }
// }
// }
// }
// }
}
Also used : FieldStoreStmt(org.mapleir.ir.code.stmt.FieldStoreStmt) ClassNode(org.objectweb.asm.tree.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.objectweb.asm.tree.MethodNode) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) Expr(org.mapleir.ir.code.Expr) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph)

Example 49 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class FieldRSADecryptionPass method accept.

@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
    this.cxt = cxt;
    for (MethodNode m : cxt.getIRCache().getActiveMethods()) {
        ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
        for (BasicBlock b : cfg.vertices()) {
            for (Stmt stmt : b) {
                for (Expr c : stmt.enumerateOnlyChildren()) {
                    if (c.getOpcode() == ARITHMETIC) {
                        ArithmeticExpr arith = (ArithmeticExpr) c;
                        if (arith.getOperator() == Operator.MUL) {
                            Expr l = arith.getLeft();
                            Expr r = arith.getRight();
                            if (r.getOpcode() == CONST_LOAD && l.getOpcode() == FIELD_LOAD) {
                                FieldLoadExpr fle = (FieldLoadExpr) l;
                                ConstantExpr constt = (ConstantExpr) r;
                                Number n = (Number) constt.getConstant();
                                boolean isLong = (n instanceof Long);
                                if (__eq(n, 1, isLong) || __eq(n, 0, isLong)) {
                                    continue;
                                }
                                if (n instanceof Integer || n instanceof Long) {
                                    cdecs.getNonNull(key(fle)).add(n);
                                }
                            }
                        }
                    }
                }
                if (stmt.getOpcode() == FIELD_STORE) {
                    FieldStoreStmt fss = (FieldStoreStmt) stmt;
                    Expr val = fss.getValueExpression();
                    if (bcheck1(val)) {
                        if (val.getOpcode() == CONST_LOAD) {
                            ConstantExpr c = (ConstantExpr) val;
                            if (c.getConstant() instanceof Integer || c.getConstant() instanceof Long) {
                                Number n = (Number) c.getConstant();
                                if (large(n, c.getConstant() instanceof Long)) {
                                    cencs.getNonNull(key(fss)).add(n);
                                }
                            }
                        }
                        continue;
                    }
                    ArithmeticExpr ar = (ArithmeticExpr) val;
                    if (ar.getRight().getOpcode() == CONST_LOAD) {
                        ConstantExpr c = (ConstantExpr) ar.getRight();
                        Number n = (Number) c.getConstant();
                        boolean isLong = c.getConstant() instanceof Long;
                        if (__eq(n, 1, isLong) || __eq(n, 0, isLong)) {
                            continue;
                        }
                        if (ar.getOperator() == Operator.ADD) {
                            if (!large(n, isLong)) {
                                continue;
                            }
                        }
                        cencs.getNonNull(key(fss)).add(n);
                    }
                }
            }
            for (Stmt stmt : b) {
                if (stmt.getOpcode() == FIELD_STORE) {
                    if (key((FieldStoreStmt) stmt).equals("co.k I")) {
                    // System.out.println("HERE1: " + stmt);
                    // 
                    // System.out.println(cfg);
                    }
                    handleFss((FieldStoreStmt) stmt);
                }
                for (Expr e : stmt.enumerateOnlyChildren()) {
                    if (e.getOpcode() == FIELD_LOAD) {
                        if (key((FieldLoadExpr) e).equals("co.k I")) {
                        // System.out.println("HERE2: " + stmt);
                        }
                        handleFle(stmt, (FieldLoadExpr) e);
                    }
                }
            }
        }
    }
    Set<String> keys = new HashSet<>();
    keys.addAll(cencs.keySet());
    keys.addAll(cdecs.keySet());
    for (String k : keys) {
        boolean _longint = k.endsWith("J");
        Set<Number> encs = cencs.getNonNull(k);
        Set<Number> decs = cdecs.getNonNull(k);
        try {
            Number[] pair = get_pair(encs, decs, constants.getNonNull(k), _longint);
            if (pair.length != 2) {
                Set<Number> extended = new HashSet<>(constants.getNonNull(k));
                extended.addAll(dangerConstants.getNonNull(k));
                pair = get_pair(encs, decs, extended, _longint);
            }
            if (pair.length != 2) {
            // System.out.println("No pair for: " + k);
            // System.out.println("Constants: " + constants.getNonNull(k));
            // System.out.println("Dconsts  : " + dangerConstants.getNonNull(k));
            // System.out.println("Encs     : " + encs);
            // System.out.println("Decs     : " + decs);
            } else {
                pairs.put(k, pair);
            // System.out.println("for: " + k + ": " + Arrays.toString(pair));
            }
        } catch (IllegalStateException e) {
            System.err.println();
            System.err.println("Constants: " + constants.getNonNull(k));
            System.out.println("Dconsts  : " + dangerConstants.getNonNull(k));
            System.err.println("Encs     : " + encs);
            System.err.println("Decs     : " + decs);
            System.err.println("key: " + k);
            throw e;
        }
    }
    System.out.printf("  identified %n field encoder/decoder pairs.%n", pairs.size());
    transform(cxt);
    return pairs.size();
}
Also used : FieldStoreStmt(org.mapleir.ir.code.stmt.FieldStoreStmt) 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) BigInteger(java.math.BigInteger) MethodNode(org.objectweb.asm.tree.MethodNode) ConstantExpr(org.mapleir.ir.code.expr.ConstantExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) Expr(org.mapleir.ir.code.Expr) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) ArithmeticExpr(org.mapleir.ir.code.expr.ArithmeticExpr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) HashSet(java.util.HashSet)

Example 50 with BasicBlock

use of org.mapleir.ir.cfg.BasicBlock in project maple-ir by LLVM-but-worse.

the class ConstantExpressionEvaluatorPass method eliminateBranch.

private void eliminateBranch(ControlFlowGraph cfg, BasicBlock b, ConditionalJumpStmt cond, int insnIndex, boolean val) {
    if (val) {
        // remove immediate edge (it will never be taken)
        for (FlowEdge<BasicBlock> fe : new HashSet<>(cfg.getEdges(b))) {
            if (fe.getType() == FlowEdges.IMMEDIATE) {
                cfg.exciseEdge(fe);
            }
        }
        // create new jump and update cfg
        UnconditionalJumpStmt newJump = new UnconditionalJumpStmt(cond.getTrueSuccessor());
        b.set(insnIndex, newJump);
        UnconditionalJumpEdge<BasicBlock> uje = new UnconditionalJumpEdge<>(b, cond.getTrueSuccessor());
        cfg.addEdge(b, uje);
    } else {
        // always false, keep immediate (fallthrough) and remove the conditional branch.
        // remove statement amd uses in d/u map
        cfg.exciseStmt(cond);
        // remove conditional edge
        for (FlowEdge<BasicBlock> fe : new HashSet<>(cfg.getEdges(b))) {
            if (fe.getType() == FlowEdges.COND) {
                if (fe.dst() != cond.getTrueSuccessor()) {
                    throw new IllegalStateException(fe + ", " + cond);
                }
                cfg.exciseEdge(fe);
            }
        }
    }
}
Also used : BasicBlock(org.mapleir.ir.cfg.BasicBlock) UnconditionalJumpEdge(org.mapleir.flowgraph.edges.UnconditionalJumpEdge) HashSet(java.util.HashSet) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt)

Aggregations

BasicBlock (org.mapleir.ir.cfg.BasicBlock)70 Stmt (org.mapleir.ir.code.Stmt)37 Expr (org.mapleir.ir.code.Expr)34 Local (org.mapleir.ir.locals.Local)30 VarExpr (org.mapleir.ir.code.expr.VarExpr)29 CopyPhiStmt (org.mapleir.ir.code.stmt.copy.CopyPhiStmt)25 AbstractCopyStmt (org.mapleir.ir.code.stmt.copy.AbstractCopyStmt)24 CopyVarStmt (org.mapleir.ir.code.stmt.copy.CopyVarStmt)22 PhiExpr (org.mapleir.ir.code.expr.PhiExpr)19 VersionedLocal (org.mapleir.ir.locals.impl.VersionedLocal)19 HashSet (java.util.HashSet)12 ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)11 UnconditionalJumpStmt (org.mapleir.ir.code.stmt.UnconditionalJumpStmt)10 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)9 BasicLocal (org.mapleir.ir.locals.impl.BasicLocal)9 NullPermeableHashMap (org.mapleir.stdlib.collections.map.NullPermeableHashMap)9 ConditionalJumpStmt (org.mapleir.ir.code.stmt.ConditionalJumpStmt)8 Type (org.objectweb.asm.Type)7 ArrayList (java.util.ArrayList)6 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)6