Skip to content

Commit 507935f

Browse files
committed
Fixes for multiple issues in DSC/KC Triage views.
1. Crash on kernel cache image load 2. Duplicate Load Image buttons in kernel cache view 3. Improper selection behavior in both views 4. Address column should no longer resize to be smaller than contents 5. Symbol tables should now be properly sortable
1 parent 37e20cc commit 507935f

File tree

6 files changed

+371
-366
lines changed

6 files changed

+371
-366
lines changed

view/kernelcache/ui/kctriage.cpp

Lines changed: 14 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,14 @@
1-
#include "globalarea.h"
2-
#include "kctriage.h"
3-
#include "progresstask.h"
4-
#include "ui/fontsettings.h"
51
#include <QMessageBox>
62
#include <QPainter>
73
#include <cmath>
4+
#include "globalarea.h"
5+
#include "kctriage.h"
6+
#include "ui/fontsettings.h"
87

98
using namespace BinaryNinja;
109
using namespace KernelCacheAPI;
1110

1211

13-
SymbolTableModel::SymbolTableModel(SymbolTableView* parent)
14-
: QAbstractTableModel(parent), m_parent(parent) {
15-
// TODO: Need to implement updating this font if it is changed by the user
16-
m_font = getMonospaceFont(parent);
17-
}
18-
19-
20-
int SymbolTableModel::rowCount(const QModelIndex& parent) const {
21-
Q_UNUSED(parent);
22-
return static_cast<int>(m_symbols.size());
23-
}
24-
25-
26-
int SymbolTableModel::columnCount(const QModelIndex& parent) const {
27-
Q_UNUSED(parent);
28-
// We have 3 columns: Address, Name, and Image
29-
return 3;
30-
}
31-
32-
33-
QVariant SymbolTableModel::data(const QModelIndex& index, int role) const {
34-
if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::FontRole)) {
35-
return QVariant();
36-
}
37-
38-
const KCSymbol& symbol = m_symbols.at(index.row());
39-
40-
switch (role)
41-
{
42-
case Qt::DisplayRole:
43-
{
44-
switch (index.column()) {
45-
case 0: // Address column
46-
return QString("0x%1").arg(symbol.address, 0, 16); // Display address as hexadecimal
47-
case 1: // Name column
48-
return QString::fromStdString(symbol.name);
49-
case 2: // Image column
50-
return QString::fromStdString(symbol.image);
51-
default:
52-
return QVariant();
53-
}
54-
}
55-
case Qt::FontRole:
56-
return m_font;
57-
default:
58-
return QVariant();
59-
}
60-
}
61-
62-
63-
QVariant SymbolTableModel::headerData(int section, Qt::Orientation orientation, int role) const {
64-
if (role != Qt::DisplayRole || orientation != Qt::Horizontal) {
65-
return QVariant();
66-
}
67-
68-
switch (section) {
69-
case 0:
70-
return QString("Address");
71-
case 1:
72-
return QString("Name");
73-
case 2:
74-
return QString("Image");
75-
default:
76-
return QVariant();
77-
}
78-
}
79-
80-
81-
void SymbolTableModel::updateSymbols() {
82-
m_symbols = m_parent->m_symbols;
83-
setFilter(m_filter);
84-
}
85-
86-
87-
const KCSymbol& SymbolTableModel::symbolAt(int row) const {
88-
return m_symbols.at(row);
89-
}
90-
91-
92-
void SymbolTableModel::setFilter(std::string text)
93-
{
94-
beginResetModel();
95-
96-
m_filter = text;
97-
m_symbols.clear();
98-
99-
if (!m_filter.empty())
100-
{
101-
m_symbols.reserve(m_parent->m_symbols.size());
102-
for (const auto& symbol : m_parent->m_symbols)
103-
if (symbol.name.find(m_filter) != std::string::npos)
104-
m_symbols.push_back(symbol);
105-
m_symbols.shrink_to_fit();
106-
}
107-
else
108-
{
109-
m_symbols = m_parent->m_symbols;
110-
}
111-
112-
endResetModel();
113-
}
114-
115-
116-
SymbolTableView::SymbolTableView(QWidget* parent, Ref<KernelCache> cache)
117-
: QTableView(parent), m_model(new SymbolTableModel(this)) {
118-
119-
// Set up the filter model
120-
setModel(m_model);
121-
122-
// Configure view settings
123-
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
124-
setEditTriggers(QAbstractItemView::NoEditTriggers);
125-
setSelectionBehavior(QAbstractItemView::SelectRows);
126-
setSelectionMode(QAbstractItemView::SingleSelection);
127-
128-
setSortingEnabled(true);
129-
130-
BackgroundThread::create(this)->thenBackground([this, cache](){
131-
// LogInfo("Symbol Search: Loading symbols...");
132-
m_symbols = cache->LoadAllSymbolsAndWait();
133-
// LogInfo("Symbol Search: Loaded 0x%zx symbols", m_symbols.size());
134-
})->thenMainThread([this](){
135-
m_model->updateSymbols();
136-
})->start();
137-
}
138-
139-
140-
SymbolTableView::~SymbolTableView() {
141-
delete m_model;
142-
}
143-
144-
145-
void SymbolTableView::setFilter(const std::string& filter) {
146-
m_model->setFilter(filter);
147-
}
148-
149-
15012
KCTriageViewType::KCTriageViewType()
15113
: ViewType("KCTriage", "Kernel Cache Triage")
15214
{}
@@ -194,8 +56,6 @@ KCTriageView::KCTriageView(QWidget* parent, BinaryViewRef data) : QWidget(parent
19456
m_layout->addWidget(m_triageTabs);
19557
setLayout(m_layout);
19658

197-
// XXX: RefreshData
198-
19959
m_triageTabs->selectWidget(defaultWidget);
20060
}
20161

@@ -261,18 +121,18 @@ QWidget* KCTriageView::initImageTable()
261121
auto loadImageButton = new QPushButton();
262122
connect(loadImageButton, &QPushButton::clicked, [this](bool) {
263123
// Collect only visible selected rows
264-
QModelIndexList visibleSelectedRows;
124+
QModelIndexList selected;
265125
for (const auto& index : m_imageTable->selectionModel()->selectedRows()) {
266126
if (!m_imageTable->isRowHidden(index.row())) {
267-
visibleSelectedRows.append(index);
127+
selected.append(index);
268128
}
269129
}
270130

271-
if (visibleSelectedRows.empty())
131+
if (selected.empty())
272132
return;
273133

274-
for (const auto& selection : visibleSelectedRows) {
275-
auto name = selection.data().toString().toStdString();
134+
for (const auto& selection : selected) {
135+
auto name = m_imageModel->item(selection.row(), 1)->text().toStdString();
276136
WorkerPriorityEnqueue([this, name]() { m_cache->LoadImageWithInstallName(name); });
277137
}
278138
});
@@ -284,20 +144,19 @@ QWidget* KCTriageView::initImageTable()
284144
});
285145

286146
connect(m_imageTable, &FilterableTableView::activated, this, [=](const QModelIndex& index) {
287-
auto selected = m_imageModel->item(index.row(), 0);
147+
auto selected = m_imageModel->item(index.row(), 1);
288148
auto name = selected->text().toStdString();
289149
WorkerPriorityEnqueue([this, name]() { m_cache->LoadImageWithInstallName(name); });
290150
});
291151

292152
auto loadImageLayout = new QVBoxLayout;
293153
loadImageLayout->addWidget(loadImageFilterEdit);
294154
loadImageLayout->addWidget(m_imageTable);
295-
loadImageLayout->addWidget(loadImageButton);
296155

297-
auto buttonLayout = new QHBoxLayout;
298-
buttonLayout->addWidget(loadImageButton);
299-
buttonLayout->setAlignment(Qt::AlignLeft);
300-
loadImageLayout->addLayout(buttonLayout);
156+
auto loadImageFooterLayout = new QHBoxLayout;
157+
loadImageFooterLayout->addWidget(loadImageButton);
158+
loadImageFooterLayout->setAlignment(Qt::AlignLeft);
159+
loadImageLayout->addLayout(loadImageFooterLayout);
301160

302161
auto loadImageWidget = new QWidget;
303162
loadImageWidget->setLayout(loadImageLayout);
@@ -306,7 +165,7 @@ QWidget* KCTriageView::initImageTable()
306165

307166
m_imageTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
308167

309-
m_imageTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
168+
m_imageTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
310169
m_imageTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
311170

312171
m_imageTable->setSelectionBehavior(QAbstractItemView::SelectRows);
@@ -332,23 +191,13 @@ void KCTriageView::initSymbolTable()
332191
m_symbolTable->setFilter(filter.toStdString());
333192
});
334193

335-
// Apply custom column styling
336-
m_symbolTable->setItemDelegateForColumn(0, new AddressColorDelegate(m_symbolTable));
337-
338194
auto symbolLayout = new QVBoxLayout;
339195
symbolLayout->addWidget(symbolFilterEdit);
340196
symbolLayout->addWidget(m_symbolTable);
341197

342198
auto symbolWidget = new QWidget;
343199
symbolWidget->setLayout(symbolLayout);
344200

345-
m_symbolTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents); // Address
346-
m_symbolTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); // Name
347-
m_symbolTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch); // Image
348-
349-
m_symbolTable->setSelectionBehavior(QAbstractItemView::SelectRows);
350-
m_symbolTable->setSelectionMode(QAbstractItemView::SingleSelection);
351-
352201
std::function<void(uint64_t)> navigateToAddress = [=](uint64_t addr) {
353202
ExecuteOnMainThread([addr, this](){
354203
if (Settings::Instance()->Get<bool>("ui.view.graph.preferred"))

0 commit comments

Comments
 (0)