mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 19:36:11 +00:00
Working colors and columns
This commit is contained in:
parent
5e2d58ea11
commit
d974c24daa
@ -158,6 +158,7 @@ set(SOURCES
|
|||||||
tools/basefind/BaseFindResultsDialog.cpp
|
tools/basefind/BaseFindResultsDialog.cpp
|
||||||
tools/bindiff/DiffLoadDialog.cpp
|
tools/bindiff/DiffLoadDialog.cpp
|
||||||
tools/bindiff/DiffWaitDialog.cpp
|
tools/bindiff/DiffWaitDialog.cpp
|
||||||
|
tools/bindiff/DiffWindow.cpp
|
||||||
)
|
)
|
||||||
set(HEADER_FILES
|
set(HEADER_FILES
|
||||||
core/Cutter.h
|
core/Cutter.h
|
||||||
@ -325,6 +326,7 @@ set(HEADER_FILES
|
|||||||
tools/basefind/BaseFindResultsDialog.h
|
tools/basefind/BaseFindResultsDialog.h
|
||||||
tools/bindiff/DiffLoadDialog.h
|
tools/bindiff/DiffLoadDialog.h
|
||||||
tools/bindiff/DiffWaitDialog.h
|
tools/bindiff/DiffWaitDialog.h
|
||||||
|
tools/bindiff/DiffWindow.h
|
||||||
)
|
)
|
||||||
set(UI_FILES
|
set(UI_FILES
|
||||||
dialogs/AboutDialog.ui
|
dialogs/AboutDialog.ui
|
||||||
@ -401,6 +403,7 @@ set(UI_FILES
|
|||||||
tools/basefind/BaseFindResultsDialog.ui
|
tools/basefind/BaseFindResultsDialog.ui
|
||||||
tools/bindiff/DiffLoadDialog.ui
|
tools/bindiff/DiffLoadDialog.ui
|
||||||
tools/bindiff/DiffWaitDialog.ui
|
tools/bindiff/DiffWaitDialog.ui
|
||||||
|
tools/bindiff/DiffWindow.ui
|
||||||
)
|
)
|
||||||
set(QRC_FILES
|
set(QRC_FILES
|
||||||
resources.qrc
|
resources.qrc
|
||||||
|
@ -82,10 +82,6 @@ const QHash<QString, QHash<ColorFlags, QColor>> Configuration::cutterOptionColor
|
|||||||
{ { DarkFlag, QColor(0x4c, 0xaf, 0x50) }, { LightFlag, QColor(0x00, 0xc8, 0x53) } } },
|
{ { DarkFlag, QColor(0x4c, 0xaf, 0x50) }, { LightFlag, QColor(0x00, 0xc8, 0x53) } } },
|
||||||
{ "gui.match.partial",
|
{ "gui.match.partial",
|
||||||
{ { DarkFlag, QColor(0xff, 0xc1, 0x07) }, { LightFlag, QColor(0xff, 0xa0, 0x00) } } },
|
{ { DarkFlag, QColor(0xff, 0xc1, 0x07) }, { LightFlag, QColor(0xff, 0xa0, 0x00) } } },
|
||||||
{ "gui.match.none",
|
|
||||||
{ { DarkFlag, QColor(0xf4, 0x43, 0x36) }, { LightFlag, QColor(0xd3, 0x2f, 0x2f) } } },
|
|
||||||
{ "gui.match.new",
|
|
||||||
{ { DarkFlag, QColor(0x21, 0x96, 0xf3) }, { LightFlag, QColor(0x19, 0x76, 0xd2) } } },
|
|
||||||
{ "lineHighlight",
|
{ "lineHighlight",
|
||||||
{ { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) },
|
{ { DarkFlag, QColor(0x15, 0x1d, 0x1d, 0x96) },
|
||||||
{ LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) } } },
|
{ LightFlag, QColor(0xd2, 0xd2, 0xff, 0x96) } } },
|
||||||
|
@ -100,27 +100,27 @@ QList<BinDiffMatchDescription> BinDiff::matches()
|
|||||||
desc.simtype = RZ_ANALYSIS_SIMILARITY_TYPE_STR(pair->similarity);
|
desc.simtype = RZ_ANALYSIS_SIMILARITY_TYPE_STR(pair->similarity);
|
||||||
desc.similarity = pair->similarity;
|
desc.similarity = pair->similarity;
|
||||||
|
|
||||||
pairs << desc;
|
pairs.push_back(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<FunctionDescription> BinDiff::mismatch(bool fileA)
|
QList<FunctionDescription> BinDiff::mismatch(bool originalFile)
|
||||||
{
|
{
|
||||||
QList<FunctionDescription> list;
|
QList<FunctionDescription> list;
|
||||||
RzAnalysisFunction *func = nullptr;
|
|
||||||
RzList *unmatch = fileA ? result->unmatch_a : result->unmatch_b;
|
|
||||||
RzListIter *it = nullptr;
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RzAnalysisFunction *func = nullptr;
|
||||||
|
RzList *unmatch = originalFile ? result->unmatch_a : result->unmatch_b;
|
||||||
|
RzListIter *it = nullptr;
|
||||||
|
|
||||||
CutterRzListForeach (unmatch, it, RzAnalysisFunction, func) {
|
CutterRzListForeach (unmatch, it, RzAnalysisFunction, func) {
|
||||||
FunctionDescription desc;
|
FunctionDescription desc;
|
||||||
setFunctionDescription(&desc, func);
|
setFunctionDescription(&desc, func);
|
||||||
list << desc;
|
list.push_back(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
|
@ -22,7 +22,7 @@ public:
|
|||||||
void setAnalysisLevel(int aLevel);
|
void setAnalysisLevel(int aLevel);
|
||||||
|
|
||||||
QList<BinDiffMatchDescription> matches();
|
QList<BinDiffMatchDescription> matches();
|
||||||
QList<FunctionDescription> mismatch(bool fileA);
|
QList<FunctionDescription> mismatch(bool originalFile);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void cancel();
|
void cancel();
|
||||||
|
@ -4564,6 +4564,32 @@ bool CutterCore::isWriteModeEnabled()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RzList *get_functions(RzAnalysis *analysis)
|
||||||
|
{
|
||||||
|
RzList *functions = rz_analysis_get_fcns(analysis);
|
||||||
|
if (!functions) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RzList *list = rz_list_newf(nullptr);
|
||||||
|
if (!list) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
RzAnalysisFunction *func = nullptr;
|
||||||
|
RzListIter *it = nullptr;
|
||||||
|
|
||||||
|
CutterRzListForeach (functions, it, RzAnalysisFunction, func) {
|
||||||
|
QString name = func->name;
|
||||||
|
if (name.startsWith("sym.imp.") || name.startsWith("loc.imp.") || name.startsWith("imp.")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rz_list_add_sorted(list, func, analysis->columnSort);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int level,
|
RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int level,
|
||||||
RzAnalysisMatchThreadInfoCb callback, void *user)
|
RzAnalysisMatchThreadInfoCb callback, void *user)
|
||||||
{
|
{
|
||||||
@ -4621,21 +4647,18 @@ RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int leve
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
fcns_a = rz_list_clone(rz_analysis_get_fcns(core_a->analysis));
|
fcns_a = get_functions(core_a->analysis);
|
||||||
if (rz_list_empty(fcns_a)) {
|
if (rz_list_empty(fcns_a)) {
|
||||||
qWarning() << "no functions found in the current opened file";
|
qWarning() << "no functions found in the current opened file";
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
fcns_b = rz_list_clone(rz_analysis_get_fcns(core_b->analysis));
|
fcns_b = get_functions(core_b->analysis);
|
||||||
if (rz_list_empty(fcns_b)) {
|
if (rz_list_empty(fcns_b)) {
|
||||||
qWarning() << "no functions found in " << filePath;
|
qWarning() << "no functions found in " << filePath;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
rz_list_sort(fcns_a, core_a->analysis->columnSort);
|
|
||||||
rz_list_sort(fcns_b, core_b->analysis->columnSort);
|
|
||||||
|
|
||||||
opts.analysis_a = core_a->analysis;
|
opts.analysis_a = core_a->analysis;
|
||||||
opts.analysis_b = core_b->analysis;
|
opts.analysis_b = core_b->analysis;
|
||||||
opts.callback = callback;
|
opts.callback = callback;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string notr="true">Select which file to compare.</string>
|
<string notr="false">Select which file to compare.</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<property name="sizeConstraint">
|
<property name="sizeConstraint">
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include <core/Cutter.h>
|
#include <core/Cutter.h>
|
||||||
#include <rz_util.h>
|
#include <rz_util.h>
|
||||||
|
|
||||||
|
#include "DiffWindow.h"
|
||||||
|
|
||||||
DiffWaitDialog::DiffWaitDialog(QWidget *parent)
|
DiffWaitDialog::DiffWaitDialog(QWidget *parent)
|
||||||
: QDialog(parent), timer(parent), bDiff(new BinDiff()), ui(new Ui::DiffWaitDialog)
|
: QDialog(parent), timer(parent), bDiff(new BinDiff()), ui(new Ui::DiffWaitDialog)
|
||||||
{
|
{
|
||||||
@ -29,27 +31,18 @@ DiffWaitDialog::DiffWaitDialog(QWidget *parent)
|
|||||||
|
|
||||||
DiffWaitDialog::~DiffWaitDialog()
|
DiffWaitDialog::~DiffWaitDialog()
|
||||||
{
|
{
|
||||||
if (bDiff->isRunning()) {
|
if (bDiff && bDiff->isRunning()) {
|
||||||
bDiff->cancel();
|
bDiff->cancel();
|
||||||
bDiff->wait();
|
bDiff->wait();
|
||||||
|
delete bDiff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<BinDiffMatchDescription> DiffWaitDialog::matches()
|
|
||||||
{
|
|
||||||
return bDiff->matches();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<FunctionDescription> DiffWaitDialog::mismatch(bool fileA)
|
|
||||||
{
|
|
||||||
return bDiff->mismatch(fileA);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DiffWaitDialog::show(QString original, QString modified, int level)
|
void DiffWaitDialog::show(QString original, QString modified, int level)
|
||||||
{
|
{
|
||||||
connect(this, &DiffWaitDialog::cancelJob, bDiff.get(), &BinDiff::cancel);
|
connect(this, &DiffWaitDialog::cancelJob, bDiff, &BinDiff::cancel);
|
||||||
connect(bDiff.get(), &BinDiff::progress, this, &DiffWaitDialog::onProgress);
|
connect(bDiff, &BinDiff::progress, this, &DiffWaitDialog::onProgress);
|
||||||
connect(bDiff.get(), &BinDiff::complete, this, &DiffWaitDialog::onCompletion);
|
connect(bDiff, &BinDiff::complete, this, &DiffWaitDialog::onCompletion);
|
||||||
connect(&timer, &QTimer::timeout, this, &DiffWaitDialog::updateElapsedTime);
|
connect(&timer, &QTimer::timeout, this, &DiffWaitDialog::updateElapsedTime);
|
||||||
|
|
||||||
ui->lineEditOriginal->setText(original);
|
ui->lineEditOriginal->setText(original);
|
||||||
@ -86,6 +79,12 @@ void DiffWaitDialog::onProgress(BinDiffStatusDescription status)
|
|||||||
void DiffWaitDialog::onCompletion()
|
void DiffWaitDialog::onCompletion()
|
||||||
{
|
{
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
|
auto results = new DiffWindow(bDiff, parentWidget());
|
||||||
|
bDiff = nullptr;
|
||||||
|
|
||||||
|
results->showMaximized();
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffWaitDialog::updateElapsedTime()
|
void DiffWaitDialog::updateElapsedTime()
|
||||||
|
@ -24,9 +24,6 @@ public:
|
|||||||
|
|
||||||
void show(QString original, QString modified, int level);
|
void show(QString original, QString modified, int level);
|
||||||
|
|
||||||
QList<BinDiffMatchDescription> matches();
|
|
||||||
QList<FunctionDescription> mismatch(bool fileA);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onProgress(BinDiffStatusDescription status);
|
void onProgress(BinDiffStatusDescription status);
|
||||||
void onCompletion();
|
void onCompletion();
|
||||||
@ -41,7 +38,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
QElapsedTimer eTimer;
|
QElapsedTimer eTimer;
|
||||||
QTimer timer;
|
QTimer timer;
|
||||||
std::unique_ptr<BinDiff> bDiff;
|
BinDiff *bDiff;
|
||||||
std::unique_ptr<Ui::DiffWaitDialog> ui;
|
std::unique_ptr<Ui::DiffWaitDialog> ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string notr="true">Performing binary diffing</string>
|
<string notr="false">Performing binary diffing</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<property name="sizeConstraint">
|
<property name="sizeConstraint">
|
||||||
|
239
src/tools/bindiff/DiffWindow.cpp
Normal file
239
src/tools/bindiff/DiffWindow.cpp
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
#include "DiffWindow.h"
|
||||||
|
#include "ui_DiffWindow.h"
|
||||||
|
|
||||||
|
#include <core/Cutter.h>
|
||||||
|
#include "common/Configuration.h"
|
||||||
|
#include "CutterConfig.h"
|
||||||
|
#include <rz_th.h>
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
DiffMatchModel::DiffMatchModel(QList<BinDiffMatchDescription> *list, QColor cPerf, QColor cPart,
|
||||||
|
QObject *parent)
|
||||||
|
: QAbstractListModel(parent), list(list), perfect(cPerf), partial(cPart)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int DiffMatchModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return list->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DiffMatchModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return DiffMatchModel::ColumnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DiffMatchModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (index.row() >= list->count())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
const BinDiffMatchDescription &entry = list->at(index.row());
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case NameOrig:
|
||||||
|
return entry.original.name;
|
||||||
|
case SizeOrig:
|
||||||
|
return QString::asprintf("%llu (%#llx)", entry.original.linearSize,
|
||||||
|
entry.original.linearSize);
|
||||||
|
case AddressOrig:
|
||||||
|
return RzAddressString(entry.original.offset);
|
||||||
|
case Similarity:
|
||||||
|
return QString::asprintf("%.2f (%.2f %%)", entry.similarity, entry.similarity * 100.0);
|
||||||
|
case AddressMod:
|
||||||
|
return RzAddressString(entry.modified.offset);
|
||||||
|
case SizeMod:
|
||||||
|
return QString::asprintf("%llu (%#llx)", entry.modified.linearSize,
|
||||||
|
entry.modified.linearSize);
|
||||||
|
case NameMod:
|
||||||
|
return entry.modified.name;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::ToolTipRole: {
|
||||||
|
return entry.simtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::BackgroundRole: {
|
||||||
|
return gradientByRatio(entry.similarity);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DiffMatchModel::headerData(int section, Qt::Orientation, int role) const
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (section) {
|
||||||
|
case NameOrig:
|
||||||
|
return tr("Name (A)");
|
||||||
|
case SizeOrig:
|
||||||
|
return tr("Size (A)");
|
||||||
|
case AddressOrig:
|
||||||
|
return tr("Address (A)");
|
||||||
|
case Similarity:
|
||||||
|
return tr("Similarity");
|
||||||
|
case AddressMod:
|
||||||
|
return tr("Address (B)");
|
||||||
|
case SizeMod:
|
||||||
|
return tr("Size (B)");
|
||||||
|
case NameMod:
|
||||||
|
return tr("Name (B)");
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor DiffMatchModel::gradientByRatio(const double ratio) const
|
||||||
|
{
|
||||||
|
float red = partial.redF() + (ratio * (perfect.redF() - partial.redF()));
|
||||||
|
float green = partial.greenF() + (ratio * (perfect.greenF() - partial.greenF()));
|
||||||
|
float blue = partial.blueF() + (ratio * (perfect.blueF() - partial.blueF()));
|
||||||
|
return QColor::fromRgbF(red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
DiffMismatchModel::DiffMismatchModel(QList<FunctionDescription> *list, QObject *parent)
|
||||||
|
: QAbstractListModel(parent), list(list)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int DiffMismatchModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return list->count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DiffMismatchModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return DiffMismatchModel::ColumnCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DiffMismatchModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (index.row() >= list->count())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
const FunctionDescription &entry = list->at(index.row());
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case FuncName:
|
||||||
|
return entry.name;
|
||||||
|
case FuncAddress:
|
||||||
|
return RzAddressString(entry.offset);
|
||||||
|
case FuncLinearSize:
|
||||||
|
return QString::asprintf("%llu (%#llx)", entry.linearSize, entry.linearSize);
|
||||||
|
case FuncNargs:
|
||||||
|
return QString::asprintf("%llu", entry.nargs);
|
||||||
|
case FuncNlocals:
|
||||||
|
return QString::asprintf("%llu", entry.nlocals);
|
||||||
|
case FuncNbbs:
|
||||||
|
return QString::asprintf("%llu", entry.nbbs);
|
||||||
|
case FuncCalltype:
|
||||||
|
return entry.calltype;
|
||||||
|
case FuncEdges:
|
||||||
|
return QString::asprintf("%llu", entry.edges);
|
||||||
|
case FuncStackframe:
|
||||||
|
return QString::asprintf("%llu", entry.stackframe);
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::ToolTipRole: {
|
||||||
|
return entry.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DiffMismatchModel::headerData(int section, Qt::Orientation, int role) const
|
||||||
|
{
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
switch (section) {
|
||||||
|
case FuncName:
|
||||||
|
return tr("Name");
|
||||||
|
case FuncAddress:
|
||||||
|
return tr("Address");
|
||||||
|
case FuncLinearSize:
|
||||||
|
return tr("Linear Size");
|
||||||
|
case FuncNargs:
|
||||||
|
return tr("Num Args");
|
||||||
|
case FuncNlocals:
|
||||||
|
return tr("Num Locals");
|
||||||
|
case FuncNbbs:
|
||||||
|
return tr("Basic Blocks");
|
||||||
|
case FuncCalltype:
|
||||||
|
return tr("Call Type");
|
||||||
|
case FuncEdges:
|
||||||
|
return tr("Edges");
|
||||||
|
case FuncStackframe:
|
||||||
|
return tr("Stackframe");
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DiffWindow::DiffWindow(BinDiff *bd, QWidget *parent)
|
||||||
|
: QDialog(parent), ui(new Ui::DiffWindow), bDiff(bd)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->comboBoxShowInfo->addItem(tr("Summary"));
|
||||||
|
ui->comboBoxShowInfo->addItem(tr("AAAA"));
|
||||||
|
ui->comboBoxShowInfo->addItem(tr("BBBB"));
|
||||||
|
|
||||||
|
listMatch = bDiff->matches();
|
||||||
|
listDel = bDiff->mismatch(true);
|
||||||
|
listAdd = bDiff->mismatch(false);
|
||||||
|
|
||||||
|
QColor perfect = Config()->getColor("gui.match.perfect");
|
||||||
|
QColor partial = Config()->getColor("gui.match.partial");
|
||||||
|
|
||||||
|
modelMatch = new DiffMatchModel(&listMatch, perfect, partial, this);
|
||||||
|
modelDel = new DiffMismatchModel(&listDel, this);
|
||||||
|
modelAdd = new DiffMismatchModel(&listAdd, this);
|
||||||
|
|
||||||
|
// Matches Table
|
||||||
|
ui->tableViewMatch->setModel(modelMatch);
|
||||||
|
ui->tableViewMatch->sortByColumn(DiffMatchModel::Similarity, Qt::AscendingOrder);
|
||||||
|
ui->tableViewMatch->verticalHeader()->hide();
|
||||||
|
ui->tableViewMatch->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
|
ui->tableViewMatch->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
|
// Deletion Table
|
||||||
|
ui->tableViewRem->setModel(modelDel);
|
||||||
|
ui->tableViewRem->sortByColumn(DiffMismatchModel::FuncName, Qt::AscendingOrder);
|
||||||
|
ui->tableViewRem->verticalHeader()->hide();
|
||||||
|
ui->tableViewRem->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
|
ui->tableViewRem->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
|
||||||
|
// Addition Table
|
||||||
|
ui->tableViewAdd->setModel(modelAdd);
|
||||||
|
ui->tableViewAdd->sortByColumn(DiffMismatchModel::FuncName, Qt::AscendingOrder);
|
||||||
|
ui->tableViewAdd->verticalHeader()->hide();
|
||||||
|
ui->tableViewAdd->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
|
ui->tableViewAdd->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
DiffWindow::~DiffWindow() {}
|
||||||
|
|
||||||
|
void DiffWindow::actionExport_as_JSON() {}
|
||||||
|
|
||||||
|
void DiffWindow::actionExport_as_Markdown() {}
|
108
src/tools/bindiff/DiffWindow.h
Normal file
108
src/tools/bindiff/DiffWindow.h
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#ifndef DIFF_WINDOW_H
|
||||||
|
#define DIFF_WINDOW_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QListWidgetItem>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <core/Cutter.h>
|
||||||
|
|
||||||
|
class DiffWindow;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class DiffWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DiffMatchModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
friend DiffWindow;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Column {
|
||||||
|
NameOrig = 0,
|
||||||
|
SizeOrig,
|
||||||
|
AddressOrig,
|
||||||
|
Similarity,
|
||||||
|
AddressMod,
|
||||||
|
SizeMod,
|
||||||
|
NameMod,
|
||||||
|
ColumnCount
|
||||||
|
};
|
||||||
|
|
||||||
|
DiffMatchModel(QList<BinDiffMatchDescription> *list, QColor cPerf, QColor cPart,
|
||||||
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
|
||||||
|
QColor gradientByRatio(const double ratio) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<BinDiffMatchDescription> *list;
|
||||||
|
|
||||||
|
QColor perfect, partial;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DiffMismatchModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
friend DiffWindow;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Column {
|
||||||
|
FuncName = 0,
|
||||||
|
FuncAddress,
|
||||||
|
FuncLinearSize,
|
||||||
|
FuncNargs,
|
||||||
|
FuncNlocals,
|
||||||
|
FuncNbbs,
|
||||||
|
FuncCalltype,
|
||||||
|
FuncEdges,
|
||||||
|
FuncStackframe,
|
||||||
|
ColumnCount
|
||||||
|
};
|
||||||
|
|
||||||
|
DiffMismatchModel(QList<FunctionDescription> *list, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<FunctionDescription> *list;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DiffWindow : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DiffWindow(BinDiff *bd, QWidget *parent = nullptr);
|
||||||
|
~DiffWindow();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void actionExport_as_JSON();
|
||||||
|
void actionExport_as_Markdown();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Ui::DiffWindow> ui;
|
||||||
|
std::unique_ptr<BinDiff> bDiff;
|
||||||
|
|
||||||
|
DiffMatchModel *modelMatch;
|
||||||
|
DiffMismatchModel *modelDel;
|
||||||
|
DiffMismatchModel *modelAdd;
|
||||||
|
|
||||||
|
QList<BinDiffMatchDescription> listMatch;
|
||||||
|
QList<FunctionDescription> listDel;
|
||||||
|
QList<FunctionDescription> listAdd;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DIFF_WINDOW_H
|
156
src/tools/bindiff/DiffWindow.ui
Normal file
156
src/tools/bindiff/DiffWindow.ui
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>DiffWindow</class>
|
||||||
|
<widget class="QDialog" name="DiffWindow">
|
||||||
|
<property name="windowModality">
|
||||||
|
<enum>Qt::NonModal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>992</width>
|
||||||
|
<height>641</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Diff Between Binaries</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QMenuBar" name="menuBar">
|
||||||
|
<property name="defaultUp">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="nativeMenuBar">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuExport">
|
||||||
|
<property name="title">
|
||||||
|
<string>Export as ...</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionExport_as_JSON"/>
|
||||||
|
<addaction name="actionExport_as_Markdown"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuExport"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tabMatchFunc">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::DefaultContextMenu</enum>
|
||||||
|
</property>
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Match Funcs</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="tableViewMatch"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabMismatchRem">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Removed Funcs</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayoutMismatchRem">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="tableViewRem"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabMismatchAdd">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Added Funcs</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayoutMismatchAdd">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="tableViewAdd"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tabInfo">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Info Diff</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayoutInfo">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>527</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Show...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="comboBoxShowInfo">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="tableViewInfo"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
<action name="actionExport_as_JSON">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export as JSON</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionExport_as_Markdown">
|
||||||
|
<property name="text">
|
||||||
|
<string>Export as Markdown</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
Loading…
Reference in New Issue
Block a user