Search in sources :

Example 1 with CodeNode

use of com.google.security.zynamics.binnavi.API.disassembly.CodeNode in project binnavi by google.

the class PathFinder method connectFunctions.

/**
   * Connects the functions in the view using inlining edges.
   *
   * @param view The view where the edges are created.
   * @param startNode The start node of the path.
   * @param targetNode The target node of the path.
   * @param passedFunctions All functions that lie on the path.
   * @param entryNodes Keeps track of the entry nodes of all functions.
   * @param exitNodes Keeps track of the exit nodes of all functions.
   * @param functionMap Keeps track to what function a node belongs to.
   *
   * @return Node pair that contains the updated start node and target node.
   */
private static NodePair connectFunctions(final View view, final ViewNode startNode, final ViewNode targetNode, final Collection<FunctionBlock> passedFunctions, final Map<Function, ViewNode> entryNodes, final ArrayListMultimap<Function, ViewNode> exitNodes, final Map<ViewNode, Function> functionMap) {
    ViewNode realStartNode = startNode;
    ViewNode realTargetNode = targetNode;
    final Set<ViewNode> handled = new HashSet<ViewNode>();
    while (true) {
        boolean splitNode = false;
        start: for (final ViewNode node : view.getGraph().getNodes()) {
            if (handled.contains(node)) {
                continue;
            }
            if (!(node instanceof CodeNode)) {
                continue;
            }
            final CodeNode cnode = (CodeNode) node;
            for (final Instruction instruction : cnode.getInstructions()) {
                for (final FunctionBlock functionBlock : passedFunctions) {
                    final Function function = functionBlock.getFunction();
                    if (callsFunction(instruction, function)) {
                        // A function call to a function on the path was found.
                        // At this point we have to split the code node after
                        // the function call.
                        final NodePair result = splitBlock(view, functionMap.get(cnode), cnode, instruction);
                        if (realStartNode == cnode) {
                            // Of course it is possible that the start node was split,
                            // therefore we have to update the start node to the upper
                            // part of the new node.
                            realStartNode = result.getFirst();
                        }
                        if (realTargetNode == cnode) {
                            // Of course it is possible that the target node was split,
                            // therefore we have to update the target node to the upper
                            // part of the new node.
                            realTargetNode = result.getFirst();
                        }
                        // too.
                        for (final FunctionBlock functionBlock2 : passedFunctions) {
                            final Function function2 = functionBlock2.getFunction();
                            if (entryNodes.get(function2) == cnode) {
                                // Update the entry nodes
                                entryNodes.put(function2, result.getFirst());
                            }
                            if (exitNodes.get(function2).contains(cnode)) {
                                // Update the exit nodes
                                if (result.getSecond() != null) {
                                    exitNodes.remove(function2, cnode);
                                    exitNodes.put(function2, result.getSecond());
                                }
                            }
                        }
                        if (functionMap.containsKey(cnode)) {
                            final Function f = functionMap.get(cnode);
                            functionMap.remove(cnode);
                            functionMap.put(result.getFirst(), f);
                        }
                        handled.add(result.getFirst());
                        if (result.getSecond() == null) {
                            for (final ViewEdge edge : node.getOutgoingEdges()) {
                                for (final ViewNode currentExitNode : exitNodes.get(function)) {
                                    final ViewEdge leaveEdge = view.createEdge(currentExitNode, edge.getTarget(), EdgeType.LeaveInlinedFunction);
                                    leaveEdge.setColor(DEFAULT_INLINING_EDGE_COLOR);
                                }
                                view.deleteEdge(edge);
                            }
                            final ViewEdge enterEdge = view.createEdge(result.getFirst(), entryNodes.get(function), EdgeType.EnterInlinedFunction);
                            enterEdge.setColor(DEFAULT_INLINING_EDGE_COLOR);
                            handled.add(cnode);
                        } else {
                            // The node was split. We simply have to connect both split parts to the
                            // called function.
                            final ViewEdge enterEdge = view.createEdge(result.getFirst(), entryNodes.get(function), EdgeType.EnterInlinedFunction);
                            enterEdge.setColor(DEFAULT_INLINING_EDGE_COLOR);
                            for (final ViewNode currentExitNode : exitNodes.get(function)) {
                                final ViewEdge leaveEdge = view.createEdge(currentExitNode, result.getSecond(), EdgeType.LeaveInlinedFunction);
                                leaveEdge.setColor(DEFAULT_INLINING_EDGE_COLOR);
                            }
                        }
                        splitNode = true;
                        break start;
                    }
                }
            }
            handled.add(cnode);
        }
        if (!splitNode) {
            break;
        }
    }
    return new NodePair(realStartNode, realTargetNode);
}
Also used : Function(com.google.security.zynamics.binnavi.API.disassembly.Function) CodeNode(com.google.security.zynamics.binnavi.API.disassembly.CodeNode) ViewEdge(com.google.security.zynamics.binnavi.API.disassembly.ViewEdge) ViewNode(com.google.security.zynamics.binnavi.API.disassembly.ViewNode) Instruction(com.google.security.zynamics.binnavi.API.disassembly.Instruction) FunctionBlock(com.google.security.zynamics.binnavi.API.disassembly.FunctionBlock) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 2 with CodeNode

use of com.google.security.zynamics.binnavi.API.disassembly.CodeNode in project binnavi by google.

the class PathFinder method createInitialBlocks.

/**
   * Creates the initial nodes for all basic blocks in the passed functions.
   *
   * @param view The view where the nodes are created.
   *
   * @param passedFunctions All functions that lie on the path.
   * @param nodeMap Maps basic blocks of the functions on the path to their corresponding view
   *        nodes.
   * @param functionMap Keeps track to what function a node belongs to.
   *
   * @throws CouldntLoadDataException Thrown if a function could not be loaded.
   */
private static void createInitialBlocks(final View view, final Collection<FunctionBlock> passedFunctions, final Map<BasicBlock, ViewNode> nodeMap, final Map<ViewNode, Function> functionMap) throws CouldntLoadDataException {
    for (final FunctionBlock functionBlock : passedFunctions) {
        final Function function = functionBlock.getFunction();
        if (function.getType() == FunctionType.Import) {
            // Imported functions to not have any basic blocks, for those functions
            // we simply create a function node.
            final FunctionNode newNode = view.createFunctionNode(function);
            functionMap.put(newNode, function);
        // TODO (timkornau): Assign a proper color to the node.
        // TODO (timkornau): Properly treat forwarded functions.
        } else {
            function.load();
            for (final BasicBlock block : function.getGraph().getNodes()) {
                final CodeNode newNode = view.createCodeNode(function, block.getInstructions());
                newNode.setColor(DEFAULT_BLOCK_COLOR);
                nodeMap.put(block, newNode);
                functionMap.put(newNode, function);
            }
        }
    }
}
Also used : Function(com.google.security.zynamics.binnavi.API.disassembly.Function) CodeNode(com.google.security.zynamics.binnavi.API.disassembly.CodeNode) FunctionNode(com.google.security.zynamics.binnavi.API.disassembly.FunctionNode) BasicBlock(com.google.security.zynamics.binnavi.API.disassembly.BasicBlock) FunctionBlock(com.google.security.zynamics.binnavi.API.disassembly.FunctionBlock)

Example 3 with CodeNode

use of com.google.security.zynamics.binnavi.API.disassembly.CodeNode in project binnavi by google.

the class PathFinder method splitBlock.

/**
   * Splits a code node into two nodes at a function call. If the input node really is split, it is
   * removed from the view. If the input node is not split (because the calling instruction is the
   * last instruction of the code node) then the view nodes remain unchanged.
   *
   * @param view The view the code node belongs to.
   * @param function The function the code node belongs to.
   * @param node The node to split.
   * @param instruction The calling instruction after which the node is split.
   *
   * @return A node pair that contains the two new nodes or the input node and null if the input
   *         node was not split.
   */
private static NodePair splitBlock(final View view, final Function function, final CodeNode node, final Instruction instruction) {
    boolean before = true;
    final List<Instruction> beforeInstructions = new ArrayList<Instruction>();
    final List<Instruction> afterInstructions = new ArrayList<Instruction>();
    for (final Instruction nodeInstruction : node.getInstructions()) {
        if (before) {
            beforeInstructions.add(nodeInstruction);
        } else {
            afterInstructions.add(nodeInstruction);
        }
        if (nodeInstruction == instruction) {
            before = false;
        }
    }
    if (afterInstructions.isEmpty()) {
        return new NodePair(node, null);
    } else {
        final CodeNode firstNode = view.createCodeNode(function, beforeInstructions);
        final CodeNode secondNode = view.createCodeNode(function, afterInstructions);
        firstNode.setColor(node.getColor());
        secondNode.setColor(DEFAULT_BLOCK_COLOR);
        for (final ViewEdge edge : node.getIncomingEdges()) {
            final ViewEdge newEdge = view.createEdge(edge.getSource(), firstNode, edge.getType());
            newEdge.setColor(edge.getColor());
        }
        for (final ViewEdge edge : node.getOutgoingEdges()) {
            final ViewEdge newEdge = view.createEdge(secondNode, edge.getTarget(), edge.getType());
            newEdge.setColor(edge.getColor());
        }
        view.deleteNode(node);
        return new NodePair(firstNode, secondNode);
    }
}
Also used : CodeNode(com.google.security.zynamics.binnavi.API.disassembly.CodeNode) ArrayList(java.util.ArrayList) ViewEdge(com.google.security.zynamics.binnavi.API.disassembly.ViewEdge) Instruction(com.google.security.zynamics.binnavi.API.disassembly.Instruction)

Example 4 with CodeNode

use of com.google.security.zynamics.binnavi.API.disassembly.CodeNode in project binnavi by google.

the class BreakpointHelpers method getBreakpoints.

/**
   * Returns the addresses of a view where breakpoints are set.
   *
   * @param debugger The debugger that set the breakpoint.
   * @param view The view to search through.
   * @param type Type of the breakpoints to search for.
   *
   * @return The addresses of the view where breakpoints of a given type are set.
   */
private static List<Address> getBreakpoints(final Debugger debugger, final View view, final BreakpointType type) {
    Preconditions.checkNotNull(debugger, "Error: Debugger argument can not be null");
    Preconditions.checkNotNull(view, "Error: View argument can not be null");
    final BreakpointManager manager = debugger.getBreakpointManager();
    final List<Address> breakpoints = new ArrayList<Address>();
    for (final ViewNode node : view.getGraph().getNodes()) {
        if (node instanceof CodeNode) {
            breakpoints.addAll(getBreakpoints(debugger, (CodeNode) node, type));
        } else if (node instanceof FunctionNode) {
            final FunctionNode fnode = (FunctionNode) node;
            final BreakpointAddress address = new BreakpointAddress(fnode.getFunction().getNative().getModule(), new UnrelocatedAddress(fnode.getFunction().getNative().getAddress()));
            if (manager.getNative().hasBreakpoint(type, address)) {
                breakpoints.add(new Address(address.getAddress().getAddress().toBigInteger()));
            }
        }
    }
    return breakpoints;
}
Also used : CAddress(com.google.security.zynamics.zylib.disassembly.CAddress) BreakpointAddress(com.google.security.zynamics.binnavi.debug.models.breakpoints.BreakpointAddress) Address(com.google.security.zynamics.binnavi.API.disassembly.Address) UnrelocatedAddress(com.google.security.zynamics.binnavi.disassembly.UnrelocatedAddress) CodeNode(com.google.security.zynamics.binnavi.API.disassembly.CodeNode) UnrelocatedAddress(com.google.security.zynamics.binnavi.disassembly.UnrelocatedAddress) ArrayList(java.util.ArrayList) FunctionNode(com.google.security.zynamics.binnavi.API.disassembly.FunctionNode) ViewNode(com.google.security.zynamics.binnavi.API.disassembly.ViewNode) BreakpointAddress(com.google.security.zynamics.binnavi.debug.models.breakpoints.BreakpointAddress)

Example 5 with CodeNode

use of com.google.security.zynamics.binnavi.API.disassembly.CodeNode in project binnavi by google.

the class InstructionFinders method findInstruction.

/**
   * Searches for an instruction in a view.
   *
   * @param view The view to search through.
   * @param searchInstruction The instruction to search for.
   *
   * @return The API instruction object that wraps the search instruction.
   */
public static Instruction findInstruction(final View view, final IInstruction searchInstruction) {
    Preconditions.checkNotNull(view, "IE02056: View argument can not be null");
    Preconditions.checkNotNull(searchInstruction, "IE02060: Instruction argument can not be null");
    for (final ViewNode node : view.getGraph().getNodes()) {
        if (node instanceof CodeNode) {
            final CodeNode codeNode = (CodeNode) node;
            for (final Instruction instruction : codeNode.getInstructions()) {
                if (instruction.getNative() == searchInstruction) {
                    return instruction;
                }
            }
        }
    }
    throw new IllegalStateException("IE01275: Could not determine what instruction could not be translated");
}
Also used : CodeNode(com.google.security.zynamics.binnavi.API.disassembly.CodeNode) ViewNode(com.google.security.zynamics.binnavi.API.disassembly.ViewNode) Instruction(com.google.security.zynamics.binnavi.API.disassembly.Instruction) IInstruction(com.google.security.zynamics.zylib.disassembly.IInstruction)

Aggregations

CodeNode (com.google.security.zynamics.binnavi.API.disassembly.CodeNode)5 Instruction (com.google.security.zynamics.binnavi.API.disassembly.Instruction)3 ViewNode (com.google.security.zynamics.binnavi.API.disassembly.ViewNode)3 Function (com.google.security.zynamics.binnavi.API.disassembly.Function)2 FunctionBlock (com.google.security.zynamics.binnavi.API.disassembly.FunctionBlock)2 FunctionNode (com.google.security.zynamics.binnavi.API.disassembly.FunctionNode)2 ViewEdge (com.google.security.zynamics.binnavi.API.disassembly.ViewEdge)2 ArrayList (java.util.ArrayList)2 Address (com.google.security.zynamics.binnavi.API.disassembly.Address)1 BasicBlock (com.google.security.zynamics.binnavi.API.disassembly.BasicBlock)1 BreakpointAddress (com.google.security.zynamics.binnavi.debug.models.breakpoints.BreakpointAddress)1 UnrelocatedAddress (com.google.security.zynamics.binnavi.disassembly.UnrelocatedAddress)1 CAddress (com.google.security.zynamics.zylib.disassembly.CAddress)1 IInstruction (com.google.security.zynamics.zylib.disassembly.IInstruction)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1