Working open dialog with waiting dialog.

This commit is contained in:
wargio 2023-12-31 11:11:56 +08:00
parent 439b268927
commit 5e2d58ea11
19 changed files with 482 additions and 317 deletions

View File

@ -30,6 +30,7 @@ option(CUTTER_PACKAGE_RZ_LIBYARA "Compile and install rz-libyara during the inst
option(CUTTER_PACKAGE_RZ_SILHOUETTE "Compile and install rz-silhouette during the install step." OFF)
option(CUTTER_PACKAGE_JSDEC "Compile and install jsdec during install step." OFF)
OPTION(CUTTER_QT6 "Use QT6" OFF)
OPTION(CUTTER_ASAN "Build with ASAN" OFF)
if(NOT CUTTER_ENABLE_PYTHON)
set(CUTTER_ENABLE_PYTHON_BINDINGS OFF)
@ -188,6 +189,7 @@ message(STATUS "- Package RzLibYara: ${CUTTER_PACKAGE_RZ_LIBYARA}")
message(STATUS "- Package RzSilhouette: ${CUTTER_PACKAGE_RZ_SILHOUETTE}")
message(STATUS "- Package JSDec: ${CUTTER_PACKAGE_JSDEC}")
message(STATUS "- QT6: ${CUTTER_QT6}")
message(STATUS "- ASAN: ${CUTTER_ASAN}")
message(STATUS "")
add_subdirectory(src)

View File

@ -157,6 +157,7 @@ set(SOURCES
tools/basefind/BaseFindSearchDialog.cpp
tools/basefind/BaseFindResultsDialog.cpp
tools/bindiff/DiffLoadDialog.cpp
tools/bindiff/DiffWaitDialog.cpp
)
set(HEADER_FILES
core/Cutter.h
@ -323,6 +324,7 @@ set(HEADER_FILES
tools/basefind/BaseFindSearchDialog.h
tools/basefind/BaseFindResultsDialog.h
tools/bindiff/DiffLoadDialog.h
tools/bindiff/DiffWaitDialog.h
)
set(UI_FILES
dialogs/AboutDialog.ui
@ -398,6 +400,7 @@ set(UI_FILES
tools/basefind/BaseFindSearchDialog.ui
tools/basefind/BaseFindResultsDialog.ui
tools/bindiff/DiffLoadDialog.ui
tools/bindiff/DiffWaitDialog.ui
)
set(QRC_FILES
resources.qrc
@ -588,6 +591,12 @@ if(CUTTER_ENABLE_PACKAGING)
target_compile_definitions(Cutter PRIVATE CUTTER_ENABLE_PACKAGING)
endif()
if(CUTTER_ASAN)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always -fsanitize=address,undefined -fno-omit-frame-pointer -fsanitize-address-use-after-scope")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always -fsanitize=address,undefined -fno-omit-frame-pointer -fsanitize-address-use-after-scope")
set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fdiagnostics-color=always -fsanitize=address,undefined -fno-omit-frame-pointer -fsanitize-address-use-after-scope")
endif()
include(Translations)
# Install files

View File

@ -6,10 +6,9 @@ bool BinDiff::threadCallback(const size_t nLeft, const size_t nMatch, void *user
return bdiff->updateProgress(nLeft, nMatch);
}
BinDiff::BinDiff(CutterCore *core)
: core(core),
result(nullptr),
continue_run(true),
BinDiff::BinDiff()
: result(nullptr),
continueRun(true),
maxTotal(1)
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
,
@ -20,31 +19,48 @@ BinDiff::BinDiff(CutterCore *core)
BinDiff::~BinDiff()
{
cancel();
wait();
rz_analysis_match_result_free(result);
}
void BinDiff::run(QString fileName)
void BinDiff::setFile(QString filePath)
{
mutex.lock();
file = filePath;
mutex.unlock();
}
void BinDiff::setAnalysisLevel(int aLevel)
{
mutex.lock();
level = aLevel;
mutex.unlock();
}
void BinDiff::run()
{
qRegisterMetaType<BinDiffStatusDescription>();
mutex.lock();
rz_analysis_match_result_free(result);
result = nullptr;
continue_run = true;
continueRun = true;
maxTotal = 1; // maxTotal must be at least 1.
mutex.unlock();
core->coreMutex.lock();
result = core->diffNewFile(fileName, threadCallback, this);
core->coreMutex.unlock();
result = Core()->diffNewFile(file, level, threadCallback, this);
emit complete();
mutex.lock();
bool canComplete = continueRun;
mutex.unlock();
if (canComplete) {
emit complete();
}
}
void BinDiff::cancel()
{
mutex.lock();
continue_run = false;
continueRun = false;
mutex.unlock();
}
@ -69,6 +85,10 @@ QList<BinDiffMatchDescription> BinDiff::matches()
const RzAnalysisFunction *fcn_a = nullptr;
const RzAnalysisFunction *fcn_b = nullptr;
if (!result) {
return pairs;
}
CutterRzListForeach (result->matches, it, RzAnalysisMatchPair, pair) {
BinDiffMatchDescription desc;
fcn_a = static_cast<const RzAnalysisFunction *>(pair->pair_a);
@ -93,6 +113,10 @@ QList<FunctionDescription> BinDiff::mismatch(bool fileA)
RzList *unmatch = fileA ? result->unmatch_a : result->unmatch_b;
RzListIter *it = nullptr;
if (!result) {
return list;
}
CutterRzListForeach (unmatch, it, RzAnalysisFunction, func) {
FunctionDescription desc;
setFunctionDescription(&desc, func);
@ -102,19 +126,23 @@ QList<FunctionDescription> BinDiff::mismatch(bool fileA)
return list;
}
bool BinDiff::updateProgress(const size_t nLeft, const size_t nMatch)
bool BinDiff::updateProgress(size_t nLeft, size_t nMatch)
{
mutex.lock();
if (maxTotal < nMatch) {
if (nMatch > maxTotal) {
maxTotal = nMatch;
}
if (maxTotal < nLeft) {
if (nLeft > maxTotal) {
maxTotal = nLeft;
}
emit progress(maxTotal, nLeft, nMatch);
bool ret = continue_run;
BinDiffStatusDescription status;
status.total = maxTotal;
status.nLeft = nLeft;
status.nMatch = nMatch;
emit progress(status);
bool ret = continueRun;
mutex.unlock();
return ret;
}

View File

@ -8,17 +8,19 @@
#include "CutterDescriptions.h"
#include <rz_analysis.h>
class CutterCore;
class BinDiff : public QThread
{
Q_OBJECT
public:
explicit BinDiff(CutterCore *core);
explicit BinDiff();
virtual ~BinDiff();
void run(QString fileName);
void run();
void setFile(QString filePth);
void setAnalysisLevel(int aLevel);
QList<BinDiffMatchDescription> matches();
QList<FunctionDescription> mismatch(bool fileA);
@ -26,19 +28,20 @@ public slots:
void cancel();
signals:
void progress(const size_t total, const size_t nLeft, const size_t nMatch);
void progress(BinDiffStatusDescription status);
void complete();
private:
CutterCore *const core;
RzAnalysisMatchResult *result;
bool continue_run;
bool continueRun;
size_t maxTotal;
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QMutex mutex;
#else
QRecursiveMutex mutex;
#endif
QString file;
int level;
bool updateProgress(const size_t nLeft, const size_t nMatch);
static bool threadCallback(const size_t nLeft, const size_t nMatch, void *user);

View File

@ -233,11 +233,11 @@ CutterCore::~CutterCore()
{
delete bbHighlighter;
rz_cons_sleep_end(coreBed);
rz_core_free(this->core_b);
this->core_b = nullptr;
rz_core_task_sync_end(&core_a->tasks);
rz_core_free(this->core_a);
this->core_a = nullptr;
rz_core_free(this->core_b);
this->core_b = nullptr;
rz_cons_free();
assert(uniqueInstance == this);
uniqueInstance = nullptr;
@ -4564,30 +4564,28 @@ bool CutterCore::isWriteModeEnabled()
return false;
}
RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath,
RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath, int level,
RzAnalysisMatchThreadInfoCb callback, void *user)
{
CORE_LOCK();
RzList *fcns_a = nullptr, *fcns_b = nullptr;
RzAnalysisMatchResult *result = nullptr;
RzAnalysisMatchOpt opts;
RzListIter *iter;
RzConfigNode *node;
void *ptr;
if (core_b) {
rz_core_free(core_b);
core_b = nullptr;
}
core_b = rz_core_new();
if (!core_b) {
goto fail;
// FIXME: allocating and deallocating a new core here, taints some pointer on core_a
core_b = rz_core_new();
if (!core_b) {
return nullptr;
}
rz_config_set_b(core_b->config, "io.va", rz_config_get_b(core_a->config, "io.va"));
rz_core_loadlibs(core_b, RZ_CORE_LOADLIBS_ALL);
core_b->print->scr_prompt = false;
}
rz_config_set_b(core_b->config, "io.va", rz_config_get_b(core_a->config, "io.va"));
rz_core_loadlibs(core_b, RZ_CORE_LOADLIBS_ALL);
core_b->print->scr_prompt = false;
if (!rz_core_file_open(core_b, filePath.toUtf8().constData(), RZ_PERM_RX, 0)) {
qWarning() << "cannot open file " << filePath;
goto fail;
@ -4603,9 +4601,7 @@ RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath,
goto fail;
}
rz_list_foreach(core_a->config->nodes, iter, ptr)
{
node = reinterpret_cast<RzConfigNode *>(ptr);
CutterRzListForeach (core_a->config->nodes, iter, RzConfigNode, node) {
if (!strcmp(node->name, "scr.color") || !strcmp(node->name, "scr.interactive")
|| !strcmp(node->name, "cfg.debug")) {
rz_config_set(core_b->config, node->name, "0");
@ -4614,8 +4610,14 @@ RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath,
rz_config_set(core_b->config, node->name, node->value);
}
if (!rz_core_analysis_everything(core_b, false, nullptr)) {
qWarning() << "cannot analyze binary " << filePath;
if (!rz_core_analysis_all(core_b)) {
qWarning() << "cannot perform basic analysis of the binary " << filePath;
goto fail;
}
if (level != AnalysisLevelSymbols
&& !rz_core_analysis_everything(core_b, level == AnalysisLevelExperimental, nullptr)) {
qWarning() << "cannot perform complete analysis of the binary " << filePath;
goto fail;
}
@ -4651,10 +4653,10 @@ RzAnalysisMatchResult *CutterCore::diffNewFile(const QString &filePath,
return result;
fail:
rz_list_free(fcns_a);
rz_list_free(fcns_b);
rz_core_free(this->core_b);
this->core_b = nullptr;
rz_core_file_close_all_but(core_b);
return nullptr;
}

View File

@ -72,7 +72,6 @@ class CUTTER_EXPORT CutterCore : public QObject
friend class RzCoreLocked;
friend class RizinTask;
friend class Basefind;
friend class BinDiff;
public:
explicit CutterCore(QObject *parent = nullptr);
@ -757,7 +756,13 @@ public:
void writeGraphvizGraphToFile(QString path, QString format, RzCoreGraphType type, RVA address);
/* Diffing/Matching */
RzAnalysisMatchResult *diffNewFile(const QString &filePath,
enum {
AnalysisLevelSymbols = 0,
AnalysisLevelComplete,
AnalysisLevelExperimental,
};
RzAnalysisMatchResult *diffNewFile(const QString &filePath, int level,
RzAnalysisMatchThreadInfoCb callback, void *user);
signals:

View File

@ -413,6 +413,13 @@ struct BinDiffMatchDescription
double similarity;
};
struct BinDiffStatusDescription
{
size_t total;
size_t nLeft;
size_t nMatch;
};
Q_DECLARE_METATYPE(FunctionDescription)
Q_DECLARE_METATYPE(ImportDescription)
Q_DECLARE_METATYPE(ExportDescription)
@ -455,5 +462,6 @@ Q_DECLARE_METATYPE(VariableDescription)
Q_DECLARE_METATYPE(BasefindCoreStatusDescription)
Q_DECLARE_METATYPE(BasefindResultDescription)
Q_DECLARE_METATYPE(BinDiffMatchDescription)
Q_DECLARE_METATYPE(BinDiffStatusDescription)
#endif // DESCRIPTIONS_H

View File

@ -119,7 +119,7 @@
// Tools
#include "tools/basefind/BaseFindDialog.h"
#include "tools/bindiff/DiffLoadDialog.h"
#include "tools/bindiff/DiffWaitDialog.h"
#define PROJECT_FILE_FILTER tr("Rizin Project (*.rzdb)")
@ -1617,8 +1617,29 @@ void MainWindow::on_actionBackward_triggered()
void MainWindow::on_actionDiff_triggered()
{
auto dialog = new DiffLoadDialog(this);
dialog->show();
if (diffLoadDialog) {
delete diffLoadDialog;
}
diffLoadDialog = new DiffLoadDialog(this);
diffLoadDialog->show();
connect(diffLoadDialog, &DiffLoadDialog::startDiffing, this, &MainWindow::startDiffing);
}
void MainWindow::startDiffing()
{
if (!diffLoadDialog) {
return;
}
QString modified = diffLoadDialog->getFileToOpen();
if (modified.isEmpty()) {
messageBoxWarning(tr("Error"), tr("The compare file was not selected."));
return;
}
auto level = diffLoadDialog->getLevel();
auto diffWait = new DiffWaitDialog(this);
diffWait->show(filename, modified, level);
}
void MainWindow::on_actionForward_triggered()

View File

@ -4,12 +4,12 @@
#include "core/Cutter.h" // only needed for ut64
#include "dialogs/NewFileDialog.h"
#include "dialogs/WelcomeDialog.h"
#include "dialogs/bindiff/BinDiffDialog.h"
#include "common/Configuration.h"
#include "common/InitialOptions.h"
#include "common/IOModesController.h"
#include "common/CutterLayout.h"
#include "MemoryDockWidget.h"
#include "tools/bindiff/DiffLoadDialog.h"
#include <memory>
@ -164,6 +164,7 @@ private slots:
void addExtraHexdump();
void addExtraDisassembly();
void addExtraDecompiler();
void startDiffing();
void on_actionRefresh_Panels_triggered();
@ -271,6 +272,7 @@ private:
CallGraphWidget *callGraphDock = nullptr;
CallGraphWidget *globalCallGraphDock = nullptr;
CutterDockWidget *heapDock = nullptr;
DiffLoadDialog *diffLoadDialog = nullptr;
QMenu *disassemblyContextMenuExtensions = nullptr;
QMenu *addressableContextMenuExtensions = nullptr;
@ -335,7 +337,7 @@ private:
QSharedPointer<RizinTask> task;
RizinTaskDialog *taskDialog = nullptr;
BinDiffDialog *binDiffDialog = nullptr;
DiffLoadDialog *binDiffDialog = nullptr;
};
#endif // MAINWINDOW_H

View File

@ -1,137 +0,0 @@
#include "core/Cutter.h"
#include "BinDiffDialog.h"
#include "ui_BinDiffDialog.h"
#include "common/Configuration.h"
#include "common/BugReporting.h"
#include <QUrl>
#include <QTimer>
#include <QEventLoop>
#include <QJsonObject>
#include <QProgressBar>
#include <QProgressDialog>
#include <UpdateWorker.h>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkAccessManager>
#include "CutterConfig.h"
typedef struct {
QColor perfect;
QColor partial;
QColor none;
} DiffColors;
inline QString doubleToString(double number)
{
return QString::asprintf("%.6f", number);
}
inline QTableWidgetItem *newColoredCell(QString text, double similarity, const DiffColors *colors) {
auto item = new QTableWidgetItem(text);
if (similarity >= 1.0) {
item->setBackground(colors->perfect);
} else if (similarity >= RZ_ANALYSIS_SIMILARITY_THRESHOLD) {
item->setBackground(colors->partial);
} else {
item->setBackground(colors->none);
}
item->setForeground(Qt::black);
return item;
}
BinDiffDialog::BinDiffDialog(RzAnalysisMatchResult *result, QWidget *parent) : QDialog(parent), ui(new Ui::BinDiffDialog)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
void *ptr;
RzListIter *iter = nullptr;
RzAnalysisMatchPair *pair = nullptr;
const RzAnalysisFunction *fcn_a = nullptr, *fcn_b = nullptr;
const DiffColors colors = {
.perfect = Config()->getColor("gui.match.perfect"),
.partial = Config()->getColor("gui.match.partial"),
.none = Config()->getColor("gui.match.none"),
};
size_t n_raws = rz_list_length(result->matches);
n_raws += rz_list_length(result->unmatch_a);
n_raws += rz_list_length(result->unmatch_b);
QStringList tableHeader = {
tr("name"), tr("size"), tr("addr"),
tr("type"), tr("similarity"),
tr("addr"), tr("size"), tr("name")
};
ui->resultTable->setRowCount(n_raws);
ui->resultTable->setColumnCount(8);
ui->resultTable->setHorizontalHeaderLabels(tableHeader);
ui->resultTable->verticalHeader()->setVisible(false);
ui->resultTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
n_raws = 0;
rz_list_foreach(result->matches, iter, ptr) {
pair = static_cast<RzAnalysisMatchPair *>(ptr);
fcn_a = static_cast<const RzAnalysisFunction *>(pair->pair_a);
fcn_b = static_cast<const RzAnalysisFunction *>(pair->pair_b);
QString size_a = RzSizeString(rz_analysis_function_realsize(fcn_a));
QString size_b = RzSizeString(rz_analysis_function_realsize(fcn_b));
QString addr_a = RzAddressString(fcn_a->addr);
QString addr_b = RzAddressString(fcn_b->addr);
QString simtype = RZ_ANALYSIS_SIMILARITY_TYPE_STR(pair->similarity);
QString similarity = doubleToString(pair->similarity);
ui->resultTable->setItem(n_raws, ColumnSourceName, newColoredCell(fcn_a->name, pair->similarity, &colors));
ui->resultTable->setItem(n_raws, ColumnSourceSize, newColoredCell(size_a, pair->similarity, &colors));
ui->resultTable->setItem(n_raws, ColumnSourceAddr, newColoredCell(addr_a, pair->similarity, &colors));
ui->resultTable->setItem(n_raws, ColumnSimilarityType, newColoredCell(simtype, pair->similarity, &colors));
ui->resultTable->setItem(n_raws, ColumnSimilarityNum, newColoredCell(similarity, pair->similarity, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchAddr, newColoredCell(addr_b, pair->similarity, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchSize, newColoredCell(size_b, pair->similarity, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchName, newColoredCell(fcn_b->name, pair->similarity, &colors));
n_raws++;
}
rz_list_foreach(result->unmatch_a, iter, ptr) {
fcn_a = static_cast<RzAnalysisFunction *>(ptr);
QString size_a = RzSizeString(rz_analysis_function_realsize(fcn_a));
QString addr_a = RzAddressString(fcn_a->addr);
ui->resultTable->setItem(n_raws, ColumnSourceName, newColoredCell(fcn_a->name, 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnSourceSize, newColoredCell(size_a, 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnSourceAddr, newColoredCell(addr_a, 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnSimilarityType, newColoredCell(RZ_ANALYSIS_SIMILARITY_UNLIKE_STR, 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnSimilarityNum, newColoredCell("0.000000", 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchAddr, newColoredCell("------", 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchSize, newColoredCell("------", 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchName, newColoredCell("------", 0.0, &colors));
n_raws++;
}
rz_list_foreach(result->unmatch_b, iter, ptr) {
fcn_b = static_cast<RzAnalysisFunction *>(ptr);
QString size_b = RzSizeString(rz_analysis_function_realsize(fcn_b));
QString addr_b = RzAddressString(fcn_b->addr);
ui->resultTable->setItem(n_raws, ColumnSourceName, newColoredCell("------", 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnSourceSize, newColoredCell("------", 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnSourceAddr, newColoredCell("------", 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnSimilarityType, newColoredCell(RZ_ANALYSIS_SIMILARITY_UNLIKE_STR, 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnSimilarityNum, newColoredCell("0.000000", 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchAddr, newColoredCell(fcn_b->name, 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchSize, newColoredCell(size_b, 0.0, &colors));
ui->resultTable->setItem(n_raws, ColumnMatchName, newColoredCell(addr_b, 0.0, &colors));
n_raws++;
}
}
BinDiffDialog::~BinDiffDialog() {}
void BinDiffDialog::on_buttonBox_rejected()
{
close();
}

View File

@ -1,37 +0,0 @@
#ifndef BINDIFFDIALOG_H
#define BINDIFFDIALOG_H
#include <QDialog>
#include <memory>
#include <QtNetwork/QNetworkReply>
namespace Ui {
class BinDiffDialog;
}
class BinDiffDialog : public QDialog
{
Q_OBJECT
public:
explicit BinDiffDialog(RzAnalysisMatchResult *result, QWidget *parent = nullptr);
~BinDiffDialog();
private slots:
void on_buttonBox_rejected();
private:
enum {
ColumnSourceName = 0,
ColumnSourceSize,
ColumnSourceAddr,
ColumnSimilarityType,
ColumnSimilarityNum,
ColumnMatchAddr,
ColumnMatchSize,
ColumnMatchName
} BinDiffTableColumn;
std::unique_ptr<Ui::BinDiffDialog> ui;
};
#endif // BINDIFFDIALOG_H

View File

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BinDiffDialog</class>
<widget class="QDialog" name="BinDiffDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>935</width>
<height>554</height>
</rect>
</property>
<property name="windowTitle">
<string>Cutter Binary Diffing Tool</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1013</width>
<height>22</height>
</rect>
</property>
<property name="defaultUp">
<bool>false</bool>
</property>
<property name="nativeMenuBar">
<bool>true</bool>
</property>
<widget class="QMenu" name="menuExport">
<property name="title">
<string>Export</string>
</property>
</widget>
<addaction name="menuExport"/>
</widget>
</item>
<item>
<widget class="QTableWidget" name="resultTable"/>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -16,7 +16,7 @@ BaseFindDialog::BaseFindDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Ba
ui->nCoresCombo->clear();
for (size_t i = n_cores; i > 0; i--) {
if (n_cores == i) {
ui->nCoresCombo->addItem("All Cores");
ui->nCoresCombo->addItem(tr("All CPU Cores"));
continue;
}
ui->nCoresCombo->addItem(QString::number(i));

View File

@ -1,6 +1,8 @@
#include "DiffLoadDialog.h"
#include "ui_DiffLoadDialog.h"
#include "DiffWaitDialog.h"
#include <core/Cutter.h>
#include <rz_th.h>
@ -17,6 +19,13 @@ DiffLoadDialog::DiffLoadDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Di
ui->lineEditDiffFile->setReadOnly(true);
ui->lineEditDiffFile->setText("");
ui->comboBoxAnalysis->addItem(tr("Basic"));
ui->comboBoxAnalysis->addItem(tr("Auto"));
ui->comboBoxAnalysis->addItem(tr("Experimental"));
auto index = ui->comboBoxAnalysis->findData(tr("Auto"), Qt::DisplayRole);
ui->comboBoxAnalysis->setCurrentIndex(index);
}
DiffLoadDialog::~DiffLoadDialog() {}
@ -31,6 +40,11 @@ QString DiffLoadDialog::getPreviousDiffFile() const
return ui->lineEditDiffFile->text();
}
int DiffLoadDialog::getLevel() const
{
return ui->comboBoxAnalysis->currentIndex();
}
void DiffLoadDialog::on_buttonDiffOpen_clicked()
{
QFileDialog dialog(this);
@ -69,26 +83,9 @@ void DiffLoadDialog::on_buttonFileOpen_clicked()
ui->lineEditFileName->setText(fileName);
}
void DiffLoadDialog::openErrorBox(QString errorMessage)
{
QMessageBox mb(this);
mb.setIcon(QMessageBox::Warning);
mb.setStandardButtons(QMessageBox::Ok);
mb.setWindowTitle(tr("Error"));
mb.setText(errorMessage);
mb.exec();
}
void DiffLoadDialog::on_buttonBox_accepted()
{
QString fileName = getFileToOpen();
if (fileName.isEmpty()) {
openErrorBox(tr("The compare file was not selected."));
return;
}
emit startDiffing();
}
void DiffLoadDialog::on_buttonBox_rejected()
{
// cancel
}
void DiffLoadDialog::on_buttonBox_rejected() {}

View File

@ -21,6 +21,10 @@ public:
QString getFileToOpen() const;
QString getPreviousDiffFile() const;
int getLevel() const;
signals:
void startDiffing();
private slots:
void on_buttonDiffOpen_clicked();
@ -30,8 +34,6 @@ private slots:
private:
std::unique_ptr<Ui::DiffLoadDialog> ui;
void openErrorBox(QString errorMessage);
};
#endif // DIFF_LOAD_DIALOG_H

View File

@ -10,7 +10,7 @@
<x>0</x>
<y>0</y>
<width>636</width>
<height>142</height>
<height>184</height>
</rect>
</property>
<property name="sizePolicy">
@ -34,9 +34,6 @@
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditDiffFile"/>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditFileName"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="fileToCompareLabel">
<property name="sizePolicy">
@ -53,13 +50,6 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="buttonDiffOpen">
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="buttonFileOpen">
<property name="text">
@ -83,6 +73,26 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditFileName"/>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="buttonDiffOpen">
<property name="text">
<string>Select</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelAnalysisLevel">
<property name="text">
<string>Analysis Level</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBoxAnalysis"/>
</item>
</layout>
</item>
<item>

View File

@ -0,0 +1,106 @@
#include "DiffWaitDialog.h"
#include "ui_DiffWaitDialog.h"
#include <QTime>
#include <core/Cutter.h>
#include <rz_util.h>
DiffWaitDialog::DiffWaitDialog(QWidget *parent)
: QDialog(parent), timer(parent), bDiff(new BinDiff()), ui(new Ui::DiffWaitDialog)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
ui->lineEditNFuncs->setReadOnly(true);
ui->lineEditMatches->setReadOnly(true);
ui->lineEditEstimatedTime->setReadOnly(true);
ui->lineEditElapsedTime->setReadOnly(true);
ui->lineEditOriginal->setReadOnly(true);
ui->lineEditModified->setReadOnly(true);
ui->progressBar->setValue(0);
ui->lineEditNFuncs->setText("0");
ui->lineEditMatches->setText("0");
QTime zero(0, 0, 0, 0);
ui->lineEditElapsedTime->setText(zero.toString("hh:mm:ss"));
ui->lineEditEstimatedTime->setText(zero.toString("hh:mm:ss"));
}
DiffWaitDialog::~DiffWaitDialog()
{
if (bDiff->isRunning()) {
bDiff->cancel();
bDiff->wait();
}
}
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)
{
connect(this, &DiffWaitDialog::cancelJob, bDiff.get(), &BinDiff::cancel);
connect(bDiff.get(), &BinDiff::progress, this, &DiffWaitDialog::onProgress);
connect(bDiff.get(), &BinDiff::complete, this, &DiffWaitDialog::onCompletion);
connect(&timer, &QTimer::timeout, this, &DiffWaitDialog::updateElapsedTime);
ui->lineEditOriginal->setText(original);
ui->lineEditModified->setText(modified);
bDiff->setAnalysisLevel(level);
bDiff->setFile(modified);
eTimer.restart();
timer.setSingleShot(false);
timer.start(1000);
bDiff->start();
this->QDialog::show();
}
void DiffWaitDialog::onProgress(BinDiffStatusDescription status)
{
int partial = status.total - status.nLeft;
ut32 progress = (100 * partial) / status.total;
ui->progressBar->setValue(progress);
ui->lineEditNFuncs->setText(QString::asprintf("%lu", status.nLeft));
ui->lineEditMatches->setText(QString::asprintf("%lu", status.nMatch));
double speed = ((double)partial) / ((double)eTimer.elapsed());
ut64 seconds = (((double)status.nLeft) / speed) / 1000ull;
int hours = seconds / 3600;
seconds -= (hours * 3600);
int minutes = seconds / 60;
seconds = seconds % 60;
QTime estimated(hours, minutes, seconds, 0);
ui->lineEditEstimatedTime->setText(estimated.toString("hh:mm:ss"));
}
void DiffWaitDialog::onCompletion()
{
timer.stop();
}
void DiffWaitDialog::updateElapsedTime()
{
ut64 seconds = eTimer.elapsed() / 1000ull;
int hours = seconds / 3600;
seconds -= (hours * 3600);
int minutes = seconds / 60;
seconds = seconds % 60;
QTime current(hours, minutes, seconds, 0);
ui->lineEditElapsedTime->setText(current.toString("hh:mm:ss"));
}
void DiffWaitDialog::on_buttonBox_rejected()
{
timer.stop();
emit cancelJob();
}

View File

@ -0,0 +1,48 @@
#ifndef DIFF_WAIT_DIALOG_H
#define DIFF_WAIT_DIALOG_H
#include <QDialog>
#include <QListWidgetItem>
#include <QProgressBar>
#include <QTimer>
#include <QElapsedTimer>
#include <memory>
#include <core/Cutter.h>
namespace Ui {
class DiffWaitDialog;
}
class DiffWaitDialog : public QDialog
{
Q_OBJECT
public:
explicit DiffWaitDialog(QWidget *parent = nullptr);
~DiffWaitDialog();
void show(QString original, QString modified, int level);
QList<BinDiffMatchDescription> matches();
QList<FunctionDescription> mismatch(bool fileA);
public slots:
void onProgress(BinDiffStatusDescription status);
void onCompletion();
void updateElapsedTime();
signals:
void cancelJob();
private slots:
void on_buttonBox_rejected();
private:
QElapsedTimer eTimer;
QTimer timer;
std::unique_ptr<BinDiff> bDiff;
std::unique_ptr<Ui::DiffWaitDialog> ui;
};
#endif // DIFF_WAIT_DIALOG_H

View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DiffWaitDialog</class>
<widget class="QDialog" name="DiffWaitDialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>524</width>
<height>342</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">Performing binary diffing</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<layout class="QVBoxLayout" name="mainVerticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>24</number>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="1">
<widget class="QLineEdit" name="lineEditElapsedTime"/>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEditModified"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelElapsedTime">
<property name="text">
<string>Elapsed Time</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelModified">
<property name="text">
<string>Modified File</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="labelMatches">
<property name="text">
<string>Matches</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEditOriginal"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelOrignal">
<property name="text">
<string>Original File</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEditNFuncs"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelNFuncs">
<property name="text">
<string>Functions left to compare</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEditMatches"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelEstimatedTime">
<property name="text">
<string>Estimated Time</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEditEstimatedTime"/>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<action name="actionRemoveItem">
<property name="text">
<string>Remove item</string>
</property>
</action>
<action name="actionRemoveAll">
<property name="text">
<string>Remove all</string>
</property>
<property name="toolTip">
<string>Remove all</string>
</property>
</action>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>DiffWaitDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>240</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>254</y>
</hint>
</hints>
</connection>
</connections>
</ui>