summaryrefslogtreecommitdiff
path: root/examples/triage/view.cpp
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2019-04-02 15:30:45 -0400
committerRusty Wagner <rusty@vector35.com>2019-04-02 15:36:40 -0400
commit73a9399f5d1d86c7e291498b7fe836550f2f76ab (patch)
treee7c7cfe9a2f27a93ddac41cf600e7bc1fc638a83 /examples/triage/view.cpp
parentc17af471c48ea092434917c803f9c88fe91022a6 (diff)
Add a C++ version of the triage plugin (no Makefile yet)
Diffstat (limited to 'examples/triage/view.cpp')
-rw-r--r--examples/triage/view.cpp241
1 files changed, 241 insertions, 0 deletions
diff --git a/examples/triage/view.cpp b/examples/triage/view.cpp
new file mode 100644
index 00000000..73e036a5
--- /dev/null
+++ b/examples/triage/view.cpp
@@ -0,0 +1,241 @@
+#include <QtWidgets/QGroupBox>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QSplitter>
+#include "view.h"
+#include "entropy.h"
+#include "imports.h"
+#include "exports.h"
+#include "sections.h"
+#include "headers.h"
+#include "fontsettings.h"
+
+
+TriageView::TriageView(QWidget* parent, BinaryViewRef data): QScrollArea(parent)
+{
+ setupView(this);
+ m_data = data;
+
+ QWidget* container = new QWidget(this);
+ QVBoxLayout* layout = new QVBoxLayout();
+
+ QGroupBox* entropyGroup = new QGroupBox("Entropy", container);
+ QVBoxLayout* entropyLayout = new QVBoxLayout();
+ entropyLayout->addWidget(new EntropyWidget(entropyGroup, this, m_data));
+ entropyGroup->setLayout(entropyLayout);
+ layout->addWidget(entropyGroup);
+
+ Headers* hdr = nullptr;
+ if (m_data->GetTypeName() == "PE")
+ hdr = new PEHeaders(m_data);
+ else if (m_data->GetTypeName() != "Raw")
+ hdr = new GenericHeaders(m_data);
+
+ if (hdr)
+ {
+ QGroupBox* headerGroup = new QGroupBox("Headers", container);
+ QVBoxLayout* headerLayout = new QVBoxLayout();
+ HeaderWidget* headerWidget = new HeaderWidget(headerGroup, *hdr);
+ headerLayout->addWidget(headerWidget);
+ headerGroup->setLayout(headerLayout);
+ layout->addWidget(headerGroup);
+ delete hdr;
+ }
+
+ if (m_data->IsExecutable())
+ {
+ QSplitter* importExportSplitter = new QSplitter(Qt::Horizontal);
+
+ QGroupBox* importGroup = new QGroupBox("Imports", container);
+ QVBoxLayout* importLayout = new QVBoxLayout();
+ importLayout->addWidget(new ImportsWidget(importGroup, this, m_data));
+ importGroup->setLayout(importLayout);
+ importExportSplitter->addWidget(importGroup);
+
+ QGroupBox* exportGroup = new QGroupBox("Exports", container);
+ QVBoxLayout* exportLayout = new QVBoxLayout();
+ exportLayout->addWidget(new ExportsWidget(exportGroup, this, m_data));
+ exportGroup->setLayout(exportLayout);
+ importExportSplitter->addWidget(exportGroup);
+
+ layout->addWidget(importExportSplitter);
+
+ if (m_data->GetTypeName() != "PE")
+ {
+ QGroupBox* segmentsGroup = new QGroupBox("Segments", container);
+ QVBoxLayout* segmentsLayout = new QVBoxLayout();
+ SegmentsWidget* segmentsWidget = new SegmentsWidget(segmentsGroup, m_data);
+ segmentsLayout->addWidget(segmentsWidget);
+ segmentsGroup->setLayout(segmentsLayout);
+ layout->addWidget(segmentsGroup);
+ if (segmentsWidget->GetSegments().size() == 0)
+ segmentsGroup->hide();
+ }
+
+ QGroupBox* sectionsGroup = new QGroupBox("Sections", container);
+ QVBoxLayout* sectionsLayout = new QVBoxLayout();
+ SectionsWidget* sectionsWidget = new SectionsWidget(sectionsGroup, m_data);
+ sectionsLayout->addWidget(sectionsWidget);
+ sectionsGroup->setLayout(sectionsLayout);
+ layout->addWidget(sectionsGroup);
+ if (sectionsWidget->GetSections().size() == 0)
+ sectionsGroup->hide();
+
+ QHBoxLayout* buttonLayout = new QHBoxLayout();
+ buttonLayout->addStretch(1);
+ m_fullAnalysisButton = new QPushButton("Start Full Analysis");
+ connect(m_fullAnalysisButton, &QPushButton::clicked, this, &TriageView::startFullAnalysis);
+ buttonLayout->addWidget(m_fullAnalysisButton);
+ layout->addLayout(buttonLayout);
+ layout->addStretch(1);
+ }
+ else
+ {
+ m_byteView = new ByteView(this, m_data);
+ setBinaryDataNavigable(true);
+ layout->addWidget(m_byteView, 1);
+ }
+
+ container->setLayout(layout);
+ setWidgetResizable(true);
+ setWidget(container);
+
+ if (m_fullAnalysisButton && (BinaryNinja::Settings().Get<std::string>("analysis.mode", data) == "full"))
+ m_fullAnalysisButton->hide();
+}
+
+
+BinaryViewRef TriageView::getData()
+{
+ return m_data;
+}
+
+
+uint64_t TriageView::getCurrentOffset()
+{
+ if (m_byteView)
+ return m_byteView->getCurrentOffset();
+ return m_currentOffset;
+}
+
+
+void TriageView::getSelectionOffsets(uint64_t& begin, uint64_t& end)
+{
+ if (m_byteView)
+ {
+ m_byteView->getSelectionOffsets(begin, end);
+ return;
+ }
+ begin = m_currentOffset;
+ end = m_currentOffset;
+}
+
+
+void TriageView::setCurrentOffset(uint64_t offset)
+{
+ m_currentOffset = offset;
+ UIContext::updateStatus(true);
+}
+
+
+QFont TriageView::getFont()
+{
+ return getMonospaceFont(this);
+}
+
+
+bool TriageView::navigate(uint64_t addr)
+{
+ if (m_byteView)
+ return m_byteView->navigate(addr);
+ return false;
+}
+
+
+void TriageView::startFullAnalysis()
+{
+ BinaryNinja::Settings().Set("analysis.mode", "full", m_data);
+ for (auto& f: m_data->GetAnalysisFunctionList())
+ {
+ if (f->IsAnalysisSkipped())
+ f->Reanalyze();
+ }
+ m_data->UpdateAnalysis();
+ m_fullAnalysisButton->hide();
+}
+
+
+void TriageView::navigateToFileOffset(uint64_t offset)
+{
+ if (!m_byteView)
+ {
+ uint64_t addr = 0;
+ bool hasAddr = m_data->GetAddressForDataOffset(offset, addr);
+ ViewFrame* frame = ViewFrame::viewFrameForWidget(this);
+ if (!frame)
+ return;
+ if (!hasAddr)
+ frame->navigate("Hex:Raw", offset);
+ else
+ frame->navigate("Linear:" + frame->getCurrentDataType(), addr);
+ }
+ else
+ {
+ uint64_t addr;
+ bool hasAddr;
+ if (m_data == m_data->GetFile()->GetViewOfType("Raw"))
+ {
+ addr = offset;
+ hasAddr = true;
+ }
+ else
+ {
+ hasAddr = m_data->GetAddressForDataOffset(offset, addr);
+ }
+ if (!hasAddr)
+ {
+ ViewFrame* frame = ViewFrame::viewFrameForWidget(this);
+ if (frame)
+ frame->navigate("Hex:Raw", offset);
+ }
+ else
+ {
+ m_byteView->navigate(addr);
+ m_byteView->setFocus(Qt::OtherFocusReason);
+ }
+ }
+}
+
+
+void TriageView::focusInEvent(QFocusEvent*)
+{
+ if (m_byteView)
+ m_byteView->setFocus(Qt::OtherFocusReason);
+}
+
+
+TriageViewType::TriageViewType(): ViewType("Triage", "Triage Summary")
+{
+}
+
+
+int TriageViewType::getPriority(BinaryViewRef data, const QString&)
+{
+ bool full = BinaryNinja::Settings().Get<std::string>("analysis.mode", data) == "full";
+ bool alwaysPrefer = BinaryNinja::Settings().Get<bool>("triage.always_prefer", data);
+ bool preferForRaw = BinaryNinja::Settings().Get<bool>("triage.prefer_for_raw", data);
+ if (data->IsExecutable() && (alwaysPrefer || !full))
+ return 100;
+ if (data->GetLength() > 0)
+ {
+ if (alwaysPrefer || data->IsExecutable() || preferForRaw)
+ return 25;
+ return 1;
+ }
+ return 0;
+}
+
+
+QWidget* TriageViewType::create(BinaryViewRef data, ViewFrame* frame)
+{
+ return new TriageView(frame, data);
+}