Skip to content

Commit 0282141

Browse files
committed
update section list in triage when section list changes
1 parent 26e7687 commit 0282141

File tree

2 files changed

+153
-25
lines changed

2 files changed

+153
-25
lines changed

examples/triage/sections.cpp

Lines changed: 119 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,58 @@
11
#include <QtWidgets/QGridLayout>
22
#include <QtWidgets/QHBoxLayout>
3+
#include <QtWidgets/QLabel>
34
#include <algorithm>
45
#include <vector>
56
#include "sections.h"
67
#include "headers.h"
78
#include "fontsettings.h"
89

910

11+
SectionsModel::SectionsModel(QObject* parent, BinaryViewRef data) : QObject(parent), BinaryDataNotification(SectionUpdates)
12+
{
13+
m_data = data;
14+
m_data->RegisterNotification(this);
15+
updateSections();
16+
}
17+
18+
19+
SectionsModel::~SectionsModel()
20+
{
21+
m_data->UnregisterNotification(this);
22+
}
23+
24+
25+
void SectionsModel::updateSections()
26+
{
27+
m_sections.clear();
28+
for (auto& section : m_data->GetSections())
29+
if (section->GetSemantics() != ExternalSectionSemantics)
30+
m_sections.push_back(section);
31+
sort(m_sections.begin(), m_sections.end(),
32+
[&](SectionRef a, SectionRef b) { return a->GetStart() < b->GetStart(); });
33+
34+
emit sectionsChanged();
35+
}
36+
37+
38+
void SectionsModel::OnSectionAdded(BinaryNinja::BinaryView* data, BinaryNinja::Section* section)
39+
{
40+
QMetaObject::invokeMethod(this, &SectionsModel::updateSections, Qt::QueuedConnection);
41+
}
42+
43+
44+
void SectionsModel::OnSectionRemoved(BinaryNinja::BinaryView* data, BinaryNinja::Section* section)
45+
{
46+
QMetaObject::invokeMethod(this, &SectionsModel::updateSections, Qt::QueuedConnection);
47+
}
48+
49+
50+
void SectionsModel::OnSectionUpdated(BinaryNinja::BinaryView* data, BinaryNinja::Section* section)
51+
{
52+
QMetaObject::invokeMethod(this, &SectionsModel::updateSections, Qt::QueuedConnection);
53+
}
54+
55+
1056
SegmentsWidget::SegmentsWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent)
1157
{
1258
QGridLayout* layout = new QGridLayout();
@@ -63,29 +109,77 @@ SegmentsWidget::SegmentsWidget(QWidget* parent, BinaryViewRef data) : QWidget(pa
63109
}
64110

65111

66-
SectionsWidget::SectionsWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent)
112+
SectionsWidget::SectionsWidget(QWidget* parent, BinaryViewRef data) : QWidget(parent), m_data(data), m_model(nullptr), m_layout(nullptr), m_isRebuilding(false)
67113
{
68-
QGridLayout* layout = new QGridLayout();
69-
layout->setContentsMargins(0, 0, 0, 0);
70-
layout->setVerticalSpacing(1);
71-
layout->setHorizontalSpacing(UIContext::getScaledWindowSize(16, 16).width());
114+
m_model = new SectionsModel(this, data);
115+
116+
m_layout = new QGridLayout();
117+
m_layout->setContentsMargins(0, 0, 0, 0);
118+
m_layout->setVerticalSpacing(1);
119+
m_layout->setHorizontalSpacing(UIContext::getScaledWindowSize(16, 16).width());
120+
setLayout(m_layout);
121+
122+
connect(m_model, &SectionsModel::sectionsChanged, this, &SectionsWidget::rebuildLayout, Qt::QueuedConnection);
123+
124+
rebuildLayout();
125+
}
126+
127+
128+
SectionsWidget::~SectionsWidget()
129+
{
130+
if (m_model)
131+
{
132+
disconnect(m_model, nullptr, this, nullptr);
133+
m_model->blockSignals(true);
134+
}
135+
}
136+
137+
138+
void SectionsWidget::rebuildLayout()
139+
{
140+
if (m_isRebuilding)
141+
return;
142+
143+
m_isRebuilding = true;
144+
setUpdatesEnabled(false);
145+
146+
QObjectList children = this->children();
147+
for (QObject* child : children)
148+
{
149+
if (QWidget* widget = qobject_cast<QWidget*>(child))
150+
delete widget;
151+
}
152+
153+
delete m_layout;
154+
155+
m_layout = new QGridLayout();
156+
m_layout->setContentsMargins(0, 0, 0, 0);
157+
m_layout->setVerticalSpacing(1);
158+
m_layout->setHorizontalSpacing(UIContext::getScaledWindowSize(16, 16).width());
159+
setLayout(m_layout);
160+
161+
auto sections = m_model->GetSections();
162+
163+
if (sections.empty())
164+
{
165+
setUpdatesEnabled(true);
166+
m_isRebuilding = false;
167+
return;
168+
}
72169

73170
size_t maxNameLen = 0;
74-
for (auto& section : data->GetSections())
171+
for (auto& section : sections)
172+
{
75173
if (section->GetName().size() > maxNameLen)
76174
maxNameLen = section->GetName().size();
175+
}
77176
if (maxNameLen > 32)
78177
maxNameLen = 32;
79178

80-
for (auto& section : data->GetSections())
81-
if (section->GetSemantics() != ExternalSectionSemantics)
82-
m_sections.push_back(section);
83-
sort(m_sections.begin(), m_sections.end(),
84-
[&](SectionRef a, SectionRef b) { return a->GetStart() < b->GetStart(); });
85-
86179
int row = 0;
87-
for (auto& section : m_sections)
180+
for (auto& section : sections)
88181
{
182+
89183
std::string name = section->GetName();
90184
if (name.size() > maxNameLen)
91185
name = name.substr(0, maxNameLen - 1) + std::string("");
@@ -95,15 +189,15 @@ SectionsWidget::SectionsWidget(QWidget* parent, BinaryViewRef data) : QWidget(pa
95189
QString typeName = QString::fromStdString(section->GetType());
96190

97191
QString permissions;
98-
if (data->IsOffsetReadable(section->GetStart()))
192+
if (m_data->IsOffsetReadable(section->GetStart()))
99193
permissions += "r";
100194
else
101195
permissions += "-";
102-
if (data->IsOffsetWritable(section->GetStart()))
196+
if (m_data->IsOffsetWritable(section->GetStart()))
103197
permissions += "w";
104198
else
105199
permissions += "-";
106-
if (data->IsOffsetExecutable(section->GetStart()))
200+
if (m_data->IsOffsetExecutable(section->GetStart()))
107201
permissions += "x";
108202
else
109203
permissions += "-";
@@ -118,7 +212,7 @@ SectionsWidget::SectionsWidget(QWidget* parent, BinaryViewRef data) : QWidget(pa
118212

119213
QLabel* nameLabel = new QLabel(QString::fromStdString(name));
120214
nameLabel->setFont(getMonospaceFont(this));
121-
layout->addWidget(nameLabel, row, 0);
215+
m_layout->addWidget(nameLabel, row, 0);
122216

123217
QHBoxLayout* rangeLayout = new QHBoxLayout();
124218
rangeLayout->setContentsMargins(0, 0, 0, 0);
@@ -129,21 +223,23 @@ SectionsWidget::SectionsWidget(QWidget* parent, BinaryViewRef data) : QWidget(pa
129223
rangeLayout->addWidget(beginLabel);
130224
rangeLayout->addWidget(dashLabel);
131225
rangeLayout->addWidget(endLabel);
132-
layout->addLayout(rangeLayout, row, 1);
226+
m_layout->addLayout(rangeLayout, row, 1);
133227

134228
QLabel* permissionsLabel = new QLabel(permissions);
135229
permissionsLabel->setFont(getMonospaceFont(this));
136-
layout->addWidget(permissionsLabel, row, 2);
230+
m_layout->addWidget(permissionsLabel, row, 2);
137231
QLabel* typeLabel = new QLabel(typeName);
138232
typeLabel->setFont(getMonospaceFont(this));
139-
layout->addWidget(typeLabel, row, 3);
233+
m_layout->addWidget(typeLabel, row, 3);
140234
QLabel* semanticsLabel = new QLabel(semantics);
141235
semanticsLabel->setFont(getMonospaceFont(this));
142-
layout->addWidget(semanticsLabel, row, 4);
236+
m_layout->addWidget(semanticsLabel, row, 4);
143237

144238
row++;
145239
}
146240

147-
layout->setColumnStretch(5, 1);
148-
setLayout(layout);
241+
m_layout->setColumnStretch(5, 1);
242+
243+
setUpdatesEnabled(true);
244+
m_isRebuilding = false;
149245
}

examples/triage/sections.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,43 @@ class SegmentsWidget : public QWidget
1414
};
1515

1616

17-
class SectionsWidget : public QWidget
17+
class SectionsModel : public QObject, public BinaryNinja::BinaryDataNotification
1818
{
19+
Q_OBJECT
20+
21+
BinaryViewRef m_data;
1922
std::vector<SectionRef> m_sections;
2023

24+
void updateSections();
25+
26+
signals:
27+
void sectionsChanged();
28+
2129
public:
22-
SectionsWidget(QWidget* parent, BinaryViewRef data);
30+
SectionsModel(QObject* parent, BinaryViewRef data);
31+
virtual ~SectionsModel();
32+
2333
const std::vector<SectionRef>& GetSections() const { return m_sections; }
34+
35+
virtual void OnSectionAdded(BinaryNinja::BinaryView* data, BinaryNinja::Section* section) override;
36+
virtual void OnSectionRemoved(BinaryNinja::BinaryView* data, BinaryNinja::Section* section) override;
37+
virtual void OnSectionUpdated(BinaryNinja::BinaryView* data, BinaryNinja::Section* section) override;
38+
};
39+
40+
41+
class SectionsWidget : public QWidget
42+
{
43+
Q_OBJECT
44+
45+
BinaryViewRef m_data;
46+
SectionsModel* m_model;
47+
QGridLayout* m_layout;
48+
bool m_isRebuilding;
49+
50+
void rebuildLayout();
51+
52+
public:
53+
SectionsWidget(QWidget* parent, BinaryViewRef data);
54+
virtual ~SectionsWidget();
55+
const std::vector<SectionRef>& GetSections() const { return m_model->GetSections(); }
2456
};

0 commit comments

Comments
 (0)