Search in sources :

Example 6 with ControlFlowGraph

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

the class FieldRenamerPass method accept.

@Override
public PassResult accept(PassContext pcxt) {
    AnalysisContext cxt = pcxt.getAnalysis();
    Map<FieldNode, String> remapped = new HashMap<>();
    // int totalFields = 0;
    // int i = RenamingUtil.computeMinimum(totalFields);
    ApplicationClassSource source = cxt.getApplication();
    int i = RenamingUtil.numeric("aaaaa");
    for (ClassNode cn : source.iterate()) {
        // totalFields += cn.fields.size();
        for (FieldNode fn : cn.getFields()) {
            remapped.put(fn, RenamingUtil.createName(i++));
        }
    }
    InvocationResolver resolver = cxt.getInvocationResolver();
    for (ClassNode cn : source.iterate()) {
        for (MethodNode m : cn.getMethods()) {
            ControlFlowGraph cfg = cxt.getIRCache().getFor(m);
            for (BasicBlock b : cfg.vertices()) {
                for (Stmt stmt : b) {
                    if (stmt.getOpcode() == Opcode.FIELD_STORE) {
                        FieldStoreStmt fs = (FieldStoreStmt) stmt;
                        FieldNode f = resolver.findField(fs.getOwner(), fs.getName(), fs.getDesc(), fs.getInstanceExpression() == null);
                        if (f != null) {
                            if (remapped.containsKey(f)) {
                                fs.setName(remapped.get(f));
                            } else if (mustMark(source, f.getOwner())) {
                                System.err.println("  no remap for " + f + ", owner: " + f.getOwner());
                            }
                        } else {
                            if (mustMark(source, fs.getOwner())) {
                                System.err.println("  can't resolve field(set): " + fs.getOwner() + "." + fs.getName() + " " + fs.getDesc() + ", " + (fs.getInstanceExpression() == null));
                            }
                        }
                    }
                    for (Expr e : stmt.enumerateOnlyChildren()) {
                        if (e.getOpcode() == Opcode.FIELD_LOAD) {
                            FieldLoadExpr fl = (FieldLoadExpr) e;
                            FieldNode f = resolver.findField(fl.getOwner(), fl.getName(), fl.getDesc(), fl.getInstanceExpression() == null);
                            if (f != null) {
                                if (remapped.containsKey(f)) {
                                    fl.setName(remapped.get(f));
                                } else if (mustMark(source, f.getOwner())) {
                                    System.err.println("  no remap for " + f + ", owner: " + f.getOwner());
                                }
                            } else {
                                if (mustMark(source, fl.getOwner())) {
                                    System.err.println("  can't resolve field(get): " + fl.getOwner() + "." + fl.getName() + " " + fl.getDesc() + ", " + (fl.getInstanceExpression() == null));
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    for (Entry<FieldNode, String> e : remapped.entrySet()) {
        e.getKey().node.name = e.getValue();
    }
    System.out.printf("  Renamed %d fields.%n", remapped.size());
    return PassResult.with(pcxt, this).finished().make();
}
Also used : FieldStoreStmt(org.mapleir.ir.code.stmt.FieldStoreStmt) ClassNode(org.mapleir.asm.ClassNode) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) FieldNode(org.mapleir.asm.FieldNode) HashMap(java.util.HashMap) BasicBlock(org.mapleir.ir.cfg.BasicBlock) AnalysisContext(org.mapleir.context.AnalysisContext) FieldStoreStmt(org.mapleir.ir.code.stmt.FieldStoreStmt) Stmt(org.mapleir.ir.code.Stmt) ApplicationClassSource(org.mapleir.app.service.ApplicationClassSource) MethodNode(org.mapleir.asm.MethodNode) Expr(org.mapleir.ir.code.Expr) FieldLoadExpr(org.mapleir.ir.code.expr.FieldLoadExpr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) InvocationResolver(org.mapleir.app.service.InvocationResolver)

Example 7 with ControlFlowGraph

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

the class CFGExporterUtils method makeDotGraph.

public static DotGraph makeDotGraph(ControlFlowGraph cfg, IPropertyDictionary properties) {
    boolean showStmts = PropertyHelper.isSet(properties, OPT_STMTS);
    boolean labelEdges = PropertyHelper.isSet(properties, OPT_EDGES);
    boolean simplifyEdges = PropertyHelper.isSet(properties, OPT_SIMPLE_EDGES);
    boolean hideHandlerEdges = PropertyHelper.isSet(properties, OPT_HIDE_HANDLER_EDGES);
    DotGraph sourceGraph = Factory.graph().getGraphAttr().with(Rank.SOURCE);
    DotGraph sinkGraph = Factory.graph().getGraphAttr().with(Rank.SINK);
    DotGraph g = GraphUtils.makeDotSkeleton(cfg, (block, node) -> {
        StringBuilder sb = new StringBuilder();
        sb.append("<table>");
        {
            sb.append("<tr><td><font point-size=\"12\">").append(block.getDisplayName()).append("</font></td></tr>");
        }
        {
            sb.append("<tr><td>");
            if (showStmts) {
                StringBuilder stmtsStr = new StringBuilder();
                outputBlock(block, stmtsStr);
                sb.append(stmtsStr.toString());
            }
            sb.append("</td></tr>");
        }
        sb.append("</table>");
        Attrs colour;
        DotGraph rankGraph;
        if (cfg.getEntries().contains(block)) {
            colour = Colour.RED.fill();
            rankGraph = sourceGraph;
        } else if (cfg.getEdges(block).isEmpty()) {
            colour = Colour.GREEN.fill();
            rankGraph = sinkGraph;
        } else {
            colour = Attrs.attrs();
            rankGraph = null;
        }
        if (rankGraph != null) {
            Context.use(rankGraph, (ctx) -> {
                return rankGraph.addSource(Factory.node(node.getName()));
            });
        }
        node.with(Shape.BOX, Style.FILLED, colour, ComplexLabel.html(sb.toString()).justify(Justification.LEFT));
        return true;
    }, (e, dotE) -> {
        if (hideHandlerEdges && e instanceof TryCatchEdge) {
            // dotE.with(Style.INVIS);
            return false;
        }
        if (labelEdges) {
            dotE.with(ComplexLabel.of(simplifyEdges ? e.getClass().getSimpleName().replace("Edge", "") : e.toGraphString()));
        }
        return true;
    }).setDirected(true);
    g.addSource(sourceGraph);
    g.addSource(sinkGraph);
    return g;
}
Also used : Colour(org.mapleir.dot4j.attr.builtin.Colour) DotGraph(org.mapleir.dot4j.model.DotGraph) Shape(org.mapleir.dot4j.attr.builtin.Shape) Justification(org.mapleir.dot4j.attr.builtin.ComplexLabel.Justification) Iterator(java.util.Iterator) ComplexLabel(org.mapleir.dot4j.attr.builtin.ComplexLabel) Rank(org.mapleir.dot4j.attr.builtin.Rank) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) Context(org.mapleir.dot4j.model.Context) Stmt(org.mapleir.ir.code.Stmt) Attrs(org.mapleir.dot4j.attr.Attrs) TabbedStringWriter(org.mapleir.stdlib.util.TabbedStringWriter) IPropertyDictionary(org.mapleir.propertyframework.api.IPropertyDictionary) GraphUtils(org.mapleir.stdlib.collections.graph.GraphUtils) Style(org.mapleir.dot4j.attr.builtin.Style) Factory(org.mapleir.dot4j.model.Factory) BasicBlock(org.mapleir.ir.cfg.BasicBlock) PropertyHelper(org.mapleir.propertyframework.util.PropertyHelper) TryCatchEdge(org.mapleir.flowgraph.edges.TryCatchEdge) DotGraph(org.mapleir.dot4j.model.DotGraph) Attrs(org.mapleir.dot4j.attr.Attrs) TryCatchEdge(org.mapleir.flowgraph.edges.TryCatchEdge)

Example 8 with ControlFlowGraph

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

the class Boot method main.

public static void main(String[] args) throws Exception {
    sections = new LinkedList<>();
    logging = true;
    // Load input jar
    // File f = locateRevFile(135);
    File f = new File(args[0]);
    section("Preparing to run on " + f.getAbsolutePath());
    SingleJarDownloader<ClassNode> dl = new SingleJarDownloader<>(new JarInfo(f));
    dl.download();
    String appName = f.getName().substring(0, f.getName().length() - 4);
    ApplicationClassSource app = new ApplicationClassSource(appName, dl.getJarContents().getClassContents());
    // 
    // ApplicationClassSource app = new ApplicationClassSource("test", ClassHelper.parseClasses(CGExample.class));
    // app.addLibraries(new InstalledRuntimeClassSource(app));
    File rtjar = new File(System.getProperty("java.home"), "lib/rt.jar");
    // File androidjar = new File("res/android.jar");
    app.addLibraries(rt(app, rtjar));
    section("Initialising context.");
    IRCache irFactory = new IRCache(ControlFlowGraphBuilder::build);
    AnalysisContext cxt = new BasicAnalysisContext.BasicContextBuilder().setApplication(app).setInvocationResolver(new DefaultInvocationResolver(app)).setCache(irFactory).setApplicationContext(new SimpleApplicationContext(app)).setDataFlowAnalysis(new LiveDataFlowAnalysisImpl(irFactory)).build();
    section("Expanding callgraph and generating cfgs.");
    for (ClassNode cn : cxt.getApplication().iterate()) {
        // continue;
        for (MethodNode m : cn.getMethods()) {
            // if (!m.getName().equals("setRccState"))
            // continue;
            cxt.getIRCache().getFor(m);
        }
    }
    section0("...generated " + cxt.getIRCache().size() + " cfgs in %fs.%n", "Preparing to transform.");
    // do passes
    PassGroup masterGroup = new PassGroup("MasterController");
    for (IPass p : getTransformationPasses()) {
        masterGroup.add(p);
    }
    run(cxt, masterGroup);
    section0("...done transforming in %fs.%n", "Preparing to transform.");
    for (Entry<MethodNode, ControlFlowGraph> e : cxt.getIRCache().entrySet()) {
        MethodNode mn = e.getKey();
        ControlFlowGraph cfg = e.getValue();
        try {
            cfg.verify();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    section("Retranslating SSA IR to standard flavour.");
    for (Entry<MethodNode, ControlFlowGraph> e : cxt.getIRCache().entrySet()) {
        MethodNode mn = e.getKey();
        // if (!mn.getName().equals("openFiles"))
        // continue;
        ControlFlowGraph cfg = e.getValue();
        // CFGUtils.easyDumpCFG(cfg, "pre-destruct");
        try {
            cfg.verify();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        BoissinotDestructor.leaveSSA(cfg);
        // CFGUtils.easyDumpCFG(cfg, "pre-reaalloc");
        LocalsReallocator.realloc(cfg);
        // System.out.println(cfg);
        try {
            cfg.verify();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        // System.out.println("Rewriting " + mn.getName());
        (new ControlFlowGraphDumper(cfg, mn)).dump();
    // System.out.println(InsnListUtils.insnListToString(mn.instructions));
    }
    section("Rewriting jar.");
    dumpJar(app, dl, masterGroup, "out/rewritten.jar");
    section("Finished.");
}
Also used : ClassNode(org.mapleir.asm.ClassNode) LiveDataFlowAnalysisImpl(org.mapleir.deob.dataflow.LiveDataFlowAnalysisImpl) IRCache(org.mapleir.context.IRCache) AnalysisContext(org.mapleir.context.AnalysisContext) BasicAnalysisContext(org.mapleir.context.BasicAnalysisContext) SimpleApplicationContext(org.mapleir.app.client.SimpleApplicationContext) IPass(org.mapleir.deob.IPass) ControlFlowGraphDumper(org.mapleir.ir.codegen.ControlFlowGraphDumper) PassGroup(org.mapleir.deob.PassGroup) ApplicationClassSource(org.mapleir.app.service.ApplicationClassSource) MethodNode(org.mapleir.asm.MethodNode) JarInfo(org.topdank.byteengineer.commons.data.JarInfo) ControlFlowGraphBuilder(org.mapleir.ir.cfg.builder.ControlFlowGraphBuilder) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) SingleJarDownloader(org.topdank.byteio.in.SingleJarDownloader)

Example 9 with ControlFlowGraph

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

the class ConstantExpressionReorderPass method accept.

@Override
public PassResult accept(PassContext pcxt) {
    AnalysisContext cxt = pcxt.getAnalysis();
    int delta = 0;
    for (MethodNode m : cxt.getIRCache().getActiveMethods()) {
        ControlFlowGraph ir = cxt.getIRCache().getFor(m);
        delta += transform(ir);
    }
    System.out.println("  swapped " + delta + " constant expression orders.");
    return PassResult.with(pcxt, this).finished(delta).make();
}
Also used : MethodNode(org.mapleir.asm.MethodNode) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) AnalysisContext(org.mapleir.context.AnalysisContext)

Example 10 with ControlFlowGraph

use of org.mapleir.ir.cfg.ControlFlowGraph 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 : Local(org.mapleir.ir.locals.Local) Type(org.objectweb.asm.Type) Expr(org.mapleir.ir.code.Expr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) Iterator(java.util.Iterator) TaintableSet(org.mapleir.stdlib.collections.taint.TaintableSet) Pair(org.mapleir.stdlib.util.Pair)

Aggregations

ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)30 MethodNode (org.mapleir.asm.MethodNode)17 BasicBlock (org.mapleir.ir.cfg.BasicBlock)14 Expr (org.mapleir.ir.code.Expr)14 ClassNode (org.mapleir.asm.ClassNode)13 Stmt (org.mapleir.ir.code.Stmt)13 AnalysisContext (org.mapleir.context.AnalysisContext)11 ApplicationClassSource (org.mapleir.app.service.ApplicationClassSource)9 InvocationResolver (org.mapleir.app.service.InvocationResolver)7 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)7 FieldStoreStmt (org.mapleir.ir.code.stmt.FieldStoreStmt)7 MethodNode (org.objectweb.asm.tree.MethodNode)6 IRCache (org.mapleir.context.IRCache)5 ControlFlowGraphBuilder (org.mapleir.ir.cfg.builder.ControlFlowGraphBuilder)5 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)5 FieldLoadExpr (org.mapleir.ir.code.expr.FieldLoadExpr)5 Type (org.objectweb.asm.Type)5 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)4 SimpleApplicationContext (org.mapleir.app.client.SimpleApplicationContext)4