mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-28 15:55:26 +00:00
WIP Analysis panel after file is opened (#278)
* WIP Analysis panel after file is opened
This commit is contained in:
parent
9847836d73
commit
12316714cf
@ -17,9 +17,9 @@ branches:
|
|||||||
environment:
|
environment:
|
||||||
PYTHON: 'C:\Python36-x64'
|
PYTHON: 'C:\Python36-x64'
|
||||||
NINJA_URL: https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-win.zip
|
NINJA_URL: https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-win.zip
|
||||||
QTDIR: 'C:\Qt\5.9.2\msvc2015_64'
|
QTDIR: 'C:\Qt\5.10.0\msvc2015_64'
|
||||||
QT32PATH: 'C:\Qt\5.9.2\msvc2015'
|
QT32PATH: 'C:\Qt\5.10.0\msvc2015'
|
||||||
QT64PATH: 'C:\Qt\5.9.2\msvc2015_64'
|
QT64PATH: 'C:\Qt\5.10.0\msvc2015_64'
|
||||||
VSVARSALLPATH: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat'
|
VSVARSALLPATH: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat'
|
||||||
matrix:
|
matrix:
|
||||||
- BITS: 32
|
- BITS: 32
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "AnalThread.h"
|
#include "AnalThread.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "dialogs/OptionsDialog.h"
|
#include "dialogs/OptionsDialog.h"
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
AnalThread::AnalThread(OptionsDialog *parent) :
|
AnalThread::AnalThread(OptionsDialog *parent) :
|
||||||
QThread(parent),
|
QThread(parent),
|
||||||
@ -46,9 +47,9 @@ void AnalThread::run()
|
|||||||
core->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(), optionsDialog->getSelectedBits());
|
core->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(), optionsDialog->getSelectedBits());
|
||||||
|
|
||||||
bool rw = false;
|
bool rw = false;
|
||||||
bool load_bininfo = ui->binCheckBox->isChecked();
|
bool loadBinInfo = ui->binCheckBox->isChecked();
|
||||||
|
|
||||||
if (load_bininfo)
|
if (loadBinInfo)
|
||||||
{
|
{
|
||||||
if (!va)
|
if (!va)
|
||||||
{
|
{
|
||||||
@ -78,7 +79,12 @@ void AnalThread::run()
|
|||||||
|
|
||||||
core->setConfig("bin.demangle", ui->demangleCheckBox->isChecked());
|
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.");
|
emit updateProgress("Analysis in progress.");
|
||||||
|
|
||||||
QString os = optionsDialog->getSelectedOS();
|
QString os = optionsDialog->getSelectedOS();
|
||||||
@ -92,10 +98,10 @@ void AnalThread::run()
|
|||||||
core->loadPDB(ui->pdbLineEdit->text());
|
core->loadPDB(ui->pdbLineEdit->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optionsDialog->getSelectedEndianness() != OptionsDialog::Endianness::Auto)
|
if (optionsDialog->getSelectedEndianness() != OptionsDialog::Endianness::Auto)
|
||||||
{
|
{
|
||||||
core->setEndianness(optionsDialog->getSelectedEndianness() == OptionsDialog::Endianness::Big);
|
core->setEndianness(optionsDialog->getSelectedEndianness() == OptionsDialog::Endianness::Big);
|
||||||
}
|
}
|
||||||
|
|
||||||
// use prj.simple as default as long as regular projects are broken
|
// use prj.simple as default as long as regular projects are broken
|
||||||
core->setConfig("prj.simple", true);
|
core->setConfig("prj.simple", true);
|
||||||
|
@ -277,7 +277,7 @@ void MainWindow::initUI()
|
|||||||
connect(core, SIGNAL(projectSaved(const QString &)), this, SLOT(projectSaved(const QString &)));
|
connect(core, SIGNAL(projectSaved(const QString &)), this, SLOT(projectSaved(const QString &)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::openNewFile(const QString &fn, int anal_level, QList<QString> advanced)
|
void MainWindow::openNewFile(const QString &fn, int analLevel, QList<QString> advancedOptions)
|
||||||
{
|
{
|
||||||
setFilename(fn);
|
setFilename(fn);
|
||||||
|
|
||||||
@ -297,13 +297,18 @@ void MainWindow::openNewFile(const QString &fn, int anal_level, QList<QString> a
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Show analysis options dialog */
|
/* Show analysis options dialog */
|
||||||
|
displayAnalysisOptionsDialog(analLevel, advancedOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::displayAnalysisOptionsDialog(int analLevel, QList<QString> advancedOptions)
|
||||||
|
{
|
||||||
OptionsDialog *o = new OptionsDialog(this);
|
OptionsDialog *o = new OptionsDialog(this);
|
||||||
o->setAttribute(Qt::WA_DeleteOnClose);
|
o->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
o->show();
|
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();
|
this->refreshAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionAnalyze_triggered()
|
||||||
|
{
|
||||||
|
displayAnalysisOptionsDialog(-1, QList<QString>());
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::on_actionImportPDB_triggered()
|
void MainWindow::on_actionImportPDB_triggered()
|
||||||
{
|
{
|
||||||
QFileDialog dialog(this);
|
QFileDialog dialog(this);
|
||||||
|
@ -56,7 +56,8 @@ public:
|
|||||||
explicit MainWindow(QWidget *parent = 0);
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
void openNewFile(const QString &fn, int anal_level = -1, QList<QString> advanced = QList<QString>());
|
void openNewFile(const QString &fn, int analLevel = -1, QList<QString> advancedOptions = QList<QString>());
|
||||||
|
void displayAnalysisOptionsDialog(int analLevel, QList<QString> advancedOptions);
|
||||||
void openProject(const QString &project_name);
|
void openProject(const QString &project_name);
|
||||||
|
|
||||||
void initUI();
|
void initUI();
|
||||||
@ -137,6 +138,8 @@ private slots:
|
|||||||
|
|
||||||
void on_actionPreferences_triggered();
|
void on_actionPreferences_triggered();
|
||||||
|
|
||||||
|
void on_actionAnalyze_triggered();
|
||||||
|
|
||||||
void on_actionImportPDB_triggered();
|
void on_actionImportPDB_triggered();
|
||||||
|
|
||||||
void projectSaved(const QString &name);
|
void projectSaved(const QString &name);
|
||||||
|
@ -181,7 +181,7 @@ border-top: 0px;
|
|||||||
<x>346</x>
|
<x>346</x>
|
||||||
<y>97</y>
|
<y>97</y>
|
||||||
<width>148</width>
|
<width>148</width>
|
||||||
<height>215</height>
|
<height>238</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -190,6 +190,7 @@ border-top: 0px;
|
|||||||
<addaction name="actionNew"/>
|
<addaction name="actionNew"/>
|
||||||
<addaction name="actionOpen"/>
|
<addaction name="actionOpen"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionAnalyze"/>
|
||||||
<addaction name="actionImportPDB"/>
|
<addaction name="actionImportPDB"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionSave"/>
|
<addaction name="actionSave"/>
|
||||||
@ -1035,6 +1036,11 @@ QToolButton:pressed {
|
|||||||
<string>Import PDB</string>
|
<string>Import PDB</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionAnalyze">
|
||||||
|
<property name="text">
|
||||||
|
<string>Analyze</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources>
|
<resources>
|
||||||
|
@ -157,7 +157,7 @@ QString CutterCore::cmd(const QString &str)
|
|||||||
{
|
{
|
||||||
emit seekChanged(core_->offset);
|
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)
|
if (this->cmd("afi.").trimmed().isEmpty() && memoryWidgetPriority == MemoryWidgetType::Graph)
|
||||||
{
|
{
|
||||||
memoryWidgetPriority = MemoryWidgetType::Disassembly;
|
memoryWidgetPriority = MemoryWidgetType::Disassembly;
|
||||||
@ -273,8 +273,8 @@ void CutterCore::analyze(int level, QList<QString> advanced)
|
|||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
/*
|
/*
|
||||||
* Levels
|
* Levels
|
||||||
* Nivel 1: aaa
|
* Level 1: aaa
|
||||||
* Nivel 2: aaaa
|
* Level 2: aaaa
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (level == 1)
|
if (level == 1)
|
||||||
@ -533,19 +533,6 @@ QString CutterCore::getConfig(const QString &k)
|
|||||||
return QString(r_config_get(core_->config, key.constData()));
|
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)
|
void CutterCore::setCPU(QString arch, QString cpu, int bits, bool temporary)
|
||||||
{
|
{
|
||||||
setConfig("asm.arch", arch);
|
setConfig("asm.arch", arch);
|
||||||
@ -1377,3 +1364,9 @@ QString CutterCore::getVersionInformation()
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonArray CutterCore::getOpenedFiles()
|
||||||
|
{
|
||||||
|
QJsonDocument files = cmdj("oj");
|
||||||
|
return files.array();
|
||||||
|
}
|
||||||
|
@ -245,7 +245,6 @@ public:
|
|||||||
|
|
||||||
void setImmediateBase(const QString &r2BaseName, RVA offset = RVA_INVALID);
|
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 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);
|
bool tryFile(QString path, bool rw);
|
||||||
void analyze(int level, QList<QString> advanced);
|
void analyze(int level, QList<QString> advanced);
|
||||||
@ -361,6 +360,7 @@ public:
|
|||||||
|
|
||||||
void loadScript(const QString &scriptname);
|
void loadScript(const QString &scriptname);
|
||||||
QString getVersionInformation();
|
QString getVersionInformation();
|
||||||
|
QJsonArray getOpenedFiles();
|
||||||
|
|
||||||
RCoreLocked core() const;
|
RCoreLocked core() const;
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
|
||||||
// TODO Get rid of MainWindow
|
|
||||||
OptionsDialog::OptionsDialog(MainWindow *main):
|
OptionsDialog::OptionsDialog(MainWindow *main):
|
||||||
QDialog(0), // parent may not be main
|
QDialog(0), // parent may not be main
|
||||||
analThread(this),
|
analThread(this),
|
||||||
@ -151,7 +150,6 @@ void OptionsDialog::setupAndStartAnalysis(int level, QList<QString> advanced)
|
|||||||
ui->elapsedLabel->setVisible(true);
|
ui->elapsedLabel->setVisible(true);
|
||||||
|
|
||||||
ui->statusLabel->setText(tr("Starting analysis"));
|
ui->statusLabel->setText(tr("Starting analysis"));
|
||||||
//ui->progressBar->setValue(5);
|
|
||||||
|
|
||||||
main->initUI();
|
main->initUI();
|
||||||
|
|
||||||
@ -164,8 +162,7 @@ void OptionsDialog::setupAndStartAnalysis(int level, QList<QString> advanced)
|
|||||||
updateProgressTimer();
|
updateProgressTimer();
|
||||||
connect(&analTimer, SIGNAL(timeout()), this, SLOT(updateProgressTimer()));
|
connect(&analTimer, SIGNAL(timeout()), this, SLOT(updateProgressTimer()));
|
||||||
|
|
||||||
// Threads stuff
|
// Threads stuff, connect signal/slot
|
||||||
// connect signal/slot
|
|
||||||
connect(&analThread, &AnalThread::updateProgress, this, &OptionsDialog::updateProgress);
|
connect(&analThread, &AnalThread::updateProgress, this, &OptionsDialog::updateProgress);
|
||||||
analThread.start(main, level, advanced);
|
analThread.start(main, level, advanced);
|
||||||
}
|
}
|
||||||
|
18
src/main.cpp
18
src/main.cpp
@ -52,10 +52,10 @@ int main(int argc, char *argv[])
|
|||||||
cmd_parser.addVersionOption();
|
cmd_parser.addVersionOption();
|
||||||
cmd_parser.addPositionalArgument("filename", QObject::tr("Filename to open."));
|
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("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"));
|
QObject::tr("level"));
|
||||||
cmd_parser.addOption(anal_option);
|
cmd_parser.addOption(analOption);
|
||||||
|
|
||||||
cmd_parser.process(a);
|
cmd_parser.process(a);
|
||||||
|
|
||||||
@ -75,14 +75,14 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool anal_level_specified = false;
|
bool analLevelSpecified = false;
|
||||||
int anal_level = 0;
|
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());
|
printf("%s\n", QObject::tr("Invalid Analysis Level. May be a value between 0 and 2.").toLocal8Bit().constData());
|
||||||
return 1;
|
return 1;
|
||||||
@ -92,7 +92,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (args.empty())
|
if (args.empty())
|
||||||
{
|
{
|
||||||
if (anal_level_specified)
|
if (analLevelSpecified)
|
||||||
{
|
{
|
||||||
printf("%s\n", QObject::tr("Filename must be specified to start analysis automatically.").toLocal8Bit().constData());
|
printf("%s\n", QObject::tr("Filename must be specified to start analysis automatically.").toLocal8Bit().constData());
|
||||||
return 1;
|
return 1;
|
||||||
@ -105,7 +105,7 @@ int main(int argc, char *argv[])
|
|||||||
else // filename specified as positional argument
|
else // filename specified as positional argument
|
||||||
{
|
{
|
||||||
MainWindow *main = new MainWindow();
|
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
|
// Hack to make it work with AppImage
|
||||||
|
Loading…
Reference in New Issue
Block a user