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