summaryrefslogtreecommitdiff
path: root/python/examples/triage/files.py
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2019-03-15 15:48:41 -0400
committerRusty Wagner <rusty@vector35.com>2019-03-20 13:00:17 -0400
commitbdaf3e65c7ea19da175656a02e8d16af5f13becc (patch)
tree21c260ea11de825dcfb12723956cdc17efb08902 /python/examples/triage/files.py
parent7957fa580eb5f85bc2ce1deb7933f3b6db47a886 (diff)
Updated triage example
Diffstat (limited to 'python/examples/triage/files.py')
-rw-r--r--python/examples/triage/files.py140
1 files changed, 140 insertions, 0 deletions
diff --git a/python/examples/triage/files.py b/python/examples/triage/files.py
new file mode 100644
index 00000000..333bcf5a
--- /dev/null
+++ b/python/examples/triage/files.py
@@ -0,0 +1,140 @@
+import os
+from PySide2.QtWidgets import QWidget, QTreeView, QFileSystemModel, QVBoxLayout, QMessageBox, QAbstractItemView
+from PySide2.QtGui import QKeySequence
+from PySide2.QtCore import QSettings
+from binaryninjaui import UIActionHandler, UIAction, Menu, FileContext, ContextMenuManager
+from binaryninja.settings import Settings
+
+
+class TriageFilePicker(QWidget):
+ def __init__(self, context):
+ super(TriageFilePicker, self).__init__()
+ self.context = context
+ self.actionHandler = UIActionHandler()
+ self.actionHandler.setupActionHandler(self)
+ self.contextMenu = Menu()
+ self.contextMenuManager = ContextMenuManager(self)
+
+ layout = QVBoxLayout()
+ layout.setContentsMargins(0, 0, 0, 0)
+
+ self.model = QFileSystemModel()
+ self.model.setRootPath("")
+ self.tree = QTreeView(self)
+ self.tree.setModel(self.model)
+ self.tree.setSelectionMode(QAbstractItemView.ExtendedSelection)
+ self.tree.setColumnWidth(0, 500)
+ layout.addWidget(self.tree, 1)
+
+ self.setLayout(layout)
+
+ self.tree.doubleClicked.connect(self.onDoubleClick)
+
+ recentFile = QSettings().value("triage/recentFile", os.path.expanduser("~"))
+ while len(recentFile) > 0:
+ f = self.model.index(recentFile)
+ if f.isValid():
+ self.tree.scrollTo(f)
+ self.tree.setExpanded(f, True)
+ break
+ parentDir = os.path.dirname(recentFile)
+ if parentDir == recentFile:
+ break
+ recentFile = parentDir
+
+ self.actionHandler.bindAction("Open Selected Files", UIAction(
+ lambda context: self.openSelectedFiles(),
+ lambda context: self.areFilesSelected()))
+ self.contextMenu.addAction("Open Selected Files", "Open")
+
+ def contextMenuEvent(self, event):
+ self.contextMenuManager.show(self.contextMenu, self.actionHandler)
+
+ def onDoubleClick(self, index):
+ self.openSelectedFiles()
+
+ def openSelectedFiles(self):
+ failedToOpen = []
+ files = set()
+
+ for index in self.tree.selectionModel().selectedIndexes():
+ if self.model.fileInfo(index).isFile():
+ files.add(self.model.fileInfo(index).absoluteFilePath())
+
+ for filename in files:
+ QSettings().setValue("triage/recentFile", filename)
+
+ f = FileContext.openFilename(filename)
+ if not f:
+ failedToOpen.append(filename)
+ continue
+
+ f.createBinaryViews()
+ for data in f.getAllDataViews():
+ Settings().set_string("analysis.mode", Settings().get_string("triage.analysis_mode"), data)
+ Settings().set_bool("triage.always_prefer", True, data)
+ if data.view_type != "Raw":
+ linearSweepMode = Settings().get_string("triage.linear_sweep")
+ if linearSweepMode == "none":
+ Settings().set_bool("analysis.linearSweep.autorun", False, data)
+ elif linearSweepMode == "partial":
+ Settings().set_bool("analysis.linearSweep.autorun", True, data)
+ Settings().set_bool("analysis.linearSweep.controlFlowGraph", False, data)
+ elif linearSweepMode == "full":
+ Settings().set_bool("analysis.linearSweep.autorun", True, data)
+ Settings().set_bool("analysis.linearSweep.controlFlowGraph", True, data)
+
+ self.context.openFileContext(f)
+
+ if len(failedToOpen) > 0:
+ QMessageBox.critical(self, "Error", "Unable to open:\n" + "\n".join(failedToOpen))
+
+ def areFilesSelected(self):
+ return self.tree.selectionModel().hasSelection()
+
+
+def openForTriage(context):
+ currentContext = context.context
+ if currentContext is None:
+ return
+
+ # Do not try to set the parent window when creating tabs, as this will create a parent relationship in
+ # the bindings and will cause the widget to be destructed early. The correct parent will be assigned
+ # when createTabForWidget is called.
+ fp = TriageFilePicker(currentContext)
+ currentContext.createTabForWidget("Open for Triage", fp)
+
+
+Settings().register_setting("triage.analysis_mode", """
+ {
+ "title" : "Triage Analysis Mode",
+ "type" : "string",
+ "default" : "basic",
+ "description" : "Controls the amount of analysis performed on functions when opening for triage.",
+ "enum" : ["controlFlow", "basic", "full"],
+ "enumDescriptions" : [
+ "Only perform control flow analysis on the binary. Cross references are valid only for direct function calls.",
+ "Perform fast initial analysis of the binary. This mode does not analyze types or data flow through stack variables.",
+ "Perform full analysis of the binary." ]
+ }
+ """)
+
+Settings().register_setting("triage.linear_sweep", """
+ {
+ "title" : "Triage Linear Sweep Mode",
+ "type" : "string",
+ "default" : "partial",
+ "description" : "Controls the level of linear sweep performed when opening for triage.",
+ "enum" : ["none", "partial", "full"],
+ "enumDescriptions" : [
+ "Do not perform linear sweep of the binary.",
+ "Perform linear sweep on the binary, but skip the control flow graph analysis phase.",
+ "Perform full linear sweep on the binary." ]
+ }
+ """)
+
+UIAction.registerAction("Open for Triage...", QKeySequence("Ctrl+Alt+O"))
+UIAction.registerAction("Open Selected Files")
+
+UIActionHandler.globalActions().bindAction("Open for Triage...", UIAction(openForTriage))
+Menu.mainMenu("File").addAction("Open for Triage...", "Open")