Search in sources :

Example 31 with MaybeNullException

use of com.google.security.zynamics.binnavi.Exceptions.MaybeNullException in project binnavi by google.

the class CInliningHelper method inlineCodeNode.

/**
 * Inlines the basic blocks of a function into a code node.
 *
 * @param view The view where the inlining operation takes place.
 * @param originalNode The node where the inlining operation takes place.
 * @param inlineInstruction The function call instruction after which the function is inlined.
 * @param functionToInline The function to be inlined.
 *
 * @return Contains information about the inlining result.
 */
public static CInliningResult inlineCodeNode(final INaviView view, final INaviCodeNode originalNode, final INaviInstruction inlineInstruction, final INaviFunction functionToInline) {
    Preconditions.checkNotNull(view, "IE00108: View argument can not be null");
    Preconditions.checkNotNull(originalNode, "IE00109: Node argument can not be null");
    Preconditions.checkNotNull(inlineInstruction, "IE00110: Instruction argument can not be null");
    Preconditions.checkArgument(originalNode.hasInstruction(inlineInstruction), "IE00111: Instruction is not part of the code node");
    Preconditions.checkNotNull(functionToInline, "IE00112: Function argument can not be null");
    Preconditions.checkArgument(view.isLoaded(), "IE00113: View must be loaded before it can be inlined");
    Preconditions.checkArgument(view.getGraph().getNodes().contains(originalNode), "IE00114: Code node does not belong to the view");
    Preconditions.checkArgument(functionToInline.isLoaded(), "IE00115: Function must be loaded before it can be inlined");
    Preconditions.checkArgument(functionToInline.getBasicBlockCount() != 0, "IE00116: Functions with 0 blocks can not be inlined");
    final INaviGroupNode parentGroup = originalNode.getParentGroup();
    GroupHelpers.expandParents(originalNode);
    final List<INaviEdge> oldIncomingEdges = originalNode.getIncomingEdges();
    final List<INaviEdge> oldOutgoingEdges = originalNode.getOutgoingEdges();
    // At first we find out which instructions will be part of the new first block
    // and which instructions will be part of the new second block.
    final List<INaviInstruction> upperInstructions = new ArrayList<INaviInstruction>();
    final List<INaviInstruction> lowerInstructions = new ArrayList<INaviInstruction>();
    List<INaviInstruction> currentBlock = upperInstructions;
    for (final INaviInstruction currentInstruction : originalNode.getInstructions()) {
        currentBlock.add(currentInstruction);
        if (currentInstruction == inlineInstruction) {
            currentBlock = lowerInstructions;
        }
    }
    // Now we create the new nodes from the instructions blocks
    INaviCodeNode firstNode;
    final List<INaviViewNode> continueNodes = new ArrayList<INaviViewNode>();
    final boolean keepOriginalBlock = lowerInstructions.isEmpty();
    CCodeNode returnNode = null;
    if (keepOriginalBlock) {
        // There are no instructions in the second block => therefore the call instruction
        // is the last instruction of the block => therefore no splitting is necessary =>
        // therefore we can just reuse the original block.
        firstNode = originalNode;
        for (final INaviEdge edge : originalNode.getOutgoingEdges()) {
            continueNodes.add(edge.getTarget());
            view.getContent().deleteEdge(edge);
        }
    } else {
        // The second block is not empty => the call instruction is somewhere in the middle =>
        // the block must be split => the original block becomes useless and must be replaced by
        // two new blocks.
        final boolean recolor = (originalNode.getIncomingEdges().size() == 1) && (originalNode.getIncomingEdges().get(0).getType() == EdgeType.ENTER_INLINED_FUNCTION) && (originalNode.getOutgoingEdges().size() == 1) && (originalNode.getOutgoingEdges().get(0).getType() == EdgeType.LEAVE_INLINED_FUNCTION);
        view.getContent().deleteNode(originalNode);
        try {
            firstNode = view.getContent().createCodeNode(originalNode.getParentFunction(), upperInstructions);
        } catch (final MaybeNullException exception) {
            firstNode = view.getContent().createCodeNode(null, upperInstructions);
        }
        firstNode.setColor(originalNode.getColor());
        firstNode.setBorderColor(originalNode.getBorderColor());
        try {
            returnNode = view.getContent().createCodeNode(originalNode.getParentFunction(), lowerInstructions);
        } catch (final MaybeNullException e1) {
            returnNode = view.getContent().createCodeNode(null, lowerInstructions);
        }
        returnNode.setColor(originalNode.getColor());
        if (recolor) {
            firstNode.setBorderColor(new Color(-16736256));
            returnNode.setBorderColor(new Color(-6291456));
        }
        if (parentGroup != null) {
            parentGroup.addElement(firstNode);
            parentGroup.addElement(returnNode);
        }
        // Copy the tags of the original node too
        final Iterator<CTag> it = originalNode.getTagsIterator();
        while (it.hasNext()) {
            final CTag tag = it.next();
            try {
                firstNode.tagNode(tag);
                returnNode.tagNode(tag);
            } catch (final CouldntSaveDataException e) {
                CUtilityFunctions.logException(e);
            }
        }
        continueNodes.add(returnNode);
    }
    // Insert the nodes and edges from the loaded function
    final Triple<CCodeNode, List<CCodeNode>, ArrayList<CCodeNode>> nodes = insertNodes(view, functionToInline, parentGroup);
    final INaviCodeNode entryNode = nodes.first();
    final List<CCodeNode> exitNodes = nodes.second();
    if (!keepOriginalBlock) {
        for (final INaviEdge incomingEdge : oldIncomingEdges) {
            if (incomingEdge.getSource() == originalNode) {
                final EdgeType edgeType = incomingEdge.getType();
                view.getContent().createEdge(returnNode, firstNode, edgeType);
            } else {
                final EdgeType edgeType = incomingEdge.getType();
                view.getContent().createEdge(incomingEdge.getSource(), firstNode, edgeType);
            }
        }
    }
    // Create an edge from the upper part of the split block to the entry node
    // of the inlined function.
    view.getContent().createEdge(firstNode, entryNode, EdgeType.ENTER_INLINED_FUNCTION);
    // of the original function where control flow continues.
    for (final INaviCodeNode exitNode : exitNodes) {
        for (final INaviViewNode continueNode : continueNodes) {
            view.getContent().createEdge(exitNode, continueNode, EdgeType.LEAVE_INLINED_FUNCTION);
        }
    }
    if (!keepOriginalBlock) {
        for (final INaviEdge oldChild : oldOutgoingEdges) {
            for (final INaviViewNode continueNode : continueNodes) {
                if (oldChild.getTarget() != originalNode) {
                    view.getContent().createEdge(continueNode, oldChild.getTarget(), oldChild.getType());
                }
            }
        }
    }
    return new CInliningResult(firstNode, returnNode);
}
Also used : MaybeNullException(com.google.security.zynamics.binnavi.Exceptions.MaybeNullException) CouldntSaveDataException(com.google.security.zynamics.binnavi.Database.Exceptions.CouldntSaveDataException) Color(java.awt.Color) ArrayList(java.util.ArrayList) CTag(com.google.security.zynamics.binnavi.Tagging.CTag) EdgeType(com.google.security.zynamics.zylib.gui.zygraph.edges.EdgeType) ArrayList(java.util.ArrayList) List(java.util.List) CInliningResult(com.google.security.zynamics.binnavi.disassembly.algorithms.CInliningResult)

Example 32 with MaybeNullException

use of com.google.security.zynamics.binnavi.Exceptions.MaybeNullException in project binnavi by google.

the class View method createNode.

// ! Clones an existing node.
/**
 * Creates a new view node by cloning an existing view node.
 *
 * @param node The node to clone.
 *
 * @return The cloned node.
 */
public ViewNode createNode(final ViewNode node) {
    Preconditions.checkNotNull(node, "Error: Node argument can not be null");
    if (node instanceof CodeNode) {
        final List<INaviInstruction> instructionsList = new ArrayList<INaviInstruction>();
        for (final Instruction instruction : ((CodeNode) node).getInstructions()) {
            Preconditions.checkNotNull(instruction, "Error: Instruction list contains a null-element");
            instructionsList.add(instruction.getNative());
        }
        CCodeNode newNode;
        try {
            newNode = naviView.getContent().createCodeNode(((INaviCodeNode) node.getNative()).getParentFunction(), instructionsList);
        } catch (final MaybeNullException e) {
            newNode = naviView.getContent().createCodeNode(null, instructionsList);
        }
        adjustAttributes(node, newNode);
        return cachedNodes.get(newNode);
    } else if (node instanceof FunctionNode) {
        final CFunctionNode newNode = naviView.getContent().createFunctionNode(((INaviFunctionNode) node.getNative()).getFunction());
        adjustAttributes(node, newNode);
        return cachedNodes.get(newNode);
    } else if (node instanceof TextNode) {
        final CTextNode newNode = naviView.getContent().createTextNode(((TextNode) node).getComments());
        adjustAttributes(node, newNode);
        return cachedNodes.get(newNode);
    } else if (node instanceof GroupNode) {
        throw new IllegalStateException("Group nodes can not be cloned");
    } else {
        throw new IllegalStateException("Error: Unknown node type");
    }
}
Also used : CFunctionNode(com.google.security.zynamics.binnavi.disassembly.CFunctionNode) MaybeNullException(com.google.security.zynamics.binnavi.Exceptions.MaybeNullException) ArrayList(java.util.ArrayList) CFunctionNode(com.google.security.zynamics.binnavi.disassembly.CFunctionNode) INaviFunctionNode(com.google.security.zynamics.binnavi.disassembly.INaviFunctionNode) INaviTextNode(com.google.security.zynamics.binnavi.disassembly.INaviTextNode) CTextNode(com.google.security.zynamics.binnavi.disassembly.CTextNode) CGroupNode(com.google.security.zynamics.binnavi.disassembly.CGroupNode) INaviGroupNode(com.google.security.zynamics.binnavi.disassembly.INaviGroupNode) INaviInstruction(com.google.security.zynamics.binnavi.disassembly.INaviInstruction) INaviCodeNode(com.google.security.zynamics.binnavi.disassembly.INaviCodeNode) CCodeNode(com.google.security.zynamics.binnavi.disassembly.CCodeNode) INaviCodeNode(com.google.security.zynamics.binnavi.disassembly.INaviCodeNode) CCodeNode(com.google.security.zynamics.binnavi.disassembly.CCodeNode) INaviFunctionNode(com.google.security.zynamics.binnavi.disassembly.INaviFunctionNode) CTextNode(com.google.security.zynamics.binnavi.disassembly.CTextNode) INaviInstruction(com.google.security.zynamics.binnavi.disassembly.INaviInstruction)

Example 33 with MaybeNullException

use of com.google.security.zynamics.binnavi.Exceptions.MaybeNullException in project binnavi by google.

the class ResumeThreadSynchronizer method handleSuccess.

@Override
protected void handleSuccess(final ResumeThreadReply reply) {
    try {
        final TargetProcessThread thread = getDebugger().getProcessManager().getThread(reply.getThreadId());
        thread.setState(ThreadState.RUNNING);
    } catch (final MaybeNullException exception) {
        // Unlike in the error case, this is really a bug.
        NaviLogger.severe("Error: Tried to resume unknown thread '%d'", reply.getThreadId());
    }
}
Also used : TargetProcessThread(com.google.security.zynamics.binnavi.debug.models.processmanager.TargetProcessThread) MaybeNullException(com.google.security.zynamics.binnavi.Exceptions.MaybeNullException)

Example 34 with MaybeNullException

use of com.google.security.zynamics.binnavi.Exceptions.MaybeNullException in project binnavi by google.

the class ResumeThreadSynchronizer method handleError.

@Override
protected void handleError(final ResumeThreadReply reply) {
    try {
        final TargetProcessThread thread = getDebugger().getProcessManager().getThread(reply.getThreadId());
        // TODO: In case we can not resume the thread, we assume that it is really suspended.
        // This is not correct, however. What really needs to happen is that the debug client
        // sends the real state of the thread in the error message.
        thread.setState(ThreadState.SUSPENDED);
    } catch (final MaybeNullException exception) {
        // Note: This is not necessary an error situation. Imagine the following
        // 
        // 1. Send ResumeThread to the debug client
        // 2. While the command is sent, the thread is closed
        // 3. Debug client can not resume the thread
        // 4. We land here
        NaviLogger.severe("Error: Tried to resume unknown thread '%d'", reply.getThreadId());
    }
}
Also used : TargetProcessThread(com.google.security.zynamics.binnavi.debug.models.processmanager.TargetProcessThread) MaybeNullException(com.google.security.zynamics.binnavi.Exceptions.MaybeNullException)

Example 35 with MaybeNullException

use of com.google.security.zynamics.binnavi.Exceptions.MaybeNullException in project binnavi by google.

the class SingleStepSynchronizer method handleSuccess.

@Override
protected void handleSuccess(final SingleStepReply reply) {
    final ProcessManager processManager = getDebugger().getProcessManager();
    final long tid = reply.getThreadId();
    try {
        // Find the thread object with the specified TID
        final TargetProcessThread thread = processManager.getThread(tid);
        // At the end of a single step event, a thread is automatically suspended.
        processManager.setActiveThread(thread);
        // Update the thread object with the values from the event.
        setRegisterValues(reply.getRegisterValues());
        updateHitBreakpoints(DebuggerHelpers.getBreakpointAddress(getDebugger(), thread.getCurrentAddress()));
    } catch (final MaybeNullException e) {
        // Apparently there is no thread with the specified TID.
        // This is not necessarily an error because the thread might have
        // been closed while this handler was active.
        NaviLogger.info("Error: Process manager could not get thread. Exception %s", e);
    }
}
Also used : TargetProcessThread(com.google.security.zynamics.binnavi.debug.models.processmanager.TargetProcessThread) MaybeNullException(com.google.security.zynamics.binnavi.Exceptions.MaybeNullException) ProcessManager(com.google.security.zynamics.binnavi.debug.models.processmanager.ProcessManager)

Aggregations

MaybeNullException (com.google.security.zynamics.binnavi.Exceptions.MaybeNullException)42 INaviCodeNode (com.google.security.zynamics.binnavi.disassembly.INaviCodeNode)11 INaviFunction (com.google.security.zynamics.binnavi.disassembly.INaviFunction)11 TargetProcessThread (com.google.security.zynamics.binnavi.debug.models.processmanager.TargetProcessThread)10 CouldntSaveDataException (com.google.security.zynamics.binnavi.Database.Exceptions.CouldntSaveDataException)8 INaviInstruction (com.google.security.zynamics.binnavi.disassembly.INaviInstruction)7 SQLException (java.sql.SQLException)7 ProcessManager (com.google.security.zynamics.binnavi.debug.models.processmanager.ProcessManager)6 CallableStatement (java.sql.CallableStatement)6 ArrayList (java.util.ArrayList)5 CTag (com.google.security.zynamics.binnavi.Tagging.CTag)4 INaviFunctionNode (com.google.security.zynamics.binnavi.disassembly.INaviFunctionNode)4 INaviModule (com.google.security.zynamics.binnavi.disassembly.INaviModule)4 IAddress (com.google.security.zynamics.zylib.disassembly.IAddress)4 CouldntDeleteException (com.google.security.zynamics.binnavi.Database.Exceptions.CouldntDeleteException)3 CCodeNode (com.google.security.zynamics.binnavi.disassembly.CCodeNode)3 INaviViewNode (com.google.security.zynamics.binnavi.disassembly.INaviViewNode)3 CAddress (com.google.security.zynamics.zylib.disassembly.CAddress)3 CConnection (com.google.security.zynamics.binnavi.Database.CConnection)2 CouldntLoadDataException (com.google.security.zynamics.binnavi.Database.Exceptions.CouldntLoadDataException)2