diff --git a/.appveyor.yml b/.appveyor.yml index 1652bbb4..ca0905a9 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -17,9 +17,9 @@ branches: environment: PYTHON: 'C:\Python36-x64' NINJA_URL: https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-win.zip - QTDIR: 'C:\Qt\5.9.2\msvc2015_64' - QT32PATH: 'C:\Qt\5.9.2\msvc2015' - QT64PATH: 'C:\Qt\5.9.2\msvc2015_64' + QTDIR: 'C:\Qt\5.10.0\msvc2015_64' + QT32PATH: 'C:\Qt\5.10.0\msvc2015' + QT64PATH: 'C:\Qt\5.10.0\msvc2015_64' VSVARSALLPATH: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat' matrix: - BITS: 32 diff --git a/src/AnalThread.cpp b/src/AnalThread.cpp index 73e8d82b..cb9adf6f 100644 --- a/src/AnalThread.cpp +++ b/src/AnalThread.cpp @@ -3,6 +3,7 @@ #include "AnalThread.h" #include "MainWindow.h" #include "dialogs/OptionsDialog.h" +#include AnalThread::AnalThread(OptionsDialog *parent) : QThread(parent), @@ -46,9 +47,9 @@ void AnalThread::run() core->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(), optionsDialog->getSelectedBits()); bool rw = false; - bool load_bininfo = ui->binCheckBox->isChecked(); + bool loadBinInfo = ui->binCheckBox->isChecked(); - if (load_bininfo) + if (loadBinInfo) { if (!va) { @@ -78,7 +79,12 @@ void AnalThread::run() core->setConfig("bin.demangle", ui->demangleCheckBox->isChecked()); - core->loadFile(main->getFilename(), loadaddr, mapaddr, rw, va, binidx, load_bininfo, forceBinPlugin); + QJsonArray openedFiles = Core()->getOpenedFiles(); + qDebug() << openedFiles << openedFiles.size(); + if (!openedFiles.size()) + { + core->loadFile(main->getFilename(), loadaddr, mapaddr, rw, va, binidx, loadBinInfo, forceBinPlugin); + } emit updateProgress("Analysis in progress."); QString os = optionsDialog->getSelectedOS(); @@ -92,10 +98,10 @@ void AnalThread::run() core->loadPDB(ui->pdbLineEdit->text()); } - if (optionsDialog->getSelectedEndianness() != OptionsDialog::Endianness::Auto) - { - core->setEndianness(optionsDialog->getSelectedEndianness() == OptionsDialog::Endianness::Big); - } + if (optionsDialog->getSelectedEndianness() != OptionsDialog::Endianness::Auto) + { + core->setEndianness(optionsDialog->getSelectedEndianness() == OptionsDialog::Endianness::Big); + } // use prj.simple as default as long as regular projects are broken core->setConfig("prj.simple", true); diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 9720ad95..b91d928a 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -277,7 +277,7 @@ void MainWindow::initUI() connect(core, SIGNAL(projectSaved(const QString &)), this, SLOT(projectSaved(const QString &))); } -void MainWindow::openNewFile(const QString &fn, int anal_level, QList advanced) +void MainWindow::openNewFile(const QString &fn, int analLevel, QList advancedOptions) { setFilename(fn); @@ -297,13 +297,18 @@ void MainWindow::openNewFile(const QString &fn, int anal_level, QList a } /* Show analysis options dialog */ + displayAnalysisOptionsDialog(analLevel, advancedOptions); +} + +void MainWindow::displayAnalysisOptionsDialog(int analLevel, QList advancedOptions) +{ OptionsDialog *o = new OptionsDialog(this); o->setAttribute(Qt::WA_DeleteOnClose); o->show(); - if (anal_level >= 0) + if (analLevel >= 0) { - o->setupAndStartAnalysis(anal_level, advanced); + o->setupAndStartAnalysis(analLevel, advancedOptions); } } @@ -787,6 +792,11 @@ void MainWindow::on_actionRefresh_Panels_triggered() this->refreshAll(); } +void MainWindow::on_actionAnalyze_triggered() +{ + displayAnalysisOptionsDialog(-1, QList()); +} + void MainWindow::on_actionImportPDB_triggered() { QFileDialog dialog(this); diff --git a/src/MainWindow.h b/src/MainWindow.h index 4dad9c7e..21b405a8 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -56,7 +56,8 @@ public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - void openNewFile(const QString &fn, int anal_level = -1, QList advanced = QList()); + void openNewFile(const QString &fn, int analLevel = -1, QList advancedOptions = QList()); + void displayAnalysisOptionsDialog(int analLevel, QList advancedOptions); void openProject(const QString &project_name); void initUI(); @@ -137,6 +138,8 @@ private slots: void on_actionPreferences_triggered(); + void on_actionAnalyze_triggered(); + void on_actionImportPDB_triggered(); void projectSaved(const QString &name); diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 0db596b8..db10b492 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -181,7 +181,7 @@ border-top: 0px; 346 97 148 - 215 + 238 @@ -190,6 +190,7 @@ border-top: 0px; + @@ -1035,6 +1036,11 @@ QToolButton:pressed { Import PDB + + + Analyze + + diff --git a/src/cutter.cpp b/src/cutter.cpp index 60011789..7af54bbe 100644 --- a/src/cutter.cpp +++ b/src/cutter.cpp @@ -157,7 +157,7 @@ QString CutterCore::cmd(const QString &str) { emit seekChanged(core_->offset); - // switch from graph to disassembly if there is no function + // Switch from graph to disassembly if there is no function if (this->cmd("afi.").trimmed().isEmpty() && memoryWidgetPriority == MemoryWidgetType::Graph) { memoryWidgetPriority = MemoryWidgetType::Disassembly; @@ -273,8 +273,8 @@ void CutterCore::analyze(int level, QList advanced) CORE_LOCK(); /* * Levels - * Nivel 1: aaa - * Nivel 2: aaaa + * Level 1: aaa + * Level 2: aaaa */ if (level == 1) @@ -533,19 +533,6 @@ QString CutterCore::getConfig(const QString &k) return QString(r_config_get(core_->config, key.constData())); } -void CutterCore::setOptions(QString key) -{ - Q_UNUSED(key); - - // va - // lowercase - // show bytes - // att syntax - // asm plugin - // cpu type - // anal plugin -} - void CutterCore::setCPU(QString arch, QString cpu, int bits, bool temporary) { setConfig("asm.arch", arch); @@ -1377,3 +1364,9 @@ QString CutterCore::getVersionInformation() } return ret; } + +QJsonArray CutterCore::getOpenedFiles() +{ + QJsonDocument files = cmdj("oj"); + return files.array(); +} diff --git a/src/cutter.h b/src/cutter.h index 372b3a49..9c61b06e 100644 --- a/src/cutter.h +++ b/src/cutter.h @@ -245,7 +245,6 @@ public: void setImmediateBase(const QString &r2BaseName, RVA offset = RVA_INVALID); - void setOptions(QString key); bool loadFile(QString path, uint64_t loadaddr = 0LL, uint64_t mapaddr = 0LL, bool rw = false, int va = 0, int idx = 0, bool loadbin = false, const QString &forceBinPlugin = nullptr); bool tryFile(QString path, bool rw); void analyze(int level, QList advanced); @@ -361,6 +360,7 @@ public: void loadScript(const QString &scriptname); QString getVersionInformation(); + QJsonArray getOpenedFiles(); RCoreLocked core() const; diff --git a/src/dialogs/OptionsDialog.cpp b/src/dialogs/OptionsDialog.cpp index df7f2e16..887ca019 100644 --- a/src/dialogs/OptionsDialog.cpp +++ b/src/dialogs/OptionsDialog.cpp @@ -11,7 +11,6 @@ #include #include -// TODO Get rid of MainWindow OptionsDialog::OptionsDialog(MainWindow *main): QDialog(0), // parent may not be main analThread(this), @@ -151,7 +150,6 @@ void OptionsDialog::setupAndStartAnalysis(int level, QList advanced) ui->elapsedLabel->setVisible(true); ui->statusLabel->setText(tr("Starting analysis")); - //ui->progressBar->setValue(5); main->initUI(); @@ -164,8 +162,7 @@ void OptionsDialog::setupAndStartAnalysis(int level, QList advanced) updateProgressTimer(); connect(&analTimer, SIGNAL(timeout()), this, SLOT(updateProgressTimer())); - // Threads stuff - // connect signal/slot + // Threads stuff, connect signal/slot connect(&analThread, &AnalThread::updateProgress, this, &OptionsDialog::updateProgress); analThread.start(main, level, advanced); } diff --git a/src/main.cpp b/src/main.cpp index d3c84c19..eff57a88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,10 +52,10 @@ int main(int argc, char *argv[]) cmd_parser.addVersionOption(); cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open.")); - QCommandLineOption anal_option({"A", "anal"}, + QCommandLineOption analOption({"A", "anal"}, QObject::tr("Automatically open file and optionally start analysis. Needs filename to be specified. May be a value between 0 and 2: 0 = no analysis, 1 = aaa, 2 = aaaa (experimental)"), QObject::tr("level")); - cmd_parser.addOption(anal_option); + cmd_parser.addOption(analOption); cmd_parser.process(a); @@ -75,14 +75,14 @@ int main(int argc, char *argv[]) return 1; } - bool anal_level_specified = false; - int anal_level = 0; + bool analLevelSpecified = false; + int analLevel= 0; - if (cmd_parser.isSet(anal_option)) + if (cmd_parser.isSet(analOption)) { - anal_level = cmd_parser.value(anal_option).toInt(&anal_level_specified); + analLevel = cmd_parser.value(analOption).toInt(&analLevelSpecified); - if (!anal_level_specified || anal_level < 0 || anal_level > 2) + if (!analLevelSpecified || analLevel < 0 || analLevel > 2) { printf("%s\n", QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.").toLocal8Bit().constData()); return 1; @@ -92,7 +92,7 @@ int main(int argc, char *argv[]) if (args.empty()) { - if (anal_level_specified) + if (analLevelSpecified) { printf("%s\n", QObject::tr("Filename must be specified to start analysis automatically.").toLocal8Bit().constData()); return 1; @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) else // filename specified as positional argument { MainWindow *main = new MainWindow(); - main->openNewFile(args[0], anal_level_specified ? anal_level : -1); + main->openNewFile(args[0], analLevelSpecified ? analLevel : -1); } // Hack to make it work with AppImage