Search in sources :

Example 6 with Function

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

the class PathFinder method createInitialEdges.

/**
   * Creates view edges for all edges in the passed functions.
   *
   * @param view The view where the edges are created.
   * @param passedFunctions All functions that lie on the path.
   * @param nodeMap Maps between the basic blocks of the functions and their corresponding code
   *        nodes.
   */
private static void createInitialEdges(final View view, final Collection<FunctionBlock> passedFunctions, final Map<BasicBlock, ViewNode> nodeMap) {
    for (final FunctionBlock functionBlock : passedFunctions) {
        final Function function = functionBlock.getFunction();
        for (final BlockEdge edge : function.getGraph().getEdges()) {
            final ViewEdge newEdge = view.createEdge(nodeMap.get(edge.getSource()), nodeMap.get(edge.getTarget()), edge.getType());
            newEdge.setColor(getEdgeColor(edge));
        }
    }
}
Also used : Function(com.google.security.zynamics.binnavi.API.disassembly.Function) BlockEdge(com.google.security.zynamics.binnavi.API.disassembly.BlockEdge) ViewEdge(com.google.security.zynamics.binnavi.API.disassembly.ViewEdge) FunctionBlock(com.google.security.zynamics.binnavi.API.disassembly.FunctionBlock)

Example 7 with Function

use of com.google.security.zynamics.binnavi.API.disassembly.Function 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 8 with Function

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

the class PathfinderPlugin method showPathfindingDialog.

/**
   * Shows the pathfinding dialog that is used to select the start block and the end block of the
   * pathfinding operation.
   * 
   * @param module The target module of the pathfinding operation.
   * @throws CouldntLoadDataException Thrown if one of the functions couldn't be loaded.
   */
private void showPathfindingDialog(final Module module) throws CouldntLoadDataException {
    Preconditions.checkArgument(module.isLoaded(), "Internal Error: Target module is not loaded");
    final PathfindingDialog dlg = new PathfindingDialog(pluginInterface.getMainWindow().getFrame(), module);
    GuiHelper.centerChildToParent(pluginInterface.getMainWindow().getFrame(), dlg, true);
    dlg.setVisible(true);
    if (dlg.wasCancelled()) {
        return;
    }
    final BasicBlock sourceBlock = dlg.getStartBlock();
    final BasicBlock targetBlock = dlg.getEndBlock();
    final Function firstFunction = dlg.getStartFunction();
    final Function secondFunction = dlg.getEndFunction();
    // for every time when a user has not selected a function but a basic block this breaks.
    // As it does throw a null pointer exception.
    firstFunction.load();
    secondFunction.load();
    final CreationThread creationThread = new CreationThread(module, sourceBlock, targetBlock, firstFunction, secondFunction);
    ProgressDialog.show(pluginInterface.getMainWindow().getFrame(), "Creating path ...", creationThread);
    if ((!(creationThread.threwException())) && (creationThread.getCreatedView() == null)) {
        MessageBox.showInformation(pluginInterface.getMainWindow().getFrame(), "There is no path between the two selected blocks");
    } else {
        new Thread() {

            @Override
            public void run() {
                PluginInterface.instance().showInNewWindow(creationThread.getCreatedView());
            }
        }.start();
    }
}
Also used : Function(com.google.security.zynamics.binnavi.API.disassembly.Function) BasicBlock(com.google.security.zynamics.binnavi.API.disassembly.BasicBlock) IProgressThread(com.google.security.zynamics.binnavi.API.helpers.IProgressThread)

Example 9 with Function

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

the class CallResolver method resolveFunction.

private ResolvedFunction resolveFunction(final Address address) {
    for (final Module module : target.getModules()) {
        if (!resolvedFunctions.containsKey(module)) {
            resolveFunctions(module);
            if (!resolvedFunctions.containsKey(module)) {
                continue;
            }
        }
        final Map<Address, Function> functionMap = resolvedFunctions.get(module);
        final Function function = functionMap.get(address);
        if (function != null) {
            return new ResolvedFunction(function);
        }
    }
    for (final MemoryModule memoryModule : target.getDebugger().getProcess().getModules()) {
        if ((address.toLong() >= memoryModule.getBaseAddress().toLong()) && (address.toLong() < (memoryModule.getBaseAddress().toLong() + memoryModule.getSize()))) {
            return new ResolvedFunction(memoryModule, address);
        }
    }
    return new ResolvedFunction(address);
}
Also used : Function(com.google.security.zynamics.binnavi.API.disassembly.Function) Address(com.google.security.zynamics.binnavi.API.disassembly.Address) MemoryModule(com.google.security.zynamics.binnavi.API.debug.MemoryModule) Module(com.google.security.zynamics.binnavi.API.disassembly.Module) MemoryModule(com.google.security.zynamics.binnavi.API.debug.MemoryModule)

Example 10 with Function

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

the class OutputGraphGenerator method createLoggedView.

/**
   * Creates a view that shows all nodes and edges from the original call graph in addition to the
   * newly resolved functions.
   * 
   * @param target The target whose indirect modules were resolved.
   * @param indirectCallAddresses The addresses of the indirect call objects from the target.
   * @param resolvedAddresses The resolved function addresses.
   * 
   * @return The generated view.
   */
public static View createLoggedView(final ICallResolverTarget target, final List<IndirectCall> indirectCallAddresses, final Map<BigInteger, Set<ResolvedFunction>> resolvedAddresses) {
    final View view = target.createView();
    final Map<Function, FunctionNode> nodes = new HashMap<Function, FunctionNode>();
    for (final Entry<BigInteger, Set<ResolvedFunction>> element : resolvedAddresses.entrySet()) {
        final BigInteger start = element.getKey();
        final Set<ResolvedFunction> targets = element.getValue();
        final IndirectCall call = IndirectCallResolver.findIndirectCall(target.getDebugger(), indirectCallAddresses, start);
        FunctionNode sourceNode = nodes.get(call.getFunction());
        if (sourceNode == null) {
            sourceNode = view.createFunctionNode(call.getFunction());
            nodes.put(call.getFunction(), sourceNode);
        }
        for (final ResolvedFunction targetFunction : targets) {
            final Function function = targetFunction.getFunction();
            final MemoryModule memoryModule = targetFunction.getMemoryModule();
            if (function != null) {
                FunctionNode targetNode = nodes.get(function);
                if (targetNode == null) {
                    targetNode = view.createFunctionNode(function);
                    nodes.put(function, targetNode);
                }
                try {
                    sourceNode.appendComment(start.toString(16).toUpperCase() + " -> " + function.getAddress().toHexString().toUpperCase());
                } catch (CouldntSaveDataException | CouldntLoadDataException e) {
                    e.printStackTrace();
                }
                view.createEdge(sourceNode, targetNode, EdgeType.JumpUnconditional);
            } else if (memoryModule != null) {
                final String targetString = String.format("%s!%s", targetFunction.getMemoryModule().getName(), targetFunction.getAddress().toHexString().toUpperCase());
                try {
                    sourceNode.appendComment(start.toString(16).toUpperCase() + " -> " + targetString);
                } catch (CouldntSaveDataException | CouldntLoadDataException e) {
                    e.printStackTrace();
                }
            } else {
                final String targetString = "???!" + targetFunction.getAddress().toHexString().toUpperCase();
                try {
                    sourceNode.appendComment(start.toString(16).toUpperCase() + " -> " + targetString);
                } catch (CouldntSaveDataException | CouldntLoadDataException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    for (final Module module : target.getModules()) {
        final Callgraph callgraph = module.getCallgraph();
        for (final FunctionEdge edge : callgraph.getEdges()) {
            final FunctionNode source = nodes.get(edge.getSource().getFunction());
            final FunctionNode targetNode = nodes.get(edge.getTarget().getFunction());
            if ((source != null) && (targetNode != null)) {
                view.createEdge(source, targetNode, EdgeType.JumpUnconditional);
            }
        }
    }
    return view;
}
Also used : Set(java.util.Set) HashMap(java.util.HashMap) CouldntSaveDataException(com.google.security.zynamics.binnavi.API.disassembly.CouldntSaveDataException) CouldntLoadDataException(com.google.security.zynamics.binnavi.API.disassembly.CouldntLoadDataException) FunctionNode(com.google.security.zynamics.binnavi.API.disassembly.FunctionNode) View(com.google.security.zynamics.binnavi.API.disassembly.View) MemoryModule(com.google.security.zynamics.binnavi.API.debug.MemoryModule) Function(com.google.security.zynamics.binnavi.API.disassembly.Function) Callgraph(com.google.security.zynamics.binnavi.API.disassembly.Callgraph) FunctionEdge(com.google.security.zynamics.binnavi.API.disassembly.FunctionEdge) BigInteger(java.math.BigInteger) Module(com.google.security.zynamics.binnavi.API.disassembly.Module) MemoryModule(com.google.security.zynamics.binnavi.API.debug.MemoryModule)

Aggregations

Function (com.google.security.zynamics.binnavi.API.disassembly.Function)22 BasicBlock (com.google.security.zynamics.binnavi.API.disassembly.BasicBlock)13 View (com.google.security.zynamics.binnavi.API.disassembly.View)13 Test (org.junit.Test)9 HashMap (java.util.HashMap)6 FunctionBlock (com.google.security.zynamics.binnavi.API.disassembly.FunctionBlock)5 ViewEdge (com.google.security.zynamics.binnavi.API.disassembly.ViewEdge)5 MemoryModule (com.google.security.zynamics.binnavi.API.debug.MemoryModule)4 Address (com.google.security.zynamics.binnavi.API.disassembly.Address)4 Module (com.google.security.zynamics.binnavi.API.disassembly.Module)4 ViewNode (com.google.security.zynamics.binnavi.API.disassembly.ViewNode)4 FunctionNode (com.google.security.zynamics.binnavi.API.disassembly.FunctionNode)3 BigInteger (java.math.BigInteger)3 Set (java.util.Set)3 Callgraph (com.google.security.zynamics.binnavi.API.disassembly.Callgraph)2 CodeNode (com.google.security.zynamics.binnavi.API.disassembly.CodeNode)2 CouldntSaveDataException (com.google.security.zynamics.binnavi.API.disassembly.CouldntSaveDataException)2 FunctionEdge (com.google.security.zynamics.binnavi.API.disassembly.FunctionEdge)2 Instruction (com.google.security.zynamics.binnavi.API.disassembly.Instruction)2 BlockEdge (com.google.security.zynamics.binnavi.API.disassembly.BlockEdge)1