2018-03-04 17:42:02 +00:00
|
|
|
#include "Cutter.h"
|
2017-10-02 16:18:40 +00:00
|
|
|
#include "AnalThread.h"
|
2017-10-01 19:09:42 +00:00
|
|
|
#include "MainWindow.h"
|
|
|
|
#include "dialogs/OptionsDialog.h"
|
2018-01-27 10:40:26 +00:00
|
|
|
#include <QJsonArray>
|
2018-05-05 13:20:14 +00:00
|
|
|
#include <QDebug>
|
|
|
|
#include <QCheckBox>
|
2017-03-29 10:18:37 +00:00
|
|
|
|
2017-09-28 22:04:57 +00:00
|
|
|
AnalThread::AnalThread(OptionsDialog *parent) :
|
2017-03-31 22:43:12 +00:00
|
|
|
QThread(parent),
|
2017-09-29 11:32:53 +00:00
|
|
|
level(2),
|
2017-10-09 18:08:35 +00:00
|
|
|
main(nullptr),
|
2018-03-09 12:57:57 +00:00
|
|
|
interrupted(false)
|
2017-03-29 10:18:37 +00:00
|
|
|
{
|
2017-03-31 22:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AnalThread::~AnalThread()
|
|
|
|
{
|
2018-03-21 20:32:32 +00:00
|
|
|
if (isRunning()) {
|
2017-03-31 22:43:12 +00:00
|
|
|
quit();
|
|
|
|
wait();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-28 22:04:57 +00:00
|
|
|
void AnalThread::start(MainWindow *main, int level, QList<QString> advanced)
|
2017-03-31 22:43:12 +00:00
|
|
|
{
|
|
|
|
this->level = level;
|
2017-07-24 11:05:28 +00:00
|
|
|
this->advanced = advanced;
|
2017-09-28 22:04:57 +00:00
|
|
|
this->main = main;
|
2017-03-31 22:43:12 +00:00
|
|
|
|
|
|
|
QThread::start();
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|
|
|
|
|
2018-03-09 12:57:57 +00:00
|
|
|
void AnalThread::interruptAndWait()
|
|
|
|
{
|
|
|
|
interrupted = true;
|
|
|
|
|
2018-03-21 20:32:32 +00:00
|
|
|
while (isRunning()) {
|
2018-03-09 12:57:57 +00:00
|
|
|
r_cons_singleton()->breaked = true;
|
|
|
|
r_sys_usleep(10000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-29 10:18:37 +00:00
|
|
|
// run() will be called when a thread starts
|
|
|
|
void AnalThread::run()
|
|
|
|
{
|
2017-09-28 22:04:57 +00:00
|
|
|
const auto optionsDialog = dynamic_cast<OptionsDialog *>(parent());
|
2017-11-03 17:22:54 +00:00
|
|
|
const auto &ui = optionsDialog->ui;
|
2018-05-05 13:20:14 +00:00
|
|
|
bool va = ui->vaCheckBox->isChecked();
|
2018-05-07 15:16:51 +00:00
|
|
|
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());
|
2018-05-05 13:20:14 +00:00
|
|
|
ut64 mapAddr = Core()->math(ui->entry_mapOffset->text()); // Where to map the file once loaded (-m)
|
2018-03-09 12:57:57 +00:00
|
|
|
interrupted = false;
|
2018-05-05 13:20:14 +00:00
|
|
|
emit updateProgress(tr("Loading binary..."));
|
2018-03-09 12:57:57 +00:00
|
|
|
|
2018-05-05 13:20:14 +00:00
|
|
|
// Set the CPU details (handle auto)
|
|
|
|
Core()->setCPU(optionsDialog->getSelectedArch(), optionsDialog->getSelectedCPU(),
|
2018-03-21 20:32:32 +00:00
|
|
|
optionsDialog->getSelectedBits());
|
2017-09-28 22:04:57 +00:00
|
|
|
|
2018-05-05 13:20:14 +00:00
|
|
|
// Binary opening permissions (read/write/execute)
|
2018-02-27 10:20:48 +00:00
|
|
|
int perms = R_IO_READ | R_IO_EXEC;
|
|
|
|
if (ui->writeCheckBox->isChecked())
|
|
|
|
perms |= R_IO_WRITE;
|
2017-09-28 22:04:57 +00:00
|
|
|
|
2018-05-05 13:20:14 +00:00
|
|
|
// Check if we must load and parse binary header (ELF, PE, ...)
|
|
|
|
bool loadBinInfo = !ui->binCheckBox->isChecked();
|
2017-09-29 11:32:53 +00:00
|
|
|
QString forceBinPlugin = nullptr;
|
|
|
|
QVariant forceBinPluginData = ui->formatComboBox->currentData();
|
2018-03-21 20:32:32 +00:00
|
|
|
if (!forceBinPluginData.isNull()) {
|
2017-09-29 11:32:53 +00:00
|
|
|
RBinPluginDescription pluginDesc = forceBinPluginData.value<RBinPluginDescription>();
|
|
|
|
forceBinPlugin = pluginDesc.name;
|
|
|
|
}
|
|
|
|
|
2018-05-05 13:20:14 +00:00
|
|
|
// Demangle (must be before file Core()->loadFile)
|
|
|
|
Core()->setConfig("bin.demangle", ui->demangleCheckBox->isChecked());
|
2017-10-01 16:03:06 +00:00
|
|
|
|
2018-05-05 13:20:14 +00:00
|
|
|
// Do not reload the file if already loaded
|
2018-01-27 10:40:26 +00:00
|
|
|
QJsonArray openedFiles = Core()->getOpenedFiles();
|
2018-03-21 20:32:32 +00:00
|
|
|
if (!openedFiles.size()) {
|
2018-05-05 13:20:14 +00:00
|
|
|
Core()->loadFile(main->getFilename(), binLoadAddr, mapAddr, perms, va, loadBinInfo,
|
2018-03-21 20:32:32 +00:00
|
|
|
forceBinPlugin);
|
2018-01-27 10:40:26 +00:00
|
|
|
}
|
2017-09-28 22:04:57 +00:00
|
|
|
|
2018-05-05 13:20:14 +00:00
|
|
|
// Set asm OS configuration
|
2017-09-28 22:04:57 +00:00
|
|
|
QString os = optionsDialog->getSelectedOS();
|
2018-03-21 20:32:32 +00:00
|
|
|
if (!os.isNull()) {
|
2018-05-05 13:20:14 +00:00
|
|
|
Core()->cmd("e asm.os=" + os);
|
2017-09-28 22:04:57 +00:00
|
|
|
}
|
|
|
|
|
2018-05-05 13:20:14 +00:00
|
|
|
// Load PDB and/or scripts
|
2018-03-21 20:32:32 +00:00
|
|
|
if (ui->pdbCheckBox->isChecked()) {
|
2018-05-05 13:20:14 +00:00
|
|
|
Core()->loadPDB(ui->pdbLineEdit->text());
|
2017-09-28 22:04:57 +00:00
|
|
|
}
|
2018-04-30 06:39:48 +00:00
|
|
|
if (ui->scriptCheckBox->isChecked()) {
|
2018-05-05 13:20:14 +00:00
|
|
|
Core()->loadScript(ui->scriptLineEdit->text());
|
2018-04-30 06:39:48 +00:00
|
|
|
}
|
|
|
|
|
2018-05-05 13:20:14 +00:00
|
|
|
// Set various options
|
2018-03-21 20:32:32 +00:00
|
|
|
if (optionsDialog->getSelectedEndianness() != OptionsDialog::Endianness::Auto) {
|
2018-05-05 13:20:14 +00:00
|
|
|
Core()->setEndianness(optionsDialog->getSelectedEndianness() == OptionsDialog::Endianness::Big);
|
2018-01-27 10:40:26 +00:00
|
|
|
}
|
2018-05-05 13:20:14 +00:00
|
|
|
Core()->setBBSize(optionsDialog->getSelectedBBSize());
|
|
|
|
// Use prj.simple as default as long as regular projects are broken
|
|
|
|
Core()->setConfig("prj.simple", true);
|
|
|
|
|
|
|
|
// Start analysis
|
|
|
|
emit updateProgress(tr("Analysis in progress..."));
|
|
|
|
Core()->analyze(this->level, this->advanced);
|
|
|
|
emit updateProgress(tr("Analysis complete!"));
|
2017-03-29 10:18:37 +00:00
|
|
|
}
|