From 6f16a5a95ea203afa7afa98c576168e66ce7b457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Wed, 3 May 2017 11:09:57 +0200 Subject: [PATCH] Get more things from JSON commands and some other things (#161) * Flags and Flagspaces from JSON * Sections from JSON * Change -a option to -A with default value 3. * Move Plugin name fetching out of QRCore::getList, Enable manual setting of Arch and Bits in OptionsDialog --- src/main.cpp | 7 +- src/optionsdialog.cpp | 38 ++++--- src/qrcore.cpp | 183 ++++++++++++++++++++++----------- src/qrcore.h | 33 +++++- src/widgets/flagswidget.cpp | 38 ++++--- src/widgets/sectionswidget.cpp | 31 ++---- src/widgets/sectionswidget.h | 5 +- 7 files changed, 212 insertions(+), 123 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 94ea29b2..b8b8a7e6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,9 +29,10 @@ int main(int argc, char *argv[]) cmdParser.addVersionOption(); cmdParser.addPositionalArgument("filename", QObject::tr("Filename to open.")); - QCommandLineOption analOption({"a", "anal"}, - QObject::tr("Automatically start analysis. Needs filename to be specified. May be a value between 0 and 4."), - QObject::tr("level")); + QCommandLineOption analOption({"A", "anal"}, + QObject::tr("Automatically start analysis. Needs filename to be specified. May be a value between 0 and 4. Default is 3."), + QObject::tr("level"), + "3"); cmdParser.addOption(analOption); cmdParser.process(a); diff --git a/src/optionsdialog.cpp b/src/optionsdialog.cpp index 60c8f27d..a2a501a8 100644 --- a/src/optionsdialog.cpp +++ b/src/optionsdialog.cpp @@ -28,13 +28,9 @@ OptionsDialog::OptionsDialog(const QString &filename, QWidget *parent): ui->analSlider->setValue(defaultAnalLevel); // Fill the plugins combo - QStringList plugins; - for (auto i : this->core->getList("asm", "plugins")) - { - this->asm_plugins.append(i); - plugins.append(i); - } - ui->processorComboBox->insertItems(1, plugins); + asm_plugins = core->getAsmPluginNames(); + for (auto plugin : asm_plugins) + ui->processorComboBox->addItem(plugin, plugin); // Restore settings QSettings settings; @@ -86,12 +82,6 @@ void OptionsDialog::setupAndStartAnalysis(int level) int va = ui->vaCheckBox->isChecked(); ut64 loadaddr = 0LL; ut64 mapaddr = 0LL; - int bits = 0; - QString sel_bits = ui->bitsComboBox->currentText(); - if (sel_bits != "Auto") - { - bits = sel_bits.toInt(); - } // Save options in settings QSettings settings; @@ -164,6 +154,26 @@ void OptionsDialog::setupAndStartAnalysis(int level) } settings.setValue("spacy", ui->spacyCheckBox->isChecked()); + + + // + // Advanced Options + // + QVariant archValue = ui->processorComboBox->currentData(); + + int bits = 0; + QString sel_bits = ui->bitsComboBox->currentText(); + if (sel_bits != "Auto") + { + bits = sel_bits.toInt(); + } + + w->core->setCPU(archValue.isValid() ? archValue.toString() : NULL, + QString(), + bits); + + + bool rw = false; bool load_bininfo = ui->binCheckBox->isChecked(); @@ -189,7 +199,7 @@ void OptionsDialog::setupAndStartAnalysis(int level) int binidx = 0; // index of subbin this->w->addOutput(" > Loading file: " + this->filename); - this->w->core->loadFile(this->filename, loadaddr, mapaddr, rw, va, bits, binidx, load_bininfo); + this->w->core->loadFile(this->filename, loadaddr, mapaddr, rw, va, binidx, load_bininfo); //ui->progressBar->setValue(40); ui->statusLabel->setText("Analysis in progress"); diff --git a/src/qrcore.cpp b/src/qrcore.cpp index 302198be..483a9f9c 100644 --- a/src/qrcore.cpp +++ b/src/qrcore.cpp @@ -61,6 +61,8 @@ QRCore::QRCore(QObject *parent) : //config("http.root","/usr/local/share/radare2/last/www"); //config("http.root","/usr/local/radare2/osx/share/radare2/1.1.0-git/www"); + default_bits = 0; + this->db = sdb_new(NULL, NULL, 0); // WTF NOES } @@ -240,7 +242,7 @@ QJsonDocument QRCore::cmdj(const QString &str) return doc; } -bool QRCore::loadFile(QString path, uint64_t loadaddr, uint64_t mapaddr, bool rw, int va, int bits, int idx, bool loadbin) +bool QRCore::loadFile(QString path, uint64_t loadaddr, uint64_t mapaddr, bool rw, int va, int idx, bool loadbin) { QNOTUSED(loadaddr); QNOTUSED(idx); @@ -297,10 +299,6 @@ bool QRCore::loadFile(QString path, uint64_t loadaddr, uint64_t mapaddr, bool rw eprintf("CANNOT GET RBIN INFO\n"); } } - if (bits != 0) - { - r_config_set_i(core_->config, "asm.bits", bits); - } #if HAVE_MULTIPLE_RBIN_FILES_INSIDE_SELECT_WHICH_ONE if (!r_core_file_open(core, path.toUtf8(), R_IO_READ | (rw ? R_IO_WRITE : 0, mapaddr))) @@ -320,6 +318,9 @@ bool QRCore::loadFile(QString path, uint64_t loadaddr, uint64_t mapaddr, bool rw { // Not loading RBin info coz va = false } + + setDefaultCPU(); + r_core_hash_load(core_, path.toUtf8().constData()); fflush(stdout); return true; @@ -440,20 +441,11 @@ bool QRCore::tryFile(QString path, bool rw) QList QRCore::getList(const QString &type, const QString &subtype) { CORE_LOCK(); - RListIter *it; QList ret = QList(); if (type == "bin") { - if (subtype == "sections") - { - QString text = cmd("S*~^S"); - for (QString i : text.split("\n")) - { - ret << i.mid(2).replace(" ", ","); - } - } - else if (subtype == "types") + if (subtype == "types") { ret << "raw"; auto ft = sdb_const_get(DB, "try.filetype", 0); @@ -468,15 +460,7 @@ QList QRCore::getList(const QString &type, const QString &subtype) } else if (type == "asm") { - if (subtype == "plugins") - { - RAsmPlugin *ap; - QRListForeach(core_->assembler->plugins, it, RAsmPlugin, ap) - { - ret << ap->name; - } - } - else if (subtype == "cpus") + if (subtype == "cpus") { QString funcs = cmd("e asm.cpu=?"); QStringList lines = funcs.split("\n"); @@ -486,41 +470,7 @@ QList QRCore::getList(const QString &type, const QString &subtype) } } } - else if (type == "anal") - { - if (subtype == "plugins") - { - RAnalPlugin *ap; - QRListForeach(core_->anal->plugins, it, RAnalPlugin, ap) - { - ret << ap->name; - } - } - } - else if (type == "flagspaces") - { - QStringList lines = cmd("fs*").split("\n"); - for (auto i : lines) - { - QStringList a = i.replace("*", "").split(" "); - if (a.length() > 1) - ret << a[1]; - } - } - else if (type == "flags") - { - if (subtype != NULL && subtype != "") - cmd("fs " + subtype); - else cmd("fs *"); - QString flags = cmd("f*"); - QStringList lines = flags.split("\n"); - for (auto i : lines) - { - // TODO: is 0 in a string even possible? - if (i[0] != QChar(0) && i[1] == QChar('s')) continue; // skip 'fs ..' - ret << i.mid(2).replace(" ", ","); - } - } + return ret; } @@ -627,9 +577,12 @@ void QRCore::setCPU(QString arch, QString cpu, int bits, bool temporary) void QRCore::setDefaultCPU() { - config("asm.arch", default_arch); - config("asm.cpu", default_cpu); - config("asm.bits", QString::number(default_bits)); + if (!default_arch.isEmpty()) + config("asm.arch", default_arch); + if (!default_cpu.isEmpty()) + config("asm.cpu", default_cpu); + if (default_bits) + config("asm.bits", QString::number(default_bits)); } QString QRCore::assemble(const QString &code) @@ -862,6 +815,39 @@ QList QRCore::getSeekHistory() return ret; } + + +QStringList QRCore::getAsmPluginNames() +{ + CORE_LOCK(); + RListIter *it; + QStringList ret; + + RAsmPlugin *ap; + QRListForeach(core_->assembler->plugins, it, RAsmPlugin, ap) + { + ret << ap->name; + } + + return ret; +} + +QStringList QRCore::getAnalPluginNames() +{ + CORE_LOCK(); + RListIter *it; + QStringList ret; + + RAnalPlugin *ap; + QRListForeach(core_->anal->plugins, it, RAnalPlugin, ap) + { + ret << ap->name; + } + + return ret; +} + + QList QRCore::getAllFunctions() { CORE_LOCK(); @@ -1023,3 +1009,76 @@ QList QRCore::getAllStrings() return ret; } + + +QList QRCore::getAllFlagspaces() +{ + CORE_LOCK(); + QList ret; + + QJsonArray flagspacesArray = cmdj("fsj").array(); + for (QJsonValue value : flagspacesArray) + { + QJsonObject flagspaceObject = value.toObject(); + + FlagspaceDescription flagspace; + flagspace.name = flagspaceObject["name"].toString(); + + ret << flagspace; + } + return ret; +} + + +QList QRCore::getAllFlags(QString flagspace) +{ + CORE_LOCK(); + QList ret; + + if (!flagspace.isEmpty()) + cmd("fs " + flagspace); + else + cmd("fs *"); + + QJsonArray flagsArray = cmdj("fj").array(); + for (QJsonValue value : flagsArray) + { + QJsonObject flagObject = value.toObject(); + + FlagDescription flag; + flag.offset = flagObject["offset"].toVariant().toULongLong(); + flag.size = flagObject["size"].toVariant().toULongLong(); + flag.name = flagObject["name"].toString(); + + ret << flag; + } + return ret; +} + + +QList QRCore::getAllSections() +{ + CORE_LOCK(); + QList ret; + + QJsonArray sectionsArray = cmdj("Sj").array(); + for (QJsonValue value : sectionsArray) + { + QJsonObject sectionObject = value.toObject(); + + QString name = sectionObject["name"].toString(); + if (name.isEmpty()) + continue; + + SectionDescription section; + section.name = name; + section.vaddr = sectionObject["vaddr"].toVariant().toULongLong(); + section.vsize = sectionObject["vsize"].toVariant().toULongLong(); + section.paddr = sectionObject["paddr"].toVariant().toULongLong(); + section.size = sectionObject["size"].toVariant().toULongLong(); + section.flags = sectionObject["flags"].toString(); + + ret << section; + } + return ret; +} \ No newline at end of file diff --git a/src/qrcore.h b/src/qrcore.h index 49187e9c..c70e8f39 100644 --- a/src/qrcore.h +++ b/src/qrcore.h @@ -102,12 +102,36 @@ struct StringDescription QString string; }; +struct FlagspaceDescription +{ + QString name; +}; + +struct FlagDescription +{ + RVA offset; + RVA size; + QString name; +}; + +struct SectionDescription +{ + RVA vaddr; + RVA paddr; + RVA size; + RVA vsize; + QString name; + QString flags; +}; + Q_DECLARE_METATYPE(FunctionDescription) Q_DECLARE_METATYPE(ImportDescription) Q_DECLARE_METATYPE(SymbolDescription) Q_DECLARE_METATYPE(CommentDescription) Q_DECLARE_METATYPE(RelocDescription) Q_DECLARE_METATYPE(StringDescription) +Q_DECLARE_METATYPE(FlagspaceDescription) +Q_DECLARE_METATYPE(FlagDescription) class QRCore : public QObject { @@ -135,7 +159,7 @@ public: void delComment(ut64 addr); QMap>> getNestedComments(); void setOptions(QString key); - bool loadFile(QString path, uint64_t loadaddr = 0LL, uint64_t mapaddr = 0LL, bool rw = false, int va = 0, int bits = 0, int idx = 0, bool loadbin = false); + bool loadFile(QString path, uint64_t loadaddr = 0LL, uint64_t mapaddr = 0LL, bool rw = false, int va = 0, int idx = 0, bool loadbin = false); bool tryFile(QString path, bool rw); void analyze(int level); void seek(QString addr); @@ -175,12 +199,19 @@ public: QList getList(const QString &type, const QString &subtype = ""); QList getSeekHistory(); + + QStringList getAsmPluginNames(); + QStringList getAnalPluginNames(); + QList getAllFunctions(); QList getAllImports(); QList getAllSymbols(); QList getAllComments(const QString &filterType); QList getAllRelocs(); QList getAllStrings(); + QList getAllFlagspaces(); + QList getAllFlags(QString flagspace = NULL); + QList getAllSections(); RCoreLocked core() const; diff --git a/src/widgets/flagswidget.cpp b/src/widgets/flagswidget.cpp index 570150a9..1a54171d 100644 --- a/src/widgets/flagswidget.cpp +++ b/src/widgets/flagswidget.cpp @@ -60,13 +60,17 @@ void FlagsWidget::on_flagspaceCombo_currentTextChanged(const QString &arg1) void FlagsWidget::refreshFlagspaces() { int cur_idx = ui->flagspaceCombo->currentIndex(); - if (cur_idx < 0)cur_idx = 0; + if (cur_idx < 0) + cur_idx = 0; + ui->flagspaceCombo->clear(); - ui->flagspaceCombo->addItem("(all)"); - for (auto i : main->core->getList("flagspaces")) + ui->flagspaceCombo->addItem(tr("(all)")); + + for (auto i : main->core->getAllFlagspaces()) { - ui->flagspaceCombo->addItem(i); + ui->flagspaceCombo->addItem(i.name, QVariant::fromValue(i)); } + if (cur_idx > 0) ui->flagspaceCombo->setCurrentIndex(cur_idx); @@ -75,29 +79,23 @@ void FlagsWidget::refreshFlagspaces() void FlagsWidget::refreshFlags() { - QString flagspace = ui->flagspaceCombo->currentText(); - if (flagspace == "(all)") - flagspace = ""; + QString flagspace; + + QVariant flagspace_data = ui->flagspaceCombo->currentData(); + if(flagspace_data.isValid()) + flagspace = flagspace_data.value().name; + ui->flagsTreeWidget->clear(); QStringList flags; - for (auto i : main->core->getList("flags", flagspace)) + for (auto i : main->core->getAllFlags(flagspace)) { - QStringList a = i.split(","); - if (a.length() > 3) - { - qhelpers::appendRow(ui->flagsTreeWidget, a[1], a[2], a[0], a[3]); - //this->omnibar->fillFlags(a[0]); - } - else if (a.length() > 2) - { - qhelpers::appendRow(ui->flagsTreeWidget, a[1], a[2], a[0], ""); - //this->omnibar->fillFlags(a[0]); - } + QTreeWidgetItem *item = qhelpers::appendRow(ui->flagsTreeWidget, RSizeString(i.size), RAddressString(i.offset), i.name); + item->setData(0, Qt::UserRole, QVariant::fromValue(i)); - flags.append(a[0]); + flags.append(i.name); } qhelpers::adjustColumns(ui->flagsTreeWidget); diff --git a/src/widgets/sectionswidget.cpp b/src/widgets/sectionswidget.cpp index ae5c8416..35c45367 100644 --- a/src/widgets/sectionswidget.cpp +++ b/src/widgets/sectionswidget.cpp @@ -24,24 +24,14 @@ void SectionsWidget::setup() tree->clear(); int row = 0; - for (auto i : main->core->getList("bin", "sections")) + for (auto section : main->core->getAllSections()) { - QStringList a = i.split(","); - if (a.length() > 4) - { - // Fix to work with ARM bins - //if (a[4].startsWith(".")) { - if (a[4].contains(".")) - { - QString addr = a[1]; - QString addr_end = "0x0" + main->core->itoa(main->core->math(addr + "+" + a[2])); - QString size = QString::number(main->core->math(a[2])); - QString name = a[4]; + if(!section.name.contains(".")) + continue; - fillSections(row++, name, size, addr, addr_end); - } - } + fillSections(row++, section); } + //adjustColumns(sectionsWidget->tree); //this->sectionsDock->sectionsWidget->adjustColumns(); qhelpers::adjustColumns(tree); @@ -81,8 +71,7 @@ void SectionsWidget::setupViews() pieChart->setSelectionModel(selectionModel); } -void SectionsWidget::fillSections(int row, const QString &str, const QString &str2, - const QString &str3, const QString &str4) +void SectionsWidget::fillSections(int row, const SectionDescription §ion) { // TODO: create unique colors, e. g. use HSV color space and rotate in H for 360/size static const QList colors = { QColor("#1ABC9C"), //TURQUOISE @@ -99,10 +88,10 @@ void SectionsWidget::fillSections(int row, const QString &str, const QString &st }; QTreeWidgetItem *tempItem = new QTreeWidgetItem(); - tempItem->setText(0, str); - tempItem->setText(1, str2); - tempItem->setText(2, str3); - tempItem->setText(3, str4); + tempItem->setText(0, section.name); + tempItem->setText(1, RSizeString(section.size)); + tempItem->setText(2, RAddressString(section.vaddr)); + tempItem->setText(3, RAddressString(section.vaddr + section.vsize)); tempItem->setData(0, Qt::DecorationRole, colors[row % colors.size()]); this->tree->insertTopLevelItem(0, tempItem); } diff --git a/src/widgets/sectionswidget.h b/src/widgets/sectionswidget.h index 9fd7ef9b..9ab4a182 100644 --- a/src/widgets/sectionswidget.h +++ b/src/widgets/sectionswidget.h @@ -9,6 +9,8 @@ class QAbstractItemModel; class QAbstractItemView; class QItemSelectionModel; +struct SectionDescription; + namespace Ui { class SectionsWidget; @@ -31,8 +33,7 @@ private: void setupViews(); - void fillSections(int row, const QString &str, const QString &str2 = QString(), - const QString &str3 = QString(), const QString &str4 = QString()); + void fillSections(int row, const SectionDescription §ion); }; #endif // SECTIONSWIDGET_H