summaryrefslogtreecommitdiff
path: root/python/examples/triage/view.py
blob: e06776ca7a5c7e69a7c1ff29fb5347c5241bd086 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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 . import headers
from . import entropy
from . import imports


class TriageView(QScrollArea, View):
	def __init__(self, parent, data):
		QScrollArea.__init__(self, parent)
		View.__init__(self)
		self.setupView(self)
		self.data = data
		self.currentOffset = 0

		container = QWidget(self)
		layout = QVBoxLayout()

		entropyGroup = QGroupBox("Entropy")
		entropyLayout = QVBoxLayout()
		entropyLayout.addWidget(entropy.EntropyWidget(entropyGroup, self.data))
		entropyGroup.setLayout(entropyLayout)
		layout.addWidget(entropyGroup)

		hdr = None
		try:
			if self.data.view_type == "PE":
				hdr = headers.PEHeaders(self.data)
		except:
			log.log_error(traceback.format_exc())

		if hdr is not None:
			headerGroup = QGroupBox("Headers")
			headerLayout = QVBoxLayout()
			headerWidget = headers.HeaderWidget(headerGroup, hdr)
			headerLayout.addWidget(headerWidget)
			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)

		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()

	def getData(self):
		return self.data

	def getCurrentOffset(self):
		return self.currentOffset

	def setCurrentOffset(self, offset):
		self.currentOffset = offset
		UIContext.updateStatus(True)

	def getFont(self):
		return binaryninjaui.getMonospaceFont(self)

	def navigate(self, addr):
		return False

	def startFullAnalysis(self):
		Settings().set_string("analysis.mode", "full", self.data)
		for f in self.data.functions:
			if f.analysis_skipped:
				f.reanalyze()
		self.data.update_analysis()
		self.full_analysis_button.hide()


class TriageViewType(ViewType):
	def __init__(self):
		super(TriageViewType, self).__init__("Triage", "Triage Summary")

	def getPriority(self, data, filename):
		is_full = Settings().get_string("analysis.mode", data) == "full"
		always_prefer = Settings().get_bool("ui.always_prefer_triage", data)
		if data.executable and (always_prefer or not is_full):
			return 100
		return 25

	def create(self, data, view_frame):
		return TriageView(view_frame, data)


Settings().register_setting("ui.always_prefer_triage", """
	{
		"title" : "Always Prefer Triage Summary View",
		"type" : "boolean",
		"default" : false,
		"description" : "Always prefer opening binaries in Triage Summary view, even when performing full analysis."
	}
	""")

ViewType.registerViewType(TriageViewType())