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);
}
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");
}
}
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());
}
}
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());
}
}
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);
}
}
Aggregations