Search in sources :

Example 1 with ControlFlowGraph

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

the class MethodNodePrinter method emitCode.

public void emitCode(MethodNode mn) {
    ControlFlowGraph cfg = this.getCfg(mn);
    this.emitHandlers(cfg);
    this.sw.newline().print(".code {").tab();
    this.emitCfg(cfg);
    this.sw.untab().newline().print("}");
}
Also used : ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph)

Example 2 with ControlFlowGraph

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

the class DominanceLivenessAnalyser method reduce.

private ControlFlowGraph reduce(ControlFlowGraph cfg, Set<FastGraphEdge<BasicBlock>> back) {
    ControlFlowGraph reducedCfg = cfg.copy();
    for (FastGraphEdge<BasicBlock> e : back) {
        reducedCfg.removeEdge(e.src(), (FlowEdge<BasicBlock>) e);
        backTargets.add(e.dst());
        backEdges.getNonNull(e.src()).add(e.dst());
    }
    return reducedCfg;
}
Also used : ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) BasicBlock(org.mapleir.ir.cfg.BasicBlock)

Example 3 with ControlFlowGraph

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

the class SSAGenPass method splitBlock.

private BasicBlock splitBlock(BasicBlock b, int to) {
    /* eg. split the block as follows:
		 * 
		 *  NAME:
		 *    stmt1
		 *    stmt2
		 *    stmt3
		 *    stmt4
		 *    stmt5
		 *    jump L1, L2
		 *   [jump edge to L1]
		 *   [jump edge to L2]
		 *   [exception edges]
		 * 
		 * split at 3, create a new block (incoming 
		 * immediate), transfer instruction from 0
		 * to index into new block, create immediate
		 * edge to old block, clone exception edges,
		 * redirect pred edges.
		 * 
		 * 1/9/16: we also need to modify the last
		 *         statement of the pred blocks to
		 *         point to NAME'.
		 * 
		 *  NAME':
		 *    stmt1
		 *    stmt2
		 *    stmt3
		 *   [immediate to NAME]
		 *  NAME:
		 *    stmt4
		 *    stmt5
		 *    jump L1, L2
		 *   [jump edge to L1]
		 *   [jump edge to L2]
		 *   [exception edges]
		 */
    // split block
    ControlFlowGraph cfg = builder.graph;
    BasicBlock newBlock = new BasicBlock(cfg, graphSize++, new LabelNode());
    b.transferUp(newBlock, to);
    cfg.addVertex(newBlock);
    // redo ranges
    for (ExceptionRange<BasicBlock> er : cfg.getRanges()) {
        if (er.containsVertex(b))
            er.addVertexBefore(b, newBlock);
    }
    // redirect b preds into newBlock and remove them.
    Set<FlowEdge<BasicBlock>> oldEdges = new HashSet<>(cfg.getReverseEdges(b));
    for (FlowEdge<BasicBlock> e : oldEdges) {
        BasicBlock p = e.src();
        FlowEdge<BasicBlock> c;
        if (e instanceof TryCatchEdge) {
            // b is ehandler
            TryCatchEdge<BasicBlock> tce = (TryCatchEdge<BasicBlock>) e;
            if (tce.dst() != tce.erange.getHandler()) {
                System.err.println(builder.method.owner + "#" + builder.method.name);
                System.err.println(cfg);
                System.err.println("Very odd split case. please investigate");
                System.err.println("Offending postsplit block: " + b);
                System.err.println("Offending newblock: " + newBlock);
                System.err.println("Offending edge: " + tce);
                System.err.println("Offending erange: " + tce.erange);
            }
            if (tce.erange.getHandler() != newBlock) {
                tce.erange.setHandler(newBlock);
                cfg.addEdge(tce.src(), tce.clone(tce.src(), null));
                cfg.removeEdge(tce.src(), tce);
            }
        } else {
            c = e.clone(p, newBlock);
            cfg.addEdge(p, c);
            cfg.removeEdge(p, e);
        }
        // Fix flow instruction targets
        if (!p.isEmpty()) {
            Stmt last = p.get(p.size() - 1);
            int op = last.getOpcode();
            if (e instanceof ConditionalJumpEdge) {
                if (op != Opcode.COND_JUMP)
                    throw new IllegalArgumentException("wrong flow instruction");
                ConditionalJumpStmt j = (ConditionalJumpStmt) last;
                // assertTarget(last, j.getTrueSuccessor(), b);
                if (j.getTrueSuccessor() == b)
                    j.setTrueSuccessor(newBlock);
            } else if (e instanceof UnconditionalJumpEdge) {
                if (op != Opcode.UNCOND_JUMP)
                    throw new IllegalArgumentException("wrong flow instruction");
                UnconditionalJumpStmt j = (UnconditionalJumpStmt) last;
                assertTarget(j, j.getTarget(), b);
                j.setTarget(newBlock);
            } else if (e instanceof SwitchEdge) {
                if (op != Opcode.SWITCH_JUMP)
                    throw new IllegalArgumentException("wrong flow instruction.");
                SwitchStmt s = (SwitchStmt) last;
                for (Entry<Integer, BasicBlock> en : s.getTargets().entrySet()) {
                    BasicBlock t = en.getValue();
                    if (t == b) {
                        en.setValue(newBlock);
                    }
                }
            }
        }
    }
    if (!checkCloneHandler(newBlock)) {
        System.err.println(cfg);
        System.err.println(newBlock.getDisplayName());
        System.err.println(b.getDisplayName());
        throw new IllegalStateException("the new block should always need a handler..?");
    }
    // clone exception edges
    for (FlowEdge<BasicBlock> e : cfg.getEdges(b)) {
        if (e.getType() == FlowEdges.TRYCATCH) {
            // second param is discarded (?)
            TryCatchEdge<BasicBlock> c = ((TryCatchEdge<BasicBlock>) e).clone(newBlock, null);
            cfg.addEdge(newBlock, c);
        }
    }
    // create immediate to newBlock
    cfg.addEdge(newBlock, new ImmediateEdge<>(newBlock, b));
    // update assigns
    Set<Local> assignedLocals = new HashSet<>();
    for (Stmt stmt : b) if (stmt.getOpcode() == Opcode.LOCAL_STORE)
        assignedLocals.add(((CopyVarStmt) stmt).getVariable().getLocal());
    for (Stmt stmt : newBlock) {
        if (stmt.getOpcode() == Opcode.LOCAL_STORE) {
            Local copyLocal = ((CopyVarStmt) stmt).getVariable().getLocal();
            Set<BasicBlock> set = builder.assigns.get(copyLocal);
            set.add(newBlock);
            if (!assignedLocals.contains(copyLocal))
                set.remove(b);
        }
    }
    return newBlock;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TryCatchEdge(org.mapleir.flowgraph.edges.TryCatchEdge) SwitchStmt(org.mapleir.ir.code.stmt.SwitchStmt) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) PopStmt(org.mapleir.ir.code.stmt.PopStmt) ThrowStmt(org.mapleir.ir.code.stmt.ThrowStmt) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt) Stmt(org.mapleir.ir.code.Stmt) CopyPhiStmt(org.mapleir.ir.code.stmt.copy.CopyPhiStmt) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) AbstractCopyStmt(org.mapleir.ir.code.stmt.copy.AbstractCopyStmt) UnconditionalJumpEdge(org.mapleir.flowgraph.edges.UnconditionalJumpEdge) FlowEdge(org.mapleir.flowgraph.edges.FlowEdge) SwitchStmt(org.mapleir.ir.code.stmt.SwitchStmt) SwitchEdge(org.mapleir.flowgraph.edges.SwitchEdge) CopyVarStmt(org.mapleir.ir.code.stmt.copy.CopyVarStmt) BasicBlock(org.mapleir.ir.cfg.BasicBlock) BasicLocal(org.mapleir.ir.locals.impl.BasicLocal) Local(org.mapleir.ir.locals.Local) VersionedLocal(org.mapleir.ir.locals.impl.VersionedLocal) Constraint(org.mapleir.ir.cfg.builder.ssaopt.Constraint) UnconditionalJumpStmt(org.mapleir.ir.code.stmt.UnconditionalJumpStmt) ConditionalJumpStmt(org.mapleir.ir.code.stmt.ConditionalJumpStmt) ConditionalJumpEdge(org.mapleir.flowgraph.edges.ConditionalJumpEdge) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph)

Example 4 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;
    File rtjar = new File("res/rt.jar");
    // Load input jar
    File f = locateRevFile(135);
    // File f = new File("res/allatori6.1san.jar");
    section("Preparing to run on " + f.getAbsolutePath());
    SingleJarDownloader<ClassNode> dl = new SingleJarDownloader<>(new JarInfo(f));
    dl.download();
    String name = f.getName().substring(0, f.getName().length() - 4);
    // ApplicationClassSource app = new ApplicationClassSource(name, dl.getJarContents().getClassContents());
    // 
    ApplicationClassSource app = new ApplicationClassSource("test", ClassHelper.parseClasses(CGExample.class));
    // app.addLibraries(new InstalledRuntimeClassSource(app));
    app.addLibraries(rt(app, rtjar), new InstalledRuntimeClassSource(app));
    section("Initialising context.");
    AnalysisContext cxt = new BasicAnalysisContext.BasicContextBuilder().setApplication(app).setInvocationResolver(new DefaultInvocationResolver(app)).setCache(new IRCache(ControlFlowGraphBuilder::build)).setApplicationContext(new SimpleApplicationContext(app)).build();
    section("Expanding callgraph and generating cfgs.");
    IRCallTracer tracer = new IRCallTracer(cxt);
    for (MethodNode m : cxt.getApplicationContext().getEntryPoints()) {
        // System.out.println(m);
        tracer.trace(m);
        if (m.instructions.size() > 500 && m.instructions.size() < 100) {
            System.out.println(m);
            System.out.println(cxt.getIRCache().get(m));
        }
    }
    for (ClassNode cn : app.iterate()) {
        TabbedStringWriter sw = new TabbedStringWriter();
        sw.setTabString("  ");
        IPropertyDictionary settings = PropertyHelper.createDictionary();
        // settings.put(new BooleanProperty(ASMPrinter.PROP_ACCESS_FLAG_SAFE, true));
        ClassPrinter cp = new ClassPrinter(sw, settings, new FieldNodePrinter(sw, settings), new MethodNodePrinter(sw, settings) {

            @Override
            protected ControlFlowGraph getCfg(MethodNode mn) {
                return cxt.getIRCache().getFor(mn);
            }
        });
        cp.print(cn);
        System.out.println(sw.toString());
    }
    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);
    // for(MethodNode m : cxt.getIRCache().getActiveMethods()) {
    // if(m.instructions.size() > 100 && m.instructions.size() < 500) {
    // System.out.println(cxt.getIRCache().get(m));
    // }
    // }
    section("Retranslating SSA IR to standard flavour.");
    for (Entry<MethodNode, ControlFlowGraph> e : cxt.getIRCache().entrySet()) {
        MethodNode mn = e.getKey();
        ControlFlowGraph cfg = e.getValue();
        BoissinotDestructor.leaveSSA(cfg);
        cfg.getLocals().realloc(cfg);
        (new ControlFlowGraphDumper(cfg, mn)).dump();
    }
    section("Rewriting jar.");
    // dumpJar(app, dl, masterGroup, "out/osb5.jar");
    section("Finished.");
}
Also used : IPropertyDictionary(org.mapleir.propertyframework.api.IPropertyDictionary) ClassPrinter(org.mapleir.ir.printer.ClassPrinter) AnalysisContext(org.mapleir.context.AnalysisContext) BasicAnalysisContext(org.mapleir.context.BasicAnalysisContext) IPass(org.mapleir.deob.IPass) InstalledRuntimeClassSource(org.mapleir.app.service.InstalledRuntimeClassSource) ApplicationClassSource(org.mapleir.app.service.ApplicationClassSource) MethodNode(org.objectweb.asm.tree.MethodNode) MethodNodePrinter(org.mapleir.ir.printer.MethodNodePrinter) SingleJarDownloader(org.topdank.byteio.in.SingleJarDownloader) TabbedStringWriter(org.mapleir.stdlib.util.TabbedStringWriter) ClassNode(org.objectweb.asm.tree.ClassNode) FieldNodePrinter(org.mapleir.ir.printer.FieldNodePrinter) IRCache(org.mapleir.context.IRCache) IRCallTracer(org.mapleir.deob.interproc.IRCallTracer) SimpleApplicationContext(org.mapleir.app.client.SimpleApplicationContext) ControlFlowGraphDumper(org.mapleir.ir.algorithms.ControlFlowGraphDumper) PassGroup(org.mapleir.deob.PassGroup) JarInfo(org.topdank.byteengineer.commons.data.JarInfo) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) BasicAnalysisContext(org.mapleir.context.BasicAnalysisContext)

Example 5 with ControlFlowGraph

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

the class ConcreteStaticInvocationPass method accept.

@Override
public int accept(AnalysisContext cxt, IPass prev, List<IPass> completed) {
    int fixed = 0;
    InvocationResolver resolver = cxt.getInvocationResolver();
    for (ClassNode cn : cxt.getApplication().iterate()) {
        for (MethodNode mn : cn.methods) {
            ControlFlowGraph cfg = cxt.getIRCache().getFor(mn);
            for (BasicBlock b : cfg.vertices()) {
                for (Stmt stmt : b) {
                    for (Expr e : stmt.enumerateOnlyChildren()) {
                        if (e.getOpcode() == Opcode.INVOKE) {
                            InvocationExpr invoke = (InvocationExpr) e;
                            if (invoke.isStatic()) {
                                MethodNode invoked = resolver.resolveStaticCall(invoke.getOwner(), invoke.getName(), invoke.getDesc());
                                if (invoked != null) {
                                    if (!invoked.owner.name.equals(invoke.getOwner())) {
                                        invoke.setOwner(invoked.owner.name);
                                        fixed++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    System.out.printf("  corrected %d dodgy static calls.%n", fixed);
    return fixed;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) MethodNode(org.objectweb.asm.tree.MethodNode) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Expr(org.mapleir.ir.code.Expr) ControlFlowGraph(org.mapleir.ir.cfg.ControlFlowGraph) InvocationResolver(org.mapleir.app.service.InvocationResolver) BasicBlock(org.mapleir.ir.cfg.BasicBlock) InvocationExpr(org.mapleir.ir.code.expr.invoke.InvocationExpr) Stmt(org.mapleir.ir.code.Stmt)

Aggregations

ControlFlowGraph (org.mapleir.ir.cfg.ControlFlowGraph)16 MethodNode (org.objectweb.asm.tree.MethodNode)11 BasicBlock (org.mapleir.ir.cfg.BasicBlock)9 Expr (org.mapleir.ir.code.Expr)9 Stmt (org.mapleir.ir.code.Stmt)9 ClassNode (org.objectweb.asm.tree.ClassNode)7 ApplicationClassSource (org.mapleir.app.service.ApplicationClassSource)4 InvocationResolver (org.mapleir.app.service.InvocationResolver)4 ConstantExpr (org.mapleir.ir.code.expr.ConstantExpr)4 InvocationExpr (org.mapleir.ir.code.expr.invoke.InvocationExpr)4 FieldStoreStmt (org.mapleir.ir.code.stmt.FieldStoreStmt)4 HashSet (java.util.HashSet)3 ArithmeticExpr (org.mapleir.ir.code.expr.ArithmeticExpr)3 FieldLoadExpr (org.mapleir.ir.code.expr.FieldLoadExpr)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 List (java.util.List)2 VarExpr (org.mapleir.ir.code.expr.VarExpr)2 InitialisedObjectExpr (org.mapleir.ir.code.expr.invoke.InitialisedObjectExpr)2 Invocation (org.mapleir.ir.code.expr.invoke.Invocation)2