cutter/src/qrcore.cpp

936 lines
24 KiB
C++
Raw Normal View History

#include "qrcore.h"
#include "sdb.h"
#include <QJsonArray>
#include <QJsonObject>
#define DB this->db
RCoreLocked::RCoreLocked(RCore *core)
: core(core)
{
r_th_lock_enter(core->lock);
}
2017-04-09 19:55:06 +00:00
RCoreLocked::RCoreLocked(RCoreLocked &&o)
2017-04-09 18:42:45 +00:00
: core(o.core)
{
2017-04-09 18:42:45 +00:00
o.core = nullptr;
}
RCoreLocked::~RCoreLocked()
{
r_th_lock_leave(core->lock);
}
2017-04-09 19:55:06 +00:00
RCoreLocked::operator RCore *() const
{
return core;
}
2017-04-09 19:55:06 +00:00
RCore *RCoreLocked::operator->() const
{
return core;
}
RCoreLocked QRCore::core() const
{
return RCoreLocked(this->core_);
}
#define CORE_LOCK() RCoreLocked core_lock__(this->core_)
QRCore::QRCore(QObject *parent) :
QObject(parent)
{
2017-04-09 19:55:06 +00:00
r_cons_new(); // initialize console
this->projectPath = "";
2017-04-09 19:55:06 +00:00
this->core_ = r_core_new();
r_core_loadlibs(this->core_, R_CORE_LOADLIBS_ALL, NULL);
// IMPLICIT r_bin_iobind (core_->bin, core_->io);
// Otherwise r2 may ask the user for input and Iaito would freeze
2017-04-09 19:55:06 +00:00
config("scr.interactive", "false");
2017-04-03 11:03:26 +00:00
// Used by the HTML5 graph
2017-04-09 19:55:06 +00:00
config("http.cors", "true");
2017-04-03 11:03:26 +00:00
config("http.sandbox", "false");
//config("http.port", "14170");
// Temporary fixes
//config("http.root","/usr/local/share/radare2/last/www");
//config("http.root","/usr/local/radare2/osx/share/radare2/1.1.0-git/www");
2017-04-09 19:55:06 +00:00
this->db = sdb_new(NULL, NULL, 0); // WTF NOES
}
2017-04-09 19:55:06 +00:00
QList<QString> QRCore::getFunctionXrefs(ut64 addr)
{
CORE_LOCK();
QList<QString> ret = QList<QString>();
RList *list = r_anal_xrefs_get(core_->anal, addr);
RAnalRef *ref;
RListIter *it;
2017-04-09 19:55:06 +00:00
QRListForeach(list, it, RAnalRef, ref)
{
ret << QString("%1,0x%2,0x%3").arg(
QString(ref->type),
QString::number(ref->addr, 16),
QString::number(ref->at, 16));
}
return ret;
}
2017-04-09 19:55:06 +00:00
QList<QString> QRCore::getFunctionRefs(ut64 addr, char type)
{
CORE_LOCK();
QList<QString> ret = QList<QString>();
//RAnalFunction *fcn = r_anal_get_fcn_at(core_->anal, addr, addr);
RAnalFunction *fcn = r_anal_get_fcn_in(core_->anal, addr, 0);
2017-04-09 19:55:06 +00:00
if (!fcn)
{
eprintf("qcore->getFunctionRefs: No function found\n");
return ret;
}
//eprintf(fcn->name);
RAnalRef *ref;
RListIter *it;
2017-04-09 19:55:06 +00:00
QRListForeach(fcn->refs, it, RAnalRef, ref)
{
if (type == ref->type || type == 0)
2017-04-09 19:55:06 +00:00
ret << QString("%1,0x%2,0x%3").arg(
QString(ref->type),
QString::number(ref->addr, 16),
QString::number(ref->at, 16));
}
return ret;
}
2017-04-09 19:55:06 +00:00
int QRCore::getCycloComplex(ut64 addr)
{
CORE_LOCK();
QString ret = "";
RAnalFunction *fcn = r_anal_get_fcn_in(core_->anal, addr, 0);
2017-04-09 19:55:06 +00:00
if (fcn)
{
ret = cmd("afcc @ " + QString(fcn->name));
return ret.toInt();
2017-04-09 19:55:06 +00:00
}
else
{
eprintf("qcore->getCycloComplex: no fcn found");
return 0;
}
}
2017-04-09 19:55:06 +00:00
int QRCore::getFcnSize(ut64 addr)
{
CORE_LOCK();
QString ret = "";
QString tmp_ret = "";
RAnalFunction *fcn = r_anal_get_fcn_in(core_->anal, addr, 0);
2017-04-09 19:55:06 +00:00
if (fcn)
{
tmp_ret = cmd("afi~size[1] " + QString(fcn->name));
ret = tmp_ret.split("\n")[0];
2017-04-09 19:55:06 +00:00
return ret.toInt() / 10;
}
else
{
eprintf("qcore->getFcnSize: no fcn found");
return 0;
}
}
2017-04-09 19:55:06 +00:00
QList<QString> QRCore::sdbList(QString path)
{
CORE_LOCK();
QList<QString> list = QList<QString>();
2017-04-09 19:55:06 +00:00
Sdb *root = sdb_ns_path(core_->sdb, path.toUtf8().constData(), 0);
if (root)
{
void *vsi;
ls_iter_t *iter;
2017-04-09 19:55:06 +00:00
ls_foreach(root->ns, iter, vsi)
{
SdbNs *nsi = (SdbNs *)vsi;
list << nsi->name;
}
}
return list;
}
2017-04-09 19:55:06 +00:00
QList<QString> QRCore::sdbListKeys(QString path)
{
CORE_LOCK();
QList<QString> list = QList<QString>();
2017-04-09 19:55:06 +00:00
Sdb *root = sdb_ns_path(core_->sdb, path.toUtf8().constData(), 0);
if (root)
{
void *vsi;
ls_iter_t *iter;
SdbList *l = sdb_foreach_list(root, false);
2017-04-09 19:55:06 +00:00
ls_foreach(l, iter, vsi)
{
SdbKv *nsi = (SdbKv *)vsi;
list << nsi->key;
}
}
return list;
}
2017-04-09 19:55:06 +00:00
QString QRCore::sdbGet(QString path, QString key)
{
CORE_LOCK();
2017-04-09 19:55:06 +00:00
Sdb *db = sdb_ns_path(core_->sdb, path.toUtf8().constData(), 0);
if (db)
{
const char *val = sdb_const_get(db, key.toUtf8().constData(), 0);
if (val && *val)
return val;
}
2017-04-09 19:55:06 +00:00
return QString("");
}
2017-04-09 19:55:06 +00:00
bool QRCore::sdbSet(QString path, QString key, QString val)
{
CORE_LOCK();
2017-04-09 19:55:06 +00:00
Sdb *db = sdb_ns_path(core_->sdb, path.toUtf8().constData(), 1);
if (!db) return false;
2017-04-09 19:55:06 +00:00
return sdb_set(db, key.toUtf8().constData(), val.toUtf8().constData(), 0);
}
2017-04-09 19:55:06 +00:00
QRCore::~QRCore()
{
r_core_free(this->core_);
r_cons_free();
}
2017-04-09 19:55:06 +00:00
QString QRCore::cmd(const QString &str)
{
CORE_LOCK();
QByteArray cmd = str.toUtf8();
//r_cons_flush();
2017-04-09 19:55:06 +00:00
char *res = r_core_cmd_str(this->core_, cmd.constData());
QString o = QString(res ? res : "");
2017-03-30 03:07:34 +00:00
//r_mem_free was added in https://github.com/radare/radare2/commit/cd28744049492dc8ac25a1f2b3ba0e42f0e9ce93
r_mem_free(res);
return o;
}
QJsonDocument QRCore::cmdj(const QString &str)
{
CORE_LOCK();
QByteArray cmd = str.toUtf8();
char *res = r_core_cmd_str(this->core_, cmd.constData());
QJsonDocument doc = res ? QJsonDocument::fromJson(QByteArray(res)) : QJsonDocument();
r_mem_free(res);
return doc;
}
2017-04-09 19:55:06 +00:00
bool QRCore::loadFile(QString path, uint64_t loadaddr = 0LL, uint64_t mapaddr = 0LL, bool rw = false, int va = 0, int bits = 0, int idx, bool loadbin)
{
QNOTUSED(loadaddr);
QNOTUSED(idx);
CORE_LOCK();
RCoreFile *f;
2017-04-09 19:55:06 +00:00
if (va == 0 || va == 2)
r_config_set_i(core_->config, "io.va", va);
// NO ONE KNOWS WHY THIS IS FIXING A SEGFAULT. core_->file should have already a proper value. Pancake dixit
//core_->file = NULL;
// mapaddr = 0LL;
2017-04-09 19:55:06 +00:00
printf("FILE OPEN (%s)\n", path.toUtf8().constData());
f = r_core_file_open(core_, path.toUtf8().constData(), rw ? (R_IO_READ | R_IO_WRITE) : R_IO_READ, mapaddr);
if (!f)
{
eprintf("r_core_file_open failed\n");
return false;
}
2017-04-09 19:55:06 +00:00
if (loadbin)
{
if (va == 1)
{
if (r_core_bin_load(core_, path.toUtf8().constData(), UT64_MAX))
{
RBinObject *obj = r_bin_get_object(core_->bin);
2017-04-09 19:55:06 +00:00
if (obj)
{
eprintf("BITS %d\n", obj->info->bits);
}
}
2017-04-09 19:55:06 +00:00
else
{
eprintf("CANNOT GET RBIN INFO\n");
}
}
else
{
if (r_core_bin_load(core_, path.toUtf8().constData(), UT64_MAX))
{
RBinObject *obj = r_bin_get_object(core_->bin);
2017-04-09 19:55:06 +00:00
if (obj)
{
eprintf("BITS %d\n", obj->info->bits);
}
else
{
eprintf("Bin load failed\n");
return false;
}
2017-04-09 19:55:06 +00:00
}
else
{
eprintf("CANNOT GET RBIN INFO\n");
}
}
2017-04-09 19:55:06 +00:00
if (bits != 0)
{
r_config_set_i(core_->config, "asm.bits", bits);
}
#if HAVE_MULTIPLE_RBIN_FILES_INSIDE_SELECT_WHICH_ONE
2017-04-09 19:55:06 +00:00
if (!r_core_file_open(core, path.toUtf8(), R_IO_READ | rw ? R_IO_WRITE : 0, mapaddr))
{
eprintf("Cannot open file\n");
}
else
{
// load RBin information
// XXX only for sub-bins
2017-04-09 19:55:06 +00:00
r_core_bin_load(core, path.toUtf8(), loadaddr);
r_bin_select_idx(core_->bin, NULL, idx);
}
#endif
2017-04-09 19:55:06 +00:00
}
else
{
// Not loading RBin info coz va = false
}
r_core_hash_load(core_, path.toUtf8().constData());
2017-04-09 19:55:06 +00:00
fflush(stdout);
return true;
}
2017-04-09 19:55:06 +00:00
void QRCore::analyze(int level)
{
CORE_LOCK();
2017-04-09 19:55:06 +00:00
/*
* Levels
* Nivel 1: afr @ entry0 y main (afr@entry0;afr@main)
* Nivel 2: aa
* Nivel 3: aaa
* Nivel 4: aaaa
*/
if (level == 1)
{
r_core_cmd0(core_, "afr@entry0;afr@main");
}
else if (level == 2)
{
r_core_cmd0(core_, "aa");
}
else if (level == 3)
{
r_core_cmd0(core_, "aaa");
}
else if (level == 4)
{
r_core_cmd0(core_, "aaaa");
}
}
2017-04-09 19:55:06 +00:00
void QRCore::renameFunction(QString prev_name, QString new_name)
{
cmd("afn " + new_name + " " + prev_name);
}
2017-04-09 19:55:06 +00:00
void QRCore::setComment(QString addr, QString cmt)
{
//r_meta_add (core->anal, 'C', addr, 1, cmt.toUtf8());
cmd("CC " + cmt + " @ " + addr);
}
2017-04-09 19:55:06 +00:00
void QRCore::delComment(ut64 addr)
{
CORE_LOCK();
2017-04-09 19:55:06 +00:00
r_meta_del(core_->anal, 'C', addr, 1, NULL);
//cmd (QString("CC-@")+addr);
}
2017-04-09 19:55:06 +00:00
QList<QList<QString>> QRCore::getComments()
{
QList<QList<QString>> ret;
QString comments = cmd("CC~CCu");
2017-04-09 19:55:06 +00:00
for (QString line : comments.split("\n"))
{
QStringList fields = line.split("CCu");
2017-04-09 19:55:06 +00:00
if (fields.length() == 2)
{
QList<QString> tmp = QList<QString>();
tmp << fields[1].split("\"")[1].trimmed();
tmp << fields[0].trimmed();
ret << tmp;
}
}
return ret;
}
2017-04-09 19:55:06 +00:00
QMap<QString, QList<QList<QString>>> QRCore::getNestedComments()
{
QMap<QString, QList<QList<QString>>> ret;
QString comments = cmd("CC~CCu");
2017-04-09 19:55:06 +00:00
for (QString line : comments.split("\n"))
{
QStringList fields = line.split("CCu");
2017-04-09 19:55:06 +00:00
if (fields.length() == 2)
{
QList<QString> tmp = QList<QString>();
tmp << fields[1].split("\"")[1].trimmed();
tmp << fields[0].trimmed();
QString fcn_name = this->cmdFunctionAt(fields[0].trimmed());
2017-04-09 19:55:06 +00:00
if (ret.contains(fcn_name))
{
ret[fcn_name].append(tmp);
2017-04-09 19:55:06 +00:00
}
else
{
ret[fcn_name].append(tmp);
}
}
}
return ret;
}
2017-04-09 19:55:06 +00:00
void QRCore::seek(QString addr)
{
if (addr.length() > 0)
seek(this->math(addr.toUtf8().constData()));
}
2017-04-09 19:55:06 +00:00
void QRCore::seek(ut64 addr)
{
CORE_LOCK();
2017-04-09 19:55:06 +00:00
r_core_seek(this->core_, addr, true);
}
2017-04-09 19:55:06 +00:00
bool QRCore::tryFile(QString path, bool rw)
{
CORE_LOCK();
RCoreFile *cf;
int flags = R_IO_READ;
if (rw) flags |= R_IO_WRITE;
2017-04-09 19:55:06 +00:00
cf = r_core_file_open(this->core_, path.toUtf8().constData(), flags, 0LL);
if (!cf)
{
eprintf("QRCore::tryFile: Cannot open file?\n");
return false;
}
bool is_writable = cf->desc->flags & R_IO_WRITE;
// if rbin works, tell entry0, and symbols (main, constructor, ..)
//r_core_file_close (this->core, cf);
2017-04-09 19:55:06 +00:00
sdb_bool_set(DB, "try.is_writable", is_writable, 0);
sdb_set(DB, "try.filetype", "elf.i386", 0);
sdb_set(DB, "try.filename", path.toUtf8().constData(), 0);
return true;
}
2017-04-09 19:55:06 +00:00
QList<QString> QRCore::getList(const QString &type, const QString &subtype)
{
CORE_LOCK();
RListIter *it;
QList<QString> ret = QList<QString>();
2017-04-09 19:55:06 +00:00
if (type == "bin")
{
if (subtype == "sections")
{
QString text = cmd("S*~^S");
for (QString i : text.split("\n"))
{
ret << i.mid(2).replace(" ", ",");
}
2017-04-09 19:55:06 +00:00
}
else if (subtype == "types")
{
ret << "raw";
2017-04-09 19:55:06 +00:00
auto ft = sdb_const_get(DB, "try.filetype", 0);
if (ft && *ft)
ret << ft;
2017-04-09 19:55:06 +00:00
}
else if (subtype == "imports")
{
QJsonArray importsArray = cmdj("iij").array();
foreach(QJsonValue value, importsArray)
2017-04-09 19:55:06 +00:00
{
QJsonObject importObject = value.toObject();
unsigned long plt = (unsigned long)importObject["plt"].toVariant().toULongLong();
int ordinal = importObject["ordinal"].toInt();
QString final = QString("%1,%2,%3,%4,%5,").arg(
QString::asprintf("%#o", ordinal),
QString::asprintf("%#010lx", plt),
importObject["bind"].toString(),
importObject["type"].toString(),
importObject["name"].toString());
ret << final;
}
2017-04-09 19:55:06 +00:00
}
else if (subtype == "entrypoints")
{
if (math("entry0") != 0)
ret << "entry0";
2017-04-09 19:55:06 +00:00
}
else if (subtype == "relocs")
{
RBinReloc *br;
2017-04-09 19:55:06 +00:00
if (core_ && core_->bin && core_->bin->cur && core_->bin->cur->o)
{
QRListForeach(core_->bin->cur->o->relocs, it, RBinReloc, br)
{
if (br->import)
{
// TODO: we want the offset too!
2017-04-09 19:55:06 +00:00
QString type = (br->additive ? "ADD_" : "SET_") + QString::number(br->type);
ret << QString("0x%1,%2,%3").arg(QString::number(br->vaddr, 16), type, br->import->name);
}
else
{
// TODO: we want the offset too!
2017-04-09 19:55:06 +00:00
QString type = (br->additive ? "ADD_" : "SET_") + QString::number(br->type);
ret << QString("0x%1,%2,reloc_%3").arg(QString::number(br->vaddr, 16), type, QString::number(br->vaddr, 16));
}
}
}
2017-04-09 19:55:06 +00:00
}
else if (subtype == "symbols")
{
RBinSymbol *bs;
2017-04-09 19:55:06 +00:00
if (core_ && core_->bin && core_->bin->cur && core_->bin->cur->o)
{
QRListForeach(core_->bin->cur->o->symbols, it, RBinSymbol, bs)
{
QString type = QString(bs->bind) + " " + QString(bs->type);
ret << QString("0x%1,%2,%3").arg(QString::number(bs->vaddr, 16), type, bs->name);
}
/* list entrypoints as symbols too */
int n = 0;
RBinAddr *entry;
2017-04-09 19:55:06 +00:00
QRListForeach(core_->bin->cur->o->entries, it, RBinAddr, entry)
{
ret << QString("0x%1,%2,%3%4").arg(QString::number(entry->vaddr, 16), "entry", "entry", QString::number(n++));
}
}
2017-04-09 19:55:06 +00:00
}
else if (subtype == "strings")
{
RBinString *bs;
2017-04-09 19:55:06 +00:00
if (core_ && core_->bin && core_->bin->cur && core_->bin->cur->o)
{
QRListForeach(core_->bin->cur->o->strings, it, RBinString, bs)
{
ret << QString("0x%1,%2").arg(QString::number(bs->vaddr, 16), bs->string);
}
}
}
2017-04-09 19:55:06 +00:00
}
else if (type == "asm")
{
if (subtype == "plugins")
{
RAsmPlugin *ap;
2017-04-09 19:55:06 +00:00
QRListForeach(core_->assembler->plugins, it, RAsmPlugin, ap)
{
ret << ap->name;
}
2017-04-09 19:55:06 +00:00
}
else if (subtype == "cpus")
{
QString funcs = cmd("e asm.cpu=?");
QStringList lines = funcs.split("\n");
2017-04-09 19:55:06 +00:00
for (auto cpu : lines)
{
ret << cpu;
}
}
2017-04-09 19:55:06 +00:00
}
else if (type == "anal")
{
if (subtype == "plugins")
{
RAnalPlugin *ap;
2017-04-09 19:55:06 +00:00
QRListForeach(core_->anal->plugins, it, RAnalPlugin, ap)
{
ret << ap->name;
}
2017-04-09 19:55:06 +00:00
}
else if (subtype == "functions")
{
QString funcs = cmd("afl");
QStringList lines = funcs.split("\n");
2017-04-09 19:55:06 +00:00
for (auto i : lines)
{
if (i != "")
{
ret << i.replace(" ", ",").replace(",,", ",").replace(",,", ",").replace(",,", ",");
}
}
}
2017-04-09 19:55:06 +00:00
}
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];
}
2017-04-09 19:55:06 +00:00
}
else if (type == "flags")
{
if (subtype != NULL && subtype != "")
cmd("fs " + subtype);
else cmd("fs *");
QString flags = cmd("f*");
QStringList lines = flags.split("\n");
2017-04-09 19:55:06 +00:00
for (auto i : lines)
{
if (i[0] != 0 && i[1] == 's') continue; // skip 'fs ..'
ret << i.mid(2).replace(" ", ",");
}
}
return ret;
}
2017-04-09 19:55:06 +00:00
ut64 QRCore::math(const QString &expr)
{
CORE_LOCK();
2017-04-09 19:55:06 +00:00
return r_num_math(this->core_ ? this->core_->num : NULL, expr.toUtf8().constData());
}
2017-04-09 19:55:06 +00:00
int QRCore::fcnCyclomaticComplexity(ut64 addr)
{
CORE_LOCK();
2017-04-09 19:55:06 +00:00
RAnalFunction *fcn = r_anal_get_fcn_at(core_->anal, addr, addr);
if (fcn)
return r_anal_fcn_cc(fcn);
return 0;
}
2017-04-09 19:55:06 +00:00
int QRCore::fcnBasicBlockCount(ut64 addr)
{
CORE_LOCK();
//RAnalFunction *fcn = r_anal_get_fcn_at (core_->anal, addr, addr);
2017-04-09 19:55:06 +00:00
RAnalFunction *fcn = r_anal_get_fcn_in(core_->anal, addr, 0);
if (fcn)
{
return r_list_length(fcn->bbs);
}
return 0;
}
2017-04-09 19:55:06 +00:00
int QRCore::fcnEndBbs(QString addr)
{
CORE_LOCK();
bool ok;
int offset = addr.toLong(&ok, 16);
2017-04-09 19:55:06 +00:00
RAnalFunction *fcn = r_anal_get_fcn_in(core_->anal, offset, 0);
if (fcn)
{
2017-03-31 11:29:11 +00:00
QString tmp = this->cmd("afi @ " + addr + " ~end-bbs").split("\n")[0];
2017-04-09 19:55:06 +00:00
if (tmp.contains(":"))
{
2017-03-31 11:29:11 +00:00
QString endbbs = tmp.split(": ")[1];
return endbbs.toInt();
}
}
return 0;
}
2017-04-09 19:55:06 +00:00
QString QRCore::itoa(ut64 num, int rdx)
{
return QString::number(num, rdx);
}
2017-04-09 19:55:06 +00:00
QString QRCore::config(const QString &k, const QString &v)
{
CORE_LOCK();
QByteArray key = k.toUtf8();
2017-04-09 19:55:06 +00:00
if (v != NULL)
{
r_config_set(core_->config, key.constData(), v.toUtf8().constData());
return NULL;
}
2017-04-09 19:55:06 +00:00
return QString(r_config_get(core_->config, key.constData()));
}
2017-04-09 19:55:06 +00:00
int QRCore::config(const QString &k, int v)
{
CORE_LOCK();
QByteArray key = k.toUtf8();
2017-04-09 19:55:06 +00:00
if (v != -1)
{
r_config_set_i(core_->config, key.constData(), v);
return 0;
}
2017-04-09 19:55:06 +00:00
return r_config_get_i(core_->config, key.constData());
}
2017-04-09 19:55:06 +00:00
void QRCore::setOptions(QString key)
{
QNOTUSED(key);
// va
// lowercase
// show bytes
// att syntax
// asm plugin
// cpu type
// anal plugin
}
2017-04-09 19:55:06 +00:00
void QRCore::setCPU(QString arch, QString cpu, int bits, bool temporary = false)
{
config("asm.arch", arch);
config("asm.cpu", cpu);
config("asm.bits", bits);
if (!temporary)
{
default_arch = arch;
default_cpu = cpu;
default_bits = bits;
}
}
2017-04-09 19:55:06 +00:00
void QRCore::setDefaultCPU()
{
config("asm.arch", default_arch);
config("asm.cpu", default_cpu);
config("asm.bits", QString::number(default_bits));
}
2017-04-09 19:55:06 +00:00
QString QRCore::assemble(const QString &code)
{
CORE_LOCK();
2017-04-09 19:55:06 +00:00
RAsmCode *ac = r_asm_massemble(core_->assembler, code.toUtf8().constData());
QString hex(ac != nullptr ? ac->buf_hex : "");
2017-04-09 19:55:06 +00:00
r_asm_code_free(ac);
return hex;
}
2017-04-09 19:55:06 +00:00
QString QRCore::disassemble(const QString &hex)
{
CORE_LOCK();
RAsmCode *ac = r_asm_mdisassemble_hexstr(core_->assembler, hex.toUtf8().constData());
2017-04-09 19:55:06 +00:00
QString code = QString(ac != nullptr ? ac->buf_asm : "");
r_asm_code_free(ac);
return code;
}
2017-04-09 19:55:06 +00:00
RAnalFunction *QRCore::functionAt(ut64 addr)
{
CORE_LOCK();
//return r_anal_fcn_find (core_->anal, addr, addr);
2017-04-09 19:55:06 +00:00
return r_anal_get_fcn_in(core_->anal, addr, 0);
}
2017-04-09 19:55:06 +00:00
QString QRCore::cmdFunctionAt(QString addr)
{
QString ret;
//afi~name:1[1] @ 0x08048e44
//ret = cmd("afi~name[1] @ " + addr);
ret = cmd("fd @ " + addr + "~[0]");
return ret.trimmed();
}
int QRCore::get_size()
{
CORE_LOCK();
RBinObject *obj = r_bin_get_object(core_->bin);
//return obj->size;
return obj != nullptr ? obj->obj_size : 0;
}
ulong QRCore::get_baddr()
{
CORE_LOCK();
ulong baddr = r_bin_get_baddr(core_->bin);
return baddr;
}
QList<QList<QString>> QRCore::get_exec_sections()
{
2017-04-09 19:55:06 +00:00
QList<QList<QString>> ret;
2017-04-09 19:55:06 +00:00
QString text = cmd("S*~^S");
for (QString line : text.split("\n"))
{
QStringList fields = line.split(" ");
2017-04-09 19:55:06 +00:00
if (fields.length() == 7)
{
if (fields[6].contains("x"))
{
QList<QString> tmp = QList<QString>();
tmp << fields[2];
tmp << fields[3];
tmp << fields[5];
ret << tmp;
}
}
}
return ret;
}
2017-04-09 19:55:06 +00:00
QString QRCore::getOffsetInfo(QString addr)
{
return cmd("ao @ " + addr);
}
2017-04-09 19:55:06 +00:00
QString QRCore::getOffsetJump(QString addr)
{
QString ret = "";
ret = cmd("ao @" + addr + "~jump[1]");
return ret;
}
2017-04-09 19:55:06 +00:00
QString QRCore::getDecompiledCode(QString addr)
{
return cmd("pdc @ " + addr);
}
2017-04-09 19:55:06 +00:00
QString QRCore::getFileInfo()
{
QString info;
info = cmd("ij");
return info;
}
2017-04-09 19:55:06 +00:00
QStringList QRCore::getStats()
{
QStringList stats;
cmd("fs functions");
stats << cmd("f~?").trimmed();
QString imps = cmd("ii~?").trimmed();
stats << imps;
cmd("fs symbols");
stats << cmd("f~?").trimmed();
cmd("fs strings");
stats << cmd("f~?").trimmed();
cmd("fs relocs");
stats << cmd("f~?").trimmed();
cmd("fs sections");
stats << cmd("f~?").trimmed();
cmd("fs *");
stats << cmd("f~?").trimmed();
return stats;
}
2017-04-09 19:55:06 +00:00
QString QRCore::getSimpleGraph(QString function)
{
// New styles
QString graph = "graph [bgcolor=invis, splines=polyline];";
QString node = "node [style=\"filled\" fillcolor=\"#4183D7\" shape=box fontname=\"Courier\" fontsize=\"8\" color=\"#4183D7\" fontcolor=\"white\"];";
QString arrow = "edge [arrowhead=\"normal\";]";
// Old styles
QString old_graph = "graph [bgcolor=white fontsize=8 fontname=\"Courier\"];";
//QString old_node = "node [color=lightgray, style=filled shape=box];";
QString old_node = "node [fillcolor=gray style=filled shape=box];";
QString old_arrow = "edge [arrowhead=\"vee\"];";
QString dot = cmd("aga @ " + function).trimmed();
dot.replace(old_graph, graph);
dot.replace(old_node, node);
dot.replace(old_arrow, arrow);
dot.replace("fillcolor=blue", "fillcolor=\"#EC644B\", color=\"#EC644B\"");
return dot;
}
2017-04-09 19:55:06 +00:00
void QRCore::getOpcodes()
{
QString opcodes = cmd("?O");
this->opcodes = opcodes.split("\n");
// Remove the last empty element
this->opcodes.removeLast();
QString registers = cmd("drp~[1]");
this->regs = registers.split("\n");
this->regs.removeLast();
}
2017-04-09 19:55:06 +00:00
void QRCore::setSettings()
{
config("scr.color", "false");
2017-04-09 19:55:06 +00:00
config("scr.interactive", "false");
config("asm.lines", "false");
// Intredazting...
//config("asm.linesright", "true");
//config("asm.lineswidth", "15");
//config("asm.functions", "false");
config("hex.pairs", "false");
config("asm.bytespace", "true");
config("asm.cmtflgrefs", "false");
config("asm.cmtright", "true");
config("asm.cmtcol", "70");
config("asm.xrefs", "false");
config("asm.fcnlines", "false");
config("asm.tabs", "5");
config("asm.tabsonce", "true");
config("asm.tabsoff", "5");
config("asm.nbytes", "10");
config("asm.midflags", "2");
//config("asm.bbline", "true");
config("anal.hasnext", "true");
config("asm.fcncalls", "false");
config("asm.calls", "false");
2017-04-09 19:55:06 +00:00
config("asm.lines.call", "false");
config("asm.flgoff", "true");
config("anal.autoname", "true");
// Highlight current node in graphviz
config("graph.gv.current", "true");
// Fucking pancake xD
config("cfg.fortunes.tts", "false");
// Experimenting with asm options
//config("asm.spacy", "true"); // We need to handle blank lines on scroll
//config("asm.section", "true"); // Breaks the disasm and navigation
//config("asm.invhex", "true"); // Needs further testing
//config("asm.flags", "false"); // Add with default true in future
// Used by the HTML5 graph
2017-04-09 19:55:06 +00:00
config("http.cors", "true");
config("http.sandbox", "false");
2017-04-03 11:03:26 +00:00
//config("http.port", "14170");
// Temporary fixes
//config("http.root","/usr/local/share/radare2/last/www");
//config("http.root","/usr/local/radare2/osx/share/radare2/1.1.0-git/www");
//config("bin.rawstr", "true");
// Graph colors and design
cmd("ec graph.true rgb:88FF88");
cmd("ec graph.false rgb:FF6666");
cmd("ec graph.trufae rgb:4183D7");
}