mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-19 02:48:49 +00:00
Use AsyncTaskDialog for initial Analysis
This commit is contained in:
parent
896925736f
commit
3e8b76138c
@ -6,10 +6,8 @@
|
||||
#include <QDebug>
|
||||
#include <QCheckBox>
|
||||
|
||||
AnalTask::AnalTask(OptionsDialog *parent) :
|
||||
AsyncTask(parent),
|
||||
level(2),
|
||||
main(nullptr)
|
||||
AnalTask::AnalTask(QObject *parent) :
|
||||
AsyncTask(parent)
|
||||
{
|
||||
}
|
||||
|
||||
@ -17,13 +15,6 @@ AnalTask::~AnalTask()
|
||||
{
|
||||
}
|
||||
|
||||
void AnalTask::setSettings(MainWindow *main, int level, QList<QString> advanced)
|
||||
{
|
||||
this->main = main;
|
||||
this->level = level;
|
||||
this->advanced = advanced;
|
||||
}
|
||||
|
||||
void AnalTask::interrupt()
|
||||
{
|
||||
AsyncTask::interrupt();
|
||||
@ -39,42 +30,27 @@ void AnalTask::interruptAndWait()
|
||||
|
||||
void AnalTask::runTask()
|
||||
{
|
||||
const auto optionsDialog = dynamic_cast<OptionsDialog *>(parent());
|
||||
const auto &ui = optionsDialog->ui;
|
||||
bool va = ui->vaCheckBox->isChecked();
|
||||
ut64 binLoadAddr = UT64_MAX; // Where the bin header is located in the file (-B)
|
||||
if (ui->entry_loadOffset->text().length() > 0)
|
||||
binLoadAddr = Core()->math(ui->entry_loadOffset->text());
|
||||
ut64 mapAddr = Core()->math(ui->entry_mapOffset->text()); // Where to map the file once loaded (-m)
|
||||
|
||||
log(tr("Loading Binary...\n"));
|
||||
|
||||
// Set the CPU details (handle auto)
|
||||
Core()->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(),
|
||||
optionsDialog->getSelectedBits());
|
||||
Core()->setCPU(options.arch, options.cpu, options.bits);
|
||||
|
||||
// Binary opening permissions (read/write/execute)
|
||||
int perms = R_IO_READ | R_IO_EXEC;
|
||||
if (ui->writeCheckBox->isChecked())
|
||||
if (options.writeEnabled)
|
||||
perms |= R_IO_WRITE;
|
||||
|
||||
// Check if we must load and parse binary header (ELF, PE, ...)
|
||||
bool loadBinInfo = !ui->binCheckBox->isChecked();
|
||||
QString forceBinPlugin = nullptr;
|
||||
QVariant forceBinPluginData = ui->formatComboBox->currentData();
|
||||
if (!forceBinPluginData.isNull()) {
|
||||
RBinPluginDescription pluginDesc = forceBinPluginData.value<RBinPluginDescription>();
|
||||
forceBinPlugin = pluginDesc.name;
|
||||
}
|
||||
|
||||
// Demangle (must be before file Core()->loadFile)
|
||||
Core()->setConfig("bin.demangle", ui->demangleCheckBox->isChecked());
|
||||
Core()->setConfig("bin.demangle", options.demangle);
|
||||
|
||||
// Do not reload the file if already loaded
|
||||
QJsonArray openedFiles = Core()->getOpenedFiles();
|
||||
if (!openedFiles.size()) {
|
||||
bool fileLoaded = Core()->loadFile(main->getFilename(), binLoadAddr, mapAddr, perms, va, loadBinInfo,
|
||||
forceBinPlugin);
|
||||
bool fileLoaded = Core()->loadFile(options.filename,
|
||||
options.binLoadAddr,
|
||||
options.mapAddr,
|
||||
perms,
|
||||
options.useVA,
|
||||
options.loadBinInfo,
|
||||
options.forceBinPlugin);
|
||||
if (!fileLoaded) {
|
||||
// Something wrong happened, fallback to open dialog
|
||||
emit openFileFailed();
|
||||
@ -83,32 +59,32 @@ void AnalTask::runTask()
|
||||
}
|
||||
}
|
||||
|
||||
// Set asm OS configuration
|
||||
QString os = optionsDialog->getSelectedOS();
|
||||
if (!os.isNull()) {
|
||||
Core()->cmd("e asm.os=" + os);
|
||||
if (!options.os.isNull()) {
|
||||
Core()->cmd("e asm.os=" + options.os);
|
||||
}
|
||||
|
||||
// Load PDB and/or scripts
|
||||
if (ui->pdbCheckBox->isChecked()) {
|
||||
Core()->loadPDB(ui->pdbLineEdit->text());
|
||||
}
|
||||
if (ui->scriptCheckBox->isChecked()) {
|
||||
Core()->loadScript(ui->scriptLineEdit->text());
|
||||
if (!options.pdbFile.isNull()) {
|
||||
Core()->loadPDB(options.pdbFile);
|
||||
}
|
||||
|
||||
// Set various options
|
||||
if (optionsDialog->getSelectedEndianness() != OptionsDialog::Endianness::Auto) {
|
||||
Core()->setEndianness(optionsDialog->getSelectedEndianness() == OptionsDialog::Endianness::Big);
|
||||
if (!options.script.isNull()) {
|
||||
Core()->loadScript(options.script);
|
||||
}
|
||||
Core()->setBBSize(optionsDialog->getSelectedBBSize());
|
||||
|
||||
if (options.endian != InitialOptions::Endianness::Auto) {
|
||||
Core()->setEndianness(options.endian == InitialOptions::Endianness::Big);
|
||||
}
|
||||
|
||||
Core()->setBBSize(options.bbsize);
|
||||
|
||||
// Use prj.simple as default as long as regular projects are broken
|
||||
Core()->setConfig("prj.simple", true);
|
||||
|
||||
// Start analysis
|
||||
log(tr("Analysis in progress...\n"));
|
||||
|
||||
Core()->analyze(this->level, this->advanced);
|
||||
Core()->analyze(options.analLevel, options.analAdvanced);
|
||||
|
||||
log(tr("Analysis complete!"));
|
||||
}
|
||||
|
@ -2,20 +2,56 @@
|
||||
#define ANALTHREAD_H
|
||||
|
||||
#include "utils/AsyncTask.h"
|
||||
#include "Cutter.h"
|
||||
|
||||
class CutterCore;
|
||||
class MainWindow;
|
||||
class OptionsDialog;
|
||||
|
||||
struct InitialOptions
|
||||
{
|
||||
enum class Endianness { Auto, Little, Big };
|
||||
|
||||
QString filename;
|
||||
|
||||
bool useVA = true;
|
||||
RVA binLoadAddr = RVA_INVALID;
|
||||
RVA mapAddr = RVA_INVALID;
|
||||
|
||||
QString arch;
|
||||
QString cpu;
|
||||
int bits = 0;
|
||||
QString os;
|
||||
|
||||
Endianness endian;
|
||||
|
||||
bool writeEnabled = false;
|
||||
bool loadBinInfo = true;
|
||||
QString forceBinPlugin;
|
||||
|
||||
bool demangle = true;
|
||||
|
||||
QString pdbFile;
|
||||
QString script;
|
||||
|
||||
int bbsize = 0;
|
||||
|
||||
int analLevel = 1;
|
||||
QList<QString> analAdvanced;
|
||||
};
|
||||
|
||||
class AnalTask : public AsyncTask
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AnalTask(OptionsDialog *parent = nullptr);
|
||||
explicit AnalTask(QObject *parent = nullptr);
|
||||
~AnalTask();
|
||||
|
||||
void setSettings(MainWindow *main, int level, QList<QString> advanced);
|
||||
QString getTitle() override { return tr("Initial Analysis"); }
|
||||
|
||||
void setOptions(const InitialOptions &options) { this->options = options; }
|
||||
|
||||
void interrupt() override;
|
||||
void interruptAndWait();
|
||||
|
||||
@ -26,9 +62,7 @@ signals:
|
||||
void openFileFailed();
|
||||
|
||||
private:
|
||||
int level;
|
||||
QList<QString> advanced;
|
||||
MainWindow *main;
|
||||
InitialOptions options;
|
||||
};
|
||||
|
||||
#endif // ANALTHREAD_H
|
||||
|
@ -71,7 +71,6 @@ public:
|
||||
void openProject(const QString &project_name);
|
||||
|
||||
void initUI();
|
||||
void finalizeOpen();
|
||||
|
||||
/*!
|
||||
* @param quit whether to show destructive button in dialog
|
||||
@ -99,6 +98,7 @@ public:
|
||||
|
||||
|
||||
public slots:
|
||||
void finalizeOpen();
|
||||
|
||||
void refreshAll();
|
||||
|
||||
|
@ -18,6 +18,7 @@ AsyncTaskDialog::AsyncTaskDialog(AsyncTask *task, QWidget *parent)
|
||||
}
|
||||
|
||||
connect(task, &AsyncTask::logChanged, this, &AsyncTaskDialog::updateLog);
|
||||
connect(task, &AsyncTask::finished, this, &QWidget::close);
|
||||
|
||||
updateLog();
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
OptionsDialog::OptionsDialog(MainWindow *main):
|
||||
QDialog(0), // parent may not be main
|
||||
analTask(this),
|
||||
main(main),
|
||||
core(Core()),
|
||||
defaultAnalLevel(1),
|
||||
@ -62,7 +61,7 @@ OptionsDialog::OptionsDialog(MainWindow *main):
|
||||
// Add this so the dialog resizes when widgets are shown/hidden
|
||||
//this->layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
connect(&analTask, SIGNAL(finished()), this, SLOT(analysisFinished()));
|
||||
//connect(&analTask, SIGNAL(finished()), this, SLOT(analysisFinished()));
|
||||
connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
|
||||
ui->programLineEdit->setText(main->getFilename());
|
||||
@ -128,15 +127,15 @@ int OptionsDialog::getSelectedBBSize()
|
||||
return 1024;
|
||||
}
|
||||
|
||||
OptionsDialog::Endianness OptionsDialog::getSelectedEndianness()
|
||||
InitialOptions::Endianness OptionsDialog::getSelectedEndianness()
|
||||
{
|
||||
switch (ui->endiannessComboBox->currentIndex()) {
|
||||
case 1:
|
||||
return Endianness::Little;
|
||||
return InitialOptions::Endianness::Little;
|
||||
case 2:
|
||||
return Endianness::Big;
|
||||
return InitialOptions::Endianness::Big;
|
||||
default:
|
||||
return Endianness::Auto;
|
||||
return InitialOptions::Endianness::Auto;
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,12 +160,50 @@ void OptionsDialog::setupAndStartAnalysis(int level, QList<QString> advanced)
|
||||
|
||||
main->initUI();
|
||||
|
||||
connect(&analTask, &AnalTask::openFileFailed, main, &MainWindow::openNewFileFailed);
|
||||
analTask.setSettings(main, level, advanced);
|
||||
Core()->getAsyncTaskManager()->start(&analTask);
|
||||
InitialOptions options;
|
||||
|
||||
AsyncTaskDialog *taskDialog = new AsyncTaskDialog(&analTask, main);
|
||||
options.filename = main->getFilename();
|
||||
|
||||
// Where the bin header is located in the file (-B)
|
||||
if (ui->entry_loadOffset->text().length() > 0) {
|
||||
options.binLoadAddr = Core()->math(ui->entry_loadOffset->text());
|
||||
}
|
||||
|
||||
options.mapAddr = Core()->math(ui->entry_mapOffset->text()); // Where to map the file once loaded (-m)
|
||||
options.arch = getSelectedArch();
|
||||
options.cpu = getSelectedCPU();
|
||||
options.bits = getSelectedBits();
|
||||
options.os = getSelectedOS();
|
||||
options.writeEnabled = ui->writeCheckBox->isChecked();
|
||||
options.loadBinInfo = !ui->binCheckBox->isChecked();
|
||||
QVariant forceBinPluginData = ui->formatComboBox->currentData();
|
||||
if (!forceBinPluginData.isNull()) {
|
||||
RBinPluginDescription pluginDesc = forceBinPluginData.value<RBinPluginDescription>();
|
||||
options.forceBinPlugin = pluginDesc.name;
|
||||
}
|
||||
options.demangle = ui->demangleCheckBox->isChecked();
|
||||
if (ui->pdbCheckBox->isChecked()) {
|
||||
options.pdbFile = ui->pdbLineEdit->text();
|
||||
}
|
||||
if (ui->scriptCheckBox->isChecked()) {
|
||||
options.script = ui->scriptLineEdit->text();
|
||||
}
|
||||
options.endian = getSelectedEndianness();
|
||||
options.bbsize = getSelectedBBSize();
|
||||
|
||||
AnalTask *analTask = new AnalTask(main);
|
||||
analTask->setOptions(options);
|
||||
|
||||
connect(analTask, &AnalTask::openFileFailed, main, &MainWindow::openNewFileFailed);
|
||||
connect(analTask, &AsyncTask::finished, main, &MainWindow::finalizeOpen);
|
||||
|
||||
Core()->getAsyncTaskManager()->start(analTask);
|
||||
|
||||
AsyncTaskDialog *taskDialog = new AsyncTaskDialog(analTask);
|
||||
taskDialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
taskDialog->show();
|
||||
|
||||
done(0);
|
||||
}
|
||||
|
||||
|
||||
@ -225,11 +262,11 @@ void OptionsDialog::on_okButton_clicked()
|
||||
|
||||
void OptionsDialog::analysisFinished()
|
||||
{
|
||||
if (analTask.isInterrupted()) {
|
||||
updateProgress(tr("Analysis aborted."));
|
||||
done(1);
|
||||
return;
|
||||
}
|
||||
//if (analTask.isInterrupted()) {
|
||||
// updateProgress(tr("Analysis aborted."));
|
||||
// done(1);
|
||||
// return;
|
||||
//}
|
||||
|
||||
updateProgress(tr("Loading interface..."));
|
||||
main->addOutput(tr(" > Analysis finished"));
|
||||
@ -240,9 +277,9 @@ void OptionsDialog::analysisFinished()
|
||||
|
||||
void OptionsDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
if (analTask.isRunning()) {
|
||||
analTask.interruptAndWait();
|
||||
}
|
||||
//if (analTask.isRunning()) {
|
||||
// analTask.interruptAndWait();
|
||||
//}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,6 @@ protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
AnalTask analTask;
|
||||
MainWindow *main;
|
||||
CutterCore *core;
|
||||
int defaultAnalLevel;
|
||||
@ -56,15 +55,13 @@ private:
|
||||
void setInteractionEnabled(bool enabled);
|
||||
|
||||
public:
|
||||
enum class Endianness { Auto, Little, Big };
|
||||
|
||||
std::unique_ptr<Ui::OptionsDialog> ui;
|
||||
|
||||
QString getSelectedArch();
|
||||
QString getSelectedCPU();
|
||||
int getSelectedBits();
|
||||
int getSelectedBBSize();
|
||||
Endianness getSelectedEndianness();
|
||||
InitialOptions::Endianness getSelectedEndianness();
|
||||
QString getSelectedOS();
|
||||
|
||||
void reject() override;
|
||||
|
@ -5,7 +5,7 @@ AsyncTask::AsyncTask(QObject *parent)
|
||||
: QObject(parent),
|
||||
QRunnable()
|
||||
{
|
||||
setAutoDelete(false);
|
||||
setAutoDelete(true);
|
||||
running = false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user