From bdaf3e65c7ea19da175656a02e8d16af5f13becc Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Fri, 15 Mar 2019 15:48:41 -0400 Subject: Updated triage example --- python/examples/triage/view.py | 136 ++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 22 deletions(-) (limited to 'python/examples/triage/view.py') diff --git a/python/examples/triage/view.py b/python/examples/triage/view.py index e06776ca..863ae045 100644 --- a/python/examples/triage/view.py +++ b/python/examples/triage/view.py @@ -2,11 +2,15 @@ import traceback import binaryninjaui from binaryninja.settings import Settings from binaryninja import log -from binaryninjaui import View, ViewType, UIContext -from PySide2.QtWidgets import QScrollArea, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QGroupBox +from binaryninjaui import View, ViewType, UIContext, ViewFrame +from PySide2.QtWidgets import QScrollArea, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QGroupBox, QSplitter +from PySide2.QtCore import Qt from . import headers from . import entropy from . import imports +from . import exports +from . import sections +from . import byte class TriageView(QScrollArea, View): @@ -16,13 +20,15 @@ class TriageView(QScrollArea, View): self.setupView(self) self.data = data self.currentOffset = 0 + self.byteView = None + self.fullAnalysisButton = None container = QWidget(self) layout = QVBoxLayout() entropyGroup = QGroupBox("Entropy") entropyLayout = QVBoxLayout() - entropyLayout.addWidget(entropy.EntropyWidget(entropyGroup, self.data)) + entropyLayout.addWidget(entropy.EntropyWidget(entropyGroup, self, self.data)) entropyGroup.setLayout(entropyLayout) layout.addWidget(entropyGroup) @@ -30,6 +36,8 @@ class TriageView(QScrollArea, View): try: if self.data.view_type == "PE": hdr = headers.PEHeaders(self.data) + elif self.data.view_type != "Raw": + hdr = headers.GenericHeaders(self.data) except: log.log_error(traceback.format_exc()) @@ -41,33 +49,73 @@ class TriageView(QScrollArea, View): headerGroup.setLayout(headerLayout) layout.addWidget(headerGroup) - importGroup = QGroupBox("Imports") - importLayout = QVBoxLayout() - importLayout.addWidget(imports.ImportsWidget(importGroup, self, self.data)) - importGroup.setLayout(importLayout) - layout.addWidget(importGroup) + if self.data.executable: + importExportSplitter = QSplitter(Qt.Horizontal) + + importGroup = QGroupBox("Imports") + importLayout = QVBoxLayout() + importLayout.addWidget(imports.ImportsWidget(importGroup, self, self.data)) + importGroup.setLayout(importLayout) + importExportSplitter.addWidget(importGroup) + + exportGroup = QGroupBox("Exports") + exportLayout = QVBoxLayout() + exportLayout.addWidget(exports.ExportsWidget(exportGroup, self, self.data)) + exportGroup.setLayout(exportLayout) + importExportSplitter.addWidget(exportGroup) + + layout.addWidget(importExportSplitter) + + if self.data.view_type != "PE": + segmentsGroup = QGroupBox("Segments") + segmentsLayout = QVBoxLayout() + segmentsWidget = sections.SegmentsWidget(segmentsGroup, self.data) + segmentsLayout.addWidget(segmentsWidget) + segmentsGroup.setLayout(segmentsLayout) + layout.addWidget(segmentsGroup) + if len(segmentsWidget.segments) == 0: + segmentsGroup.hide() + + sectionsGroup = QGroupBox("Sections") + sectionsLayout = QVBoxLayout() + sectionsWidget = sections.SectionsWidget(sectionsGroup, self.data) + sectionsLayout.addWidget(sectionsWidget) + sectionsGroup.setLayout(sectionsLayout) + layout.addWidget(sectionsGroup) + if len(sectionsWidget.sections) == 0: + sectionsGroup.hide() + + buttonLayout = QHBoxLayout() + buttonLayout.addStretch(1) + self.fullAnalysisButton = QPushButton("Start Full Analysis") + self.fullAnalysisButton.clicked.connect(self.startFullAnalysis) + buttonLayout.addWidget(self.fullAnalysisButton) + layout.addLayout(buttonLayout) + layout.addStretch(1) + else: + self.byteView = byte.ByteView(self, self.data) + layout.addWidget(self.byteView, 1) - button_layout = QHBoxLayout() - button_layout.addStretch(1) - self.full_analysis_button = QPushButton("Start Full Analysis") - self.full_analysis_button.clicked.connect(self.startFullAnalysis) - button_layout.addWidget(self.full_analysis_button) - layout.addLayout(button_layout) - - layout.addStretch(1) container.setLayout(layout) self.setWidgetResizable(True) self.setWidget(container) - if Settings().get_string("analysis.mode", data) == "full": - self.full_analysis_button.hide() + if self.fullAnalysisButton is not None and Settings().get_string("analysis.mode", data) == "full": + self.fullAnalysisButton.hide() def getData(self): return self.data def getCurrentOffset(self): + if self.byteView is not None: + return self.byteView.getCurrentOffset() return self.currentOffset + def getSelectionOffsets(self): + if self.byteView is not None: + return self.byteView.getSelectionOffsets() + return (self.currentOffset, self.currentOffset) + def setCurrentOffset(self, offset): self.currentOffset = offset UIContext.updateStatus(True) @@ -76,6 +124,8 @@ class TriageView(QScrollArea, View): return binaryninjaui.getMonospaceFont(self) def navigate(self, addr): + if self.byteView is not None: + return self.navigate(addr) return False def startFullAnalysis(self): @@ -84,7 +134,34 @@ class TriageView(QScrollArea, View): if f.analysis_skipped: f.reanalyze() self.data.update_analysis() - self.full_analysis_button.hide() + self.fullAnalysisButton.hide() + + def navigateToFileOffset(self, offset): + if self.byteView is None: + addr = self.data.get_address_for_data_offset(offset) + view_frame = ViewFrame.viewFrameForWidget(self) + if view_frame is None: + return + if addr is None: + view_frame.navigate("Hex:Raw", offset) + else: + view_frame.navigate("Linear:" + view_frame.getCurrentDataType(), addr) + else: + if self.data == self.data.file.raw: + addr = offset + else: + addr = self.data.get_address_for_data_offset(offset) + if addr is None: + view_frame = ViewFrame.viewFrameForWidget(self) + if view_frame is not None: + view_frame.navigate("Hex:Raw", offset) + else: + self.byteView.navigate(addr) + self.byteView.setFocus(Qt.OtherFocusReason) + + def focusInEvent(self, event): + if self.byteView is not None: + self.byteView.setFocus(Qt.OtherFocusReason) class TriageViewType(ViewType): @@ -93,16 +170,22 @@ class TriageViewType(ViewType): def getPriority(self, data, filename): is_full = Settings().get_string("analysis.mode", data) == "full" - always_prefer = Settings().get_bool("ui.always_prefer_triage", data) + always_prefer = Settings().get_bool("triage.always_prefer", data) + prefer_for_raw = Settings().get_bool("triage.prefer_for_raw", data) if data.executable and (always_prefer or not is_full): return 100 - return 25 + if len(data) > 0: + if always_prefer or data.executable or prefer_for_raw: + return 25 + return 1 + return 0 def create(self, data, view_frame): return TriageView(view_frame, data) -Settings().register_setting("ui.always_prefer_triage", """ +Settings().register_group("triage", "Triage") +Settings().register_setting("triage.always_prefer", """ { "title" : "Always Prefer Triage Summary View", "type" : "boolean", @@ -111,4 +194,13 @@ Settings().register_setting("ui.always_prefer_triage", """ } """) +Settings().register_setting("triage.prefer_for_raw", """ + { + "title" : "Prefer Triage Summary View for Raw Files", + "type" : "boolean", + "default" : true, + "description" : "Prefer opening raw files in Triage Summary view." + } + """) + ViewType.registerViewType(TriageViewType()) -- cgit v1.3.1