From 0e73aadf4e787df9e376108eb82e297626045b11 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Wed, 13 Mar 2019 11:26:05 -0400 Subject: Initial example triage UI plugin --- python/examples/triage/entropy.py | 91 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 python/examples/triage/entropy.py (limited to 'python/examples/triage/entropy.py') diff --git a/python/examples/triage/entropy.py b/python/examples/triage/entropy.py new file mode 100644 index 00000000..03249968 --- /dev/null +++ b/python/examples/triage/entropy.py @@ -0,0 +1,91 @@ +import math +import threading +from PySide2.QtWidgets import QWidget +from PySide2.QtGui import QImage, QColor, QPainter +from PySide2.QtCore import Qt, QSize, QTimer +from binaryninjaui import ViewFrame + + +class EntropyThread(threading.Thread): + def __init__(self, data, image, block_size): + super(EntropyThread, self).__init__() + self.data = data + self.image = image + self.block_size = block_size + self.updated = False + + def run(self): + width = self.image.width() + for i in range(0, width): + block = self.data.read(self.data.start + i * self.block_size, self.block_size) + if len(block) == 0: + v = 0 + else: + dist = [0] * 0x100 + for j in range(0, len(block)): + value = ord(block[j:j+1]) + dist[value] += 1 + s = 0 + for j in range(0, 256): + if dist[j] != 0: + s += (float(dist[j]) / len(block)) * math.log(float(dist[j]) / len(block)) + s = s / math.log(1 / 256.0) + v = int(s * 255) + if v >= 240: + self.image.setPixelColor(i, 0, QColor(v, v, v / 4, 255)) + else: + self.image.setPixelColor(i, 0, QColor(v / 4, v / 4, v, 255)) + self.updated = True + + +class EntropyWidget(QWidget): + def __init__(self, parent, data): + super(EntropyWidget, self).__init__(parent) + self.data = data + self.raw_data = data.file.raw + + self.block_size = 1024 + self.width = int(len(self.raw_data) / self.block_size) + self.image = QImage(self.width, 1, QImage.Format_ARGB32) + self.image.fill(QColor(0, 0, 0, 0)) + + self.thread = EntropyThread(self.raw_data, self.image, self.block_size) + self.started = False + + self.timer = QTimer() + self.timer.timeout.connect(self.timerEvent) + self.timer.setInterval(250) + self.timer.setSingleShot(False) + self.timer.start() + + self.setMinimumHeight(32) + + def paintEvent(self, event): + p = QPainter(self) + p.drawImage(self.rect(), self.image) + p.drawRect(self.rect()) + + def sizeHint(self): + return QSize(640, 32) + + def timerEvent(self): + if not self.started: + self.thread.start() + self.started = True + if self.thread.updated: + self.thread.updated = False + self.update() + + def mousePressEvent(self, event): + if event.button() != Qt.LeftButton: + return + frac = float(event.x()) / self.rect().width() + offset = int(frac * self.width * self.block_size) + 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) -- cgit v1.3.1