Skip to content

Commit 09b1b51

Browse files
committed
Registered sidebar widget with Binja
Also started the extraction and blob signature id widgets
1 parent dbb6658 commit 09b1b51

File tree

3 files changed

+154
-5
lines changed

3 files changed

+154
-5
lines changed

__init__.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
from binaryninja import *
1+
"""Binary Ninja plugin for identifying and extracting files from container formats using Unblob
2+
"""
23

3-
def do_nothing(bv):
4-
show_message_box("Do Nothing", "Congratulations! You have successfully done nothing.\n\n" +
5-
"Pat yourself on the back.", MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon)
4+
from binaryninja import core_ui_enabled
5+
from binaryninjaui import Sidebar
66

7-
PluginCommand.register("Useless Plugin", "Basically does nothing", do_nothing)
7+
from .sidebar import BlobExtractorSidebarType
8+
9+
if core_ui_enabled() is True:
10+
Sidebar.addSidebarWidgetType(BlobExtractorSidebarType())

icon.png

12.8 KB
Loading

sidebar.py

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
"""Blob Extractor sidebar user interface
2+
"""
3+
4+
from os import path
5+
from PySide6.QtCore import Qt
6+
from PySide6.QtWidgets import QVBoxLayout, QLabel, QWidget, QGridLayout, QFrame, QPushButton
7+
from PySide6.QtGui import QImage
8+
from binaryninja import BinaryView
9+
from binaryninjaui import (
10+
SidebarWidget,
11+
SidebarWidgetType,
12+
ViewFrame,
13+
SidebarWidgetLocation,
14+
SidebarContextSensitivity,
15+
getThemeColor,
16+
ThemeColor,
17+
)
18+
19+
# Use Qt conventions for variable and function names
20+
# pylint: disable=C0103
21+
22+
23+
class StatusLabel(QLabel):
24+
"""Styled label for status messages"""
25+
26+
def __init__(self, text: str, parent=None) -> None:
27+
super(StatusLabel, self).__init__(parent)
28+
color = getThemeColor(ThemeColor.AlphanumericHighlightColor)
29+
self.setStyleSheet(f"color: {color.name()}")
30+
self.setText(text)
31+
self.setAlignment(Qt.AlignTop)
32+
33+
34+
class HeaderLabel(QLabel):
35+
"""Styled label for widget headers"""
36+
37+
def __init__(self, text: str, parent=None) -> None:
38+
super(HeaderLabel, self).__init__(parent)
39+
self.setStyleSheet("font-size: 14px")
40+
self.setText(text)
41+
self.setAlignment(Qt.AlignLeft)
42+
self.setContentsMargins(0, 5, 0, 5)
43+
44+
45+
class ExtractResultsFrame(QFrame):
46+
"""Frame for displaying extraction results"""
47+
48+
def __init__(self, parent=None) -> None:
49+
super(ExtractResultsFrame, self).__init__(parent)
50+
layout = QVBoxLayout()
51+
layout.addWidget(QLabel("Extracted files:"))
52+
self.setLayout(layout)
53+
54+
55+
class ExtractWidget(QWidget):
56+
"""Qt widget for extracting files with unblob"""
57+
58+
def __init__(self, data: BinaryView, parent=None) -> None:
59+
super(ExtractWidget, self).__init__(parent)
60+
self.data = data
61+
self.lastTmpDir = None
62+
self.fileReports = None
63+
self.parents = None
64+
65+
self.extractButton = QPushButton("Extract")
66+
self.statusLabel = StatusLabel("")
67+
self.resultsFrame = ExtractResultsFrame()
68+
self.resultsFrame.hide()
69+
70+
layout = QGridLayout()
71+
layout.setSpacing(0)
72+
layout.setContentsMargins(0, 0, 0, 0)
73+
74+
layout.addWidget(HeaderLabel("Extracted Files"), 0, 0, 1, 5)
75+
layout.addWidget(self.extractButton, 1, 0, Qt.AlignLeft)
76+
layout.addWidget(self.statusLabel, 1, 1, 1, 4, Qt.AlignLeft)
77+
layout.addWidget(self.resultsFrame, 2, 0)
78+
self.setLayout(layout)
79+
80+
81+
class BlobsWidget(QWidget):
82+
"""Qt widget for displaying interesting blobs in the container binary"""
83+
84+
def __init__(self, parent=None) -> None:
85+
super(BlobsWidget, self).__init__(parent)
86+
layout = QGridLayout()
87+
layout.setSpacing(0)
88+
layout.setContentsMargins(0, 0, 0, 0)
89+
90+
self.statusLabel = StatusLabel("")
91+
layout.addWidget(HeaderLabel("Embedded Blobs"), 0, 0, 1, 5)
92+
layout.addWidget(self.statusLabel, 1, 0, 1, 5)
93+
self.setLayout(layout)
94+
95+
96+
class BlobExtractorSidebar(SidebarWidget):
97+
"""Sidebar Qt widget for the Blob Extractor plugin"""
98+
99+
def __init__(self, frame: ViewFrame, data: BinaryView) -> None:
100+
# pylint: disable=W0613
101+
super().__init__("Blob Extractor")
102+
self.data = data
103+
104+
layout = QVBoxLayout()
105+
self.blobWidget = BlobsWidget()
106+
layout.addWidget(self.blobWidget)
107+
self.extractWidget = ExtractWidget(data)
108+
layout.addWidget(self.extractWidget)
109+
self.setLayout(layout)
110+
111+
def notifyViewChanged(self, frame: ViewFrame) -> None:
112+
"""User changed focused to another view"""
113+
114+
if frame is None:
115+
self.data = None
116+
else:
117+
view = frame.getCurrentViewInterface()
118+
self.data = view.getData()
119+
120+
121+
class BlobExtractorSidebarType(SidebarWidgetType):
122+
"""Sidebar widget type for the Blob Extractor plugin"""
123+
124+
def __init__(self):
125+
iconDir = path.dirname(path.abspath(__file__))
126+
iconPath = path.join(iconDir, "icon.png")
127+
with open(iconPath, "rb") as f:
128+
iconData = f.read()
129+
icon = QImage()
130+
icon.loadFromData(iconData)
131+
SidebarWidgetType.__init__(self, icon, "Blob Extractor")
132+
133+
def createWidget(self, frame: ViewFrame, data: BinaryView) -> SidebarWidget:
134+
"""Create the sidebar widget"""
135+
136+
return BlobExtractorSidebar(frame, data)
137+
138+
def defaultLocation(self):
139+
"""Default location for the widget"""
140+
141+
return SidebarWidgetLocation.LeftContent
142+
143+
def contextSensitivity(self):
144+
"""Context sensitivity for the widget"""
145+
146+
return SidebarContextSensitivity.PerViewTypeSidebarContext

0 commit comments

Comments
 (0)