Search in sources :

Example 11 with ReilEdge

use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.

the class InstructionGraph method create.

/**
   * Creates an instruction graph from a REIL graph.
   * 
   * @param graph The REIL graph to convert.
   * 
   * @return The created instruction graph.
   */
public static InstructionGraph create(final ReilGraph graph) {
    Preconditions.checkNotNull(graph, "Error: graph argument can not be null");
    final List<InstructionGraphNode> nodes = new ArrayList<InstructionGraphNode>();
    final List<InstructionGraphEdge> edges = new ArrayList<InstructionGraphEdge>();
    final HashMap<ReilBlock, InstructionGraphNode> firstNodeMapping = new HashMap<ReilBlock, InstructionGraphNode>();
    final HashMap<ReilBlock, InstructionGraphNode> lastNodeMapping = new HashMap<ReilBlock, InstructionGraphNode>();
    for (final ReilBlock block : graph) {
        InstructionGraphNode lastNode = null;
        final ReilInstruction lastInstruction = Iterables.getLast(block.getInstructions());
        for (final ReilInstruction instruction : block) {
            // NOPMD by
            final InstructionGraphNode currentNode = new InstructionGraphNode(instruction);
            // sp on
            // 04.11.08
            // 14:17
            nodes.add(currentNode);
            if (instruction == lastInstruction) {
                lastNodeMapping.put(block, currentNode);
            }
            if (!firstNodeMapping.containsKey(block)) {
                firstNodeMapping.put(block, currentNode);
            }
            if (lastNode != null) {
                final InstructionGraphEdge edge = // NOPMD
                new InstructionGraphEdge(lastNode, currentNode, EdgeType.JUMP_UNCONDITIONAL);
                // by sp
                // on
                // 04.11.08
                // 14:18
                edges.add(edge);
                InstructionGraphNode.link(lastNode, currentNode, edge);
            }
            lastNode = currentNode;
        }
    }
    for (final ReilBlock block : graph) {
        for (final ReilEdge edge : block.getOutgoingEdges()) {
            final InstructionGraphEdge newEdge = new InstructionGraphEdge(lastNodeMapping.get(block), firstNodeMapping.get(edge.getTarget()), // NOPMD by sp on 04.11.08 14:18
            edge.getType());
            edges.add(newEdge);
            InstructionGraphNode.link(lastNodeMapping.get(block), firstNodeMapping.get(edge.getTarget()), newEdge);
        }
    }
    return new InstructionGraph(nodes, edges);
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) HashMap(java.util.HashMap) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ArrayList(java.util.ArrayList)

Example 12 with ReilEdge

use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.

the class ReilTranslator method handleDelayedTrueBranches.

/**
   * This function is responsible for modifying the generated graph at all likely delayed branches.
   * 
   * @param nodes
   * @param edges
   * @param delayedTrueBranches
   */
private static void handleDelayedTrueBranches(final List<ReilBlock> nodes, final List<ReilEdge> edges, final List<List<ReilInstruction>> delayedTrueBranches) {
    for (final List<ReilInstruction> lastReil : delayedTrueBranches) {
        // In this post-processing step we consider all the delayed branches where the delayed
        // instruction is only executed if the branch is taken.
        //
        // We solve the problem by removing the branch-delayed instruction from the original
        // block. Then we take the removed instructions to form a new block. The true branch
        // of the original block is connected with the new block. The false branch of the
        // original block remains unchanged.
        final ReilInstruction lastReilInstruction = lastReil.get(lastReil.size() - 1);
        for (final ReilBlock node : nodes) {
            final Iterable<ReilInstruction> nodeInstructions = node.getInstructions();
            if (Iterables.getLast(nodeInstructions) == lastReilInstruction) {
                // The situation we are having here is that have located the
                // node that contains the delayed instruction. In fact this node
                // contains only the code of the delayed instruction. It has one
                // incoming edge and two outgoing edges.
                //
                // We now have to rewrite the edges to make sure the jump has
                // the two outgoing edges.
                final ReilEdge incomingEdge = node.getIncomingEdges().get(0);
                final ReilBlock parentNode = incomingEdge.getSource();
                edges.remove(incomingEdge);
                boolean first = true;
                for (final ReilEdge outgoingEdge : node.getOutgoingEdges()) {
                    if (first) {
                        first = false;
                        final ReilEdge newEdge = new ReilEdge(parentNode, node, EdgeType.JUMP_CONDITIONAL_TRUE);
                        ReilBlock.link(parentNode, node, newEdge);
                        edges.add(newEdge);
                        final ReilEdge newEdge2 = new ReilEdge(parentNode, outgoingEdge.getTarget(), EdgeType.JUMP_CONDITIONAL_FALSE);
                        ReilBlock.link(parentNode, outgoingEdge.getTarget(), newEdge2);
                        edges.add(newEdge2);
                    } else {
                        final ReilEdge newEdge2 = new ReilEdge(node, outgoingEdge.getTarget(), outgoingEdge.getType());
                        ReilBlock.link(node, outgoingEdge.getTarget(), newEdge2);
                        edges.add(newEdge2);
                    }
                    edges.remove(outgoingEdge);
                    ReilBlock.unlink(outgoingEdge.getSource(), outgoingEdge.getTarget(), outgoingEdge);
                }
            }
        }
    }
}
Also used : ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock)

Example 13 with ReilEdge

use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.

the class TestFollowZFIncomingBackwards method generateReilGraph.

private void generateReilGraph(final List<List<String>> instructions, final List<String> edges) {
    final Map<Long, ReilBlock> blocks = new HashMap<Long, ReilBlock>();
    for (final List<String> currentBlockInstructions : instructions) {
        final List<ReilInstruction> reilInstructions = new ArrayList<ReilInstruction>();
        for (final String addressAndInstruction : currentBlockInstructions) {
            final StringTokenizer tokenizer = new StringTokenizer(addressAndInstruction, ": [,]", false);
            final long offset = Long.parseLong(tokenizer.nextToken(), 16);
            final String mnemonic = tokenizer.nextToken();
            if (mnemonic.equalsIgnoreCase("bisz") || mnemonic.equalsIgnoreCase("str") || mnemonic.equalsIgnoreCase("ldm") || mnemonic.equalsIgnoreCase("stm") || mnemonic.equalsIgnoreCase("jcc")) {
                final OperandSize firstSize = OperandSize.valueOf(tokenizer.nextToken());
                final String firstValue = tokenizer.nextToken();
                tokenizer.nextToken();
                final OperandSize thirdSize = OperandSize.valueOf(tokenizer.nextToken());
                final String thirdValue = tokenizer.nextToken();
                if (mnemonic.equalsIgnoreCase("bisz")) {
                    reilInstructions.add(ReilHelpers.createBisz(offset, firstSize, firstValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("str")) {
                    reilInstructions.add(ReilHelpers.createStr(offset, firstSize, firstValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("jcc")) {
                    reilInstructions.add(ReilHelpers.createJcc(offset, firstSize, firstValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("ldm")) {
                    reilInstructions.add(ReilHelpers.createLdm(offset, firstSize, firstValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("stm")) {
                    reilInstructions.add(ReilHelpers.createStm(offset, firstSize, firstValue, thirdSize, thirdValue));
                }
            } else if (mnemonic.equalsIgnoreCase("nop")) {
                reilInstructions.add(ReilHelpers.createNop(offset));
            } else {
                final OperandSize firstSize = OperandSize.valueOf(tokenizer.nextToken());
                final String firstValue = tokenizer.nextToken();
                final OperandSize secondSize = OperandSize.valueOf(tokenizer.nextToken());
                final String secondValue = tokenizer.nextToken();
                final OperandSize thirdSize = OperandSize.valueOf(tokenizer.nextToken());
                final String thirdValue = tokenizer.nextToken();
                if (mnemonic.equalsIgnoreCase("add")) {
                    reilInstructions.add(ReilHelpers.createAdd(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("and")) {
                    reilInstructions.add(ReilHelpers.createAnd(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("bsh")) {
                    reilInstructions.add(ReilHelpers.createBsh(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("div")) {
                    reilInstructions.add(ReilHelpers.createDiv(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("mod")) {
                    reilInstructions.add(ReilHelpers.createMod(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("mul")) {
                    reilInstructions.add(ReilHelpers.createMul(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("or")) {
                    reilInstructions.add(ReilHelpers.createOr(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("sub")) {
                    reilInstructions.add(ReilHelpers.createSub(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
                if (mnemonic.equalsIgnoreCase("xor")) {
                    reilInstructions.add(ReilHelpers.createXor(offset, firstSize, firstValue, secondSize, secondValue, thirdSize, thirdValue));
                }
            }
        }
        blocks.put(reilInstructions.get(0).getAddress().toLong(), new ReilBlock(reilInstructions));
    }
    final List<ReilEdge> reilEdges = new ArrayList<ReilEdge>();
    for (final String edge : edges) {
        final StringTokenizer edgeTokenizer = new StringTokenizer(edge, " []->");
        final Long sourceAddress = Long.parseLong(edgeTokenizer.nextToken(), 16);
        final EdgeType type = Enum.valueOf(EdgeType.class, edgeTokenizer.nextToken().toUpperCase());
        final Long targetAddress = Long.parseLong(edgeTokenizer.nextToken(), 16);
        final ReilEdge reilEdge = new ReilEdge(blocks.get(sourceAddress), blocks.get(targetAddress), type);
        ReilBlock.link(blocks.get(sourceAddress), blocks.get(targetAddress), reilEdge);
    }
    m_graph1 = new ReilGraph(Lists.newArrayList(blocks.values()), reilEdges);
}
Also used : ReilGraph(com.google.security.zynamics.reil.ReilGraph) ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) HashMap(java.util.HashMap) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ArrayList(java.util.ArrayList) EdgeType(com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType) StringTokenizer(java.util.StringTokenizer) OperandSize(com.google.security.zynamics.reil.OperandSize)

Example 14 with ReilEdge

use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.

the class InstructionGraphTest method testOneNode.

@Test
public void testOneNode() {
    final ReilBlock block1 = new ReilBlock(Lists.newArrayList(ReilHelpers.createNop(0), ReilHelpers.createNop(0), ReilHelpers.createNop(0), ReilHelpers.createNop(0), ReilHelpers.createNop(0)));
    final List<ReilBlock> blocks = Lists.<ReilBlock>newArrayList(block1);
    final ReilGraph rg = new ReilGraph(blocks, new ArrayList<ReilEdge>());
    final InstructionGraph g = InstructionGraph.create(rg);
    assertEquals(5, g.nodeCount());
    assertEquals(4, g.edgeCount());
}
Also used : ReilGraph(com.google.security.zynamics.reil.ReilGraph) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) InstructionGraph(com.google.security.zynamics.reil.algorithms.mono.InstructionGraph) Test(org.junit.Test)

Example 15 with ReilEdge

use of com.google.security.zynamics.reil.ReilEdge in project binnavi by google.

the class OperandGraphTest method testTwoNodes.

@Test
public void testTwoNodes() {
    final Collection<ReilInstruction> instructions1 = new ArrayList<ReilInstruction>();
    instructions1.add(ReilHelpers.createAdd(0, OperandSize.DWORD, "eax", OperandSize.DWORD, "123", OperandSize.QWORD, "t0"));
    final Collection<ReilInstruction> instructions2 = new ArrayList<ReilInstruction>();
    instructions2.add(ReilHelpers.createAnd(1, OperandSize.QWORD, "t0", OperandSize.DWORD, String.valueOf(0xFFFFFFFF), OperandSize.DWORD, "t1"));
    final ReilBlock block1 = new ReilBlock(instructions1);
    final ReilBlock block2 = new ReilBlock(instructions2);
    final ReilEdge edge1 = new ReilEdge(block1, block2, EdgeType.JUMP_CONDITIONAL_FALSE);
    ReilBlock.link(block1, block2, edge1);
    final List<ReilBlock> blocks = Lists.newArrayList(block1, block2);
    final List<ReilEdge> edges = Lists.newArrayList(edge1);
    final ReilGraph rg = new ReilGraph(blocks, edges);
    final OperandGraph g = OperandGraph.create(rg);
    assertEquals(6, g.nodeCount());
    assertEquals(5, g.edgeCount());
}
Also used : OperandGraph(com.google.security.zynamics.reil.algorithms.mono.OperandGraph) ReilGraph(com.google.security.zynamics.reil.ReilGraph) ReilInstruction(com.google.security.zynamics.reil.ReilInstruction) ReilEdge(com.google.security.zynamics.reil.ReilEdge) ReilBlock(com.google.security.zynamics.reil.ReilBlock) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Aggregations

ReilBlock (com.google.security.zynamics.reil.ReilBlock)16 ReilEdge (com.google.security.zynamics.reil.ReilEdge)16 ReilInstruction (com.google.security.zynamics.reil.ReilInstruction)11 ReilGraph (com.google.security.zynamics.reil.ReilGraph)10 Test (org.junit.Test)8 ArrayList (java.util.ArrayList)7 HashMap (java.util.HashMap)4 ReilFunction (com.google.security.zynamics.reil.ReilFunction)3 InstructionGraph (com.google.security.zynamics.reil.algorithms.mono.InstructionGraph)3 OperandGraph (com.google.security.zynamics.reil.algorithms.mono.OperandGraph)3 EdgeType (com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType)3 INaviInstruction (com.google.security.zynamics.binnavi.disassembly.INaviInstruction)2 InstructionGraphNode (com.google.security.zynamics.reil.algorithms.mono.InstructionGraphNode)2 ValueTrackerElement (com.google.security.zynamics.reil.algorithms.mono.valuetracking.ValueTrackerElement)2 IAddress (com.google.security.zynamics.zylib.disassembly.IAddress)2 Pair (com.google.security.zynamics.zylib.general.Pair)2 CCodeNode (com.google.security.zynamics.binnavi.disassembly.CCodeNode)1 CNaviViewEdge (com.google.security.zynamics.binnavi.disassembly.CNaviViewEdge)1 COperandTree (com.google.security.zynamics.binnavi.disassembly.COperandTree)1 INaviView (com.google.security.zynamics.binnavi.disassembly.views.INaviView)1