use of com.google.security.zynamics.binnavi.API.disassembly.View in project binnavi by google.
the class PathFinder method createPath.
/**
* Creates a view that shows all possible paths between two blocks of a module.
*
* @param module The module for which the view is created.
* @param startBlock The basic block where the path begins (must be null if startFunction is not
* null).
* @param targetBlock The basic block where the path ends (must be null if targetFunction is not
* null).
* @param startFunction The function where the path starts (must be null if startBlock is not
* null).
* @param targetFunction The function where the path ends (must be null if targetBlock is not
* null).
*
* @return The view that contains all possible paths between the start block and the target block.
*
* @throws CouldntLoadDataException
* @throws PartialLoadException
* @throws IllegalArgumentException
*/
public static View createPath(final Module module, final BasicBlock startBlock, final BasicBlock targetBlock, final Function startFunction, final Function targetFunction) throws CouldntLoadDataException, PartialLoadException {
Preconditions.checkNotNull(module, "Error: Module argument can't be null");
Preconditions.checkArgument(module.isLoaded(), "Error: Module is not loaded");
if ((startBlock == null) && (startFunction == null)) {
throw new IllegalArgumentException("Error: No valid start given");
}
if ((targetBlock == null) && (targetFunction == null)) {
throw new IllegalArgumentException("Error: No valid target given");
}
if ((startFunction != null) && !startFunction.isLoaded()) {
throw new IllegalArgumentException("Error: Start function is not loaded");
}
if ((targetFunction != null) && !targetFunction.isLoaded()) {
throw new IllegalArgumentException("Error: Target function is not loaded");
}
// The algorithm works like this:
//
// 1. Find all functions that lie between the start function and the target function.
// 2. Insert all of these functions into the new view.
// 3. Connect the individual functions at function calls and split code nodes if necessary.
// 4. Determine what nodes are actually on the path by taking the successors of the start
// node and set-unioning those with the predecessors of the target node.
// 5. Delete all the nodes which are not on the path.
// At first we determine the function where the path starts and the function where the path
// ends.
final Function realStartFunction = startFunction != null ? startFunction : startBlock.getParentFunction();
final Function realTargetFunction = targetFunction != null ? targetFunction : targetBlock.getParentFunction();
if (realStartFunction.getGraph().nodeCount() == 0) {
throw new IllegalArgumentException("Error: Functions with zero nodes can not be used for pathfinding");
}
// Determine the real start and end blocks of the path with the help of the function flow graphs
final BasicBlock realStartBlock = startBlock != null ? startBlock : findEntryNode(realStartFunction);
final BasicBlock realTargetBlock = targetBlock != null ? targetBlock : findEntryNode(realTargetFunction);
// Find out what functions are called on the way between the first block and the second block.
final LinkedHashSet<FunctionBlock> passedFunctions = findPassedFunctions(module.getCallgraph(), realStartFunction, realTargetFunction);
// Create the view that represents the calculated path
final String endAddress = realTargetBlock != null ? realTargetBlock.getAddress().toHexString() : realTargetFunction.getAddress().toHexString();
final View view = module.createView("New Pathfinder View", String.format("%s -> %s", realStartBlock.getAddress().toHexString(), endAddress));
view.load();
// Maps basic blocks of functions to their corresponding node in the new view.
final Map<BasicBlock, ViewNode> nodeMap = new HashMap<BasicBlock, ViewNode>();
// Keeps track of the entry nodes for each function,
final Map<Function, ViewNode> entryNodes = new HashMap<Function, ViewNode>();
// Keeps track of the exit nodes for each function,
final ArrayListMultimap<Function, ViewNode> exitNodes = ArrayListMultimap.create();
// Keeps track of the function a view node belongs to.
// TODO (timkornau): This should actually be accessible from the plug in API.
final Map<ViewNode, Function> functionMap = new HashMap<ViewNode, Function>();
// Create a code node for all basic blocks of the passed functions.
createInitialBlocks(view, passedFunctions, nodeMap, functionMap);
// Create view edges for all edges in the passed functions.
createInitialEdges(view, passedFunctions, nodeMap);
// Find the entry and exit nodes for all passed functions.
findEntryExitNodes(passedFunctions, nodeMap, functionMap, entryNodes, exitNodes);
ViewNode startNode = nodeMap.get(realStartBlock);
ViewNode targetNode = realTargetBlock == null ? entryNodes.get(realTargetFunction) : nodeMap.get(realTargetBlock);
startNode.setColor(Color.GREEN);
targetNode.setColor(Color.YELLOW);
// Connect the nodes of the different functions on function calls.
final NodePair splitResult = connectFunctions(view, startNode, targetNode, passedFunctions, entryNodes, exitNodes, functionMap);
startNode = splitResult.getFirst();
targetNode = splitResult.getSecond();
// all paths end here.
for (final ViewEdge edge : targetNode.getOutgoingEdges()) {
view.deleteEdge(edge);
}
// Delete all nodes that are not on the path.
deleteNodesNotOnPath(view, startNode, targetNode);
if (startNode.getOutgoingEdges().isEmpty()) {
// no path exists between the two nodes
return null;
}
try {
view.save();
} catch (final CouldntSaveDataException exception) {
CUtilityFunctions.logException(exception);
}
return view;
}
use of com.google.security.zynamics.binnavi.API.disassembly.View in project binnavi by google.
the class OutputGraphGenerator method createCompleteView.
/**
* 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 createCompleteView(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 Module module : target.getModules()) {
for (final Function function : module.getFunctions()) {
final FunctionNode node = view.createFunctionNode(function);
nodes.put(function, node);
}
final Callgraph callgraph = module.getCallgraph();
for (final FunctionEdge edge : callgraph.getEdges()) {
final FunctionNode sourceNode = nodes.get(edge.getSource().getFunction());
final FunctionNode targetNode = nodes.get(edge.getTarget().getFunction());
view.createEdge(sourceNode, targetNode, EdgeType.JumpUnconditional);
}
}
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);
final FunctionNode sourceNode = nodes.get(call.getFunction());
if (sourceNode != null) {
for (final ResolvedFunction targetFunction : targets) {
final Function function = targetFunction.getFunction();
if (function != null) {
final FunctionNode targetNode = nodes.get(function);
final ViewEdge edge = view.createEdge(sourceNode, targetNode, EdgeType.JumpUnconditional);
edge.setColor(Color.RED);
}
}
}
}
return view;
}
use of com.google.security.zynamics.binnavi.API.disassembly.View 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;
}
use of com.google.security.zynamics.binnavi.API.disassembly.View in project binnavi by google.
the class BreakpointHelpersTest method setUp.
@Before
public void setUp() throws DebugExceptionWrapper, CouldntLoadDataException, LoadCancelledException, FileReadException {
ConfigManager.instance().read();
final CDatabase database = new CDatabase("", "", "", "", "", "", "", false, false);
final Database apiDatabase = new Database(database);
final SQLProvider mockProvider = new MockSqlProvider();
final ITreeNode<CTag> nodeRootNode = new TreeNode<CTag>(new CTag(0, "", "", TagType.NODE_TAG, mockProvider));
final Tree<CTag> nodeTagTree = new Tree<CTag>(nodeRootNode);
final TagManager nodeTagManager = new TagManager(new CTagManager(nodeTagTree, TagType.NODE_TAG, mockProvider));
final ITreeNode<CTag> viewRootNode = new TreeNode<CTag>(new CTag(0, "", "", TagType.VIEW_TAG, mockProvider));
final Tree<CTag> viewTagTree = new Tree<CTag>(viewRootNode);
final TagManager viewTagManager = new TagManager(new CTagManager(viewTagTree, TagType.VIEW_TAG, mockProvider));
m_module = new CModule(1, "", "", new Date(), new Date(), "00000000000000000000000000000000", "0000000000000000000000000000000000000000", 0, 0, new CAddress(0), new CAddress(0), null, null, Integer.MAX_VALUE, false, mockProvider);
m_module.load();
m_mockDebugger = new MockDebugger(m_moduleDebugSettings);
m_mockDebugger.connect();
m_debugger = new Debugger(m_mockDebugger);
final INaviFunction parentFunction = m_module.getContent().getFunctionContainer().getFunctions().get(0);
m_mockDebugger.setAddressTranslator(m_module, new CAddress(0), new CAddress(0x1000));
final ViewContainer viewContainer = new Module(apiDatabase, m_module, nodeTagManager, viewTagManager);
final INaviView naviView = new MockView(mockProvider);
final Function apiFunction = new Function(ModuleFactory.get(), parentFunction);
final COperandTreeNode rootNode1 = new COperandTreeNode(1, IOperandTree.NODE_TYPE_REGISTER_ID, "eax", null, new ArrayList<IReference>(), mockProvider, m_module.getTypeManager(), m_module.getContent().getTypeInstanceContainer());
final COperandTreeNode rootNode2 = new COperandTreeNode(1, IOperandTree.NODE_TYPE_REGISTER_ID, "ebx", null, new ArrayList<IReference>(), mockProvider, m_module.getTypeManager(), m_module.getContent().getTypeInstanceContainer());
final COperandTree operand1 = new COperandTree(rootNode1, mockProvider, m_module.getTypeManager(), m_module.getContent().getTypeInstanceContainer());
final COperandTree operand2 = new COperandTree(rootNode2, mockProvider, m_module.getTypeManager(), m_module.getContent().getTypeInstanceContainer());
final List<COperandTree> operands = Lists.newArrayList(operand1, operand2);
final CInstruction internalInstruction = new CInstruction(true, m_module, new CAddress(0x1234), "mov", operands, new byte[] { 1, 2, 3 }, "x86-32", mockProvider);
m_view = new View(viewContainer, naviView, nodeTagManager, viewTagManager);
m_node = m_view.createCodeNode(apiFunction, Lists.newArrayList(new Instruction(internalInstruction)));
setM_functionNode(m_view.createFunctionNode(apiFunction));
}
use of com.google.security.zynamics.binnavi.API.disassembly.View in project binnavi by google.
the class PathFinderTest method testRegularFunction.
@Test
public void testRegularFunction() throws CouldntLoadDataException, PartialLoadException {
// Tests pathfinding between two simple functions
// 0x1004565
// 0x1003CD7
final Function startFunction = findFunction(m_notepad, 0x1004565);
final BasicBlock startBlock = findBlock(startFunction, 0x1004629);
final Function endFunction = findFunction(m_notepad, 0x1003C92);
final BasicBlock endBlock = findBlock(endFunction, 0x1003CD7);
final View view = PathFinder.createPath(m_notepad, startBlock, endBlock, null, null);
assertEquals(7, view.getGraph().nodeCount());
assertEquals(8, view.getGraph().edgeCount());
}
Aggregations