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