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
This commit is contained in:
Florian Märkl 2017-05-03 11:09:57 +02:00 committed by Hugo Teso
parent 416ed82149
commit 6f16a5a95e
7 changed files with 212 additions and 123 deletions

View File

@ -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);

View File

@ -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");

View File

@ -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<QString> QRCore::getList(const QString &type, const QString &subtype)
{
CORE_LOCK();
RListIter *it;
QList<QString> ret = QList<QString>();
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<QString> 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<QString> 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<RVA> 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<FunctionDescription> QRCore::getAllFunctions()
{
CORE_LOCK();
@ -1023,3 +1009,76 @@ QList<StringDescription> QRCore::getAllStrings()
return ret;
}
QList<FlagspaceDescription> QRCore::getAllFlagspaces()
{
CORE_LOCK();
QList<FlagspaceDescription> 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<FlagDescription> QRCore::getAllFlags(QString flagspace)
{
CORE_LOCK();
QList<FlagDescription> 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<SectionDescription> QRCore::getAllSections()
{
CORE_LOCK();
QList<SectionDescription> 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;
}

View File

@ -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<QString, QList<QList<QString>>> 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<QString> getList(const QString &type, const QString &subtype = "");
QList<RVA> getSeekHistory();
QStringList getAsmPluginNames();
QStringList getAnalPluginNames();
QList<FunctionDescription> getAllFunctions();
QList<ImportDescription> getAllImports();
QList<SymbolDescription> getAllSymbols();
QList<CommentDescription> getAllComments(const QString &filterType);
QList<RelocDescription> getAllRelocs();
QList<StringDescription> getAllStrings();
QList<FlagspaceDescription> getAllFlagspaces();
QList<FlagDescription> getAllFlags(QString flagspace = NULL);
QList<SectionDescription> getAllSections();
RCoreLocked core() const;

View File

@ -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<FlagspaceDescription>().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);

View File

@ -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 &section)
{
// TODO: create unique colors, e. g. use HSV color space and rotate in H for 360/size
static const QList<QColor> 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);
}

View File

@ -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 &section);
};
#endif // SECTIONSWIDGET_H