Use r2 tasks for fetching strings

This commit is contained in:
Florian Märkl 2018-05-29 18:19:59 +02:00
parent cc3ad67096
commit e3bd0612d9
4 changed files with 87 additions and 59 deletions

View File

@ -159,7 +159,9 @@ QString CutterCore::cmd(const QString &str)
RVA offset = core_->offset; RVA offset = core_->offset;
QByteArray cmd = str.toUtf8(); QByteArray cmd = str.toUtf8();
r_core_task_sync_begin(core_);
char *res = r_core_cmd_str(this->core_, cmd.constData()); char *res = r_core_cmd_str(this->core_, cmd.constData());
r_core_task_sync_end(core_);
QString o = QString(res ? res : ""); QString o = QString(res ? res : "");
r_mem_free(res); r_mem_free(res);
if (offset != core_->offset) { if (offset != core_->offset) {
@ -185,12 +187,38 @@ QJsonDocument CutterCore::cmdj(const QString &str)
CORE_LOCK(); CORE_LOCK();
QByteArray cmd = str.toUtf8(); QByteArray cmd = str.toUtf8();
r_core_task_sync_begin(core_);
char *res = r_core_cmd_str(this->core_, cmd.constData()); char *res = r_core_cmd_str(this->core_, cmd.constData());
r_core_task_sync_end(core_);
QJsonDocument doc = parseJson(res, str);
r_mem_free(res);
return doc;
}
QString CutterCore::cmdTask(const QString &str)
{
RCoreTask *task = startTask(str);
joinTask(task);
QString ret = QString::fromUtf8(task->res);
deleteTask(task);
return ret;
}
QJsonDocument CutterCore::cmdjTask(const QString &str)
{
RCoreTask *task = startTask(str);
joinTask(task);
QJsonDocument ret = parseJson(task->res, str);
deleteTask(task);
return ret;
}
QJsonDocument CutterCore::parseJson(const char *res, const QString &cmd)
{
QString resString = QString(res); QString resString = QString(res);
if (resString.isEmpty()) { if (resString.isEmpty()) {
r_mem_free(res);
return QJsonDocument(); return QJsonDocument();
} }
@ -198,12 +226,15 @@ QJsonDocument CutterCore::cmdj(const QString &str)
QJsonDocument doc = res ? QJsonDocument::fromJson(resString.toUtf8(), &jsonError) : QJsonDocument(); QJsonDocument doc = res ? QJsonDocument::fromJson(resString.toUtf8(), &jsonError) : QJsonDocument();
if (jsonError.error != QJsonParseError::NoError) { if (jsonError.error != QJsonParseError::NoError) {
eprintf("Failed to parse JSON for command \"%s\": %s\n", str.toLocal8Bit().constData(), if (!cmd.isNull()) {
eprintf("Failed to parse JSON for command \"%s\": %s\n", cmd.toLocal8Bit().constData(),
jsonError.errorString().toLocal8Bit().constData()); jsonError.errorString().toLocal8Bit().constData());
} else {
eprintf("Failed to parse JSON: %s\n", jsonError.errorString().toLocal8Bit().constData());
}
eprintf("%s\n", resString.toLocal8Bit().constData()); eprintf("%s\n", resString.toLocal8Bit().constData());
} }
r_mem_free(res);
return doc; return doc;
} }
@ -1177,11 +1208,14 @@ QList<RelocDescription> CutterCore::getAllRelocs()
QList<StringDescription> CutterCore::getAllStrings() QList<StringDescription> CutterCore::getAllStrings()
{ {
//CORE_LOCK(); return parseStringsJson(cmdjTask("izzj"));
QList<StringDescription> ret; }
//QJsonDocument stringsDoc = cmdj("izzj");
/*QJsonObject stringsObj = stringsDoc.object(); QList<StringDescription> CutterCore::parseStringsJson(const QJsonDocument &doc)
{
QList<StringDescription> ret;
QJsonObject stringsObj = doc.object();
QJsonArray stringsArray = stringsObj["strings"].toArray(); QJsonArray stringsArray = stringsObj["strings"].toArray();
for (QJsonValue value : stringsArray) { for (QJsonValue value : stringsArray) {
QJsonObject stringObject = value.toObject(); QJsonObject stringObject = value.toObject();
@ -1196,56 +1230,6 @@ QList<StringDescription> CutterCore::getAllStrings()
ret << string; ret << string;
} }
return ret;*/
RBinFile *bf = r_core_bin_cur(core_);
if (!bf) {
return {};
}
int min = getConfigi("bin.minstr");
int rawstrTmp = bf->rawstr;
bf->rawstr = 2;
RList *list = r_bin_file_get_strings(bf, min, 0);
bf->rawstr = rawstrTmp;
if (!list) {
return {};
}
RListIter *iter;
void *s;
r_list_foreach (list, iter, s) {
RBinString *str = reinterpret_cast<RBinString *>(s);
StringDescription string;
switch (str->type) {
case R_STRING_TYPE_ASCII:
string.string = QString::fromUtf8(str->string);
string.type = "ASCII";
break;
case R_STRING_TYPE_UTF8:
string.string = QString::fromUtf8(str->string);
string.type = "UTF-8";
break;
default:
// TODO: utf-16, utf-32, etc.
string.string = QString::fromUtf8(str->string);
string.type = "TODO";
break;
}
string.string = QString::fromUtf8(str->string);
string.vaddr = str->vaddr;
string.size = str->size;
string.length = str->length;
ret << string;
}
r_list_free(list);
return ret; return ret;
} }
@ -1709,12 +1693,15 @@ QString CutterCore::getVersionInformation()
} }
return ret; return ret;
} }
QJsonArray CutterCore::getOpenedFiles() QJsonArray CutterCore::getOpenedFiles()
{ {
QJsonDocument files = cmdj("oj"); QJsonDocument files = cmdj("oj");
return files.array(); return files.array();
} }
QList<QString> CutterCore::getColorThemes() QList<QString> CutterCore::getColorThemes()
{ {
QList<QString> r; QList<QString> r;
@ -1723,3 +1710,20 @@ QList<QString> CutterCore::getColorThemes()
r << s.toString(); r << s.toString();
return r; return r;
} }
RCoreTask *CutterCore::startTask(const QString &cmd)
{
RCoreTask *task = r_core_task_new (core_, cmd.toLocal8Bit().constData(), nullptr, nullptr);
r_core_task_enqueue(core_, task);
return task;
}
void CutterCore::joinTask(RCoreTask *task)
{
r_core_task_join(core_, nullptr, task);
}
void CutterCore::deleteTask(RCoreTask *task)
{
r_core_task_del(core_, task->id);
}

View File

@ -327,8 +327,12 @@ public:
l.removeAll(""); l.removeAll("");
return l; return l;
} }
QString cmdTask(const QString &str);
QJsonDocument cmdjTask(const QString &str);
QString getVersionInformation(); QString getVersionInformation();
QJsonDocument parseJson(const char *res, const QString &cmd = QString());
/* Functions methods */ /* Functions methods */
void renameFunction(const QString &oldName, const QString &newName); void renameFunction(const QString &oldName, const QString &newName);
void delFunction(RVA addr); void delFunction(RVA addr);
@ -488,6 +492,8 @@ public:
QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function, QList<XrefDescription> getXRefs(RVA addr, bool to, bool whole_function,
const QString &filterType = QString::null); const QString &filterType = QString::null);
QList<StringDescription> parseStringsJson(const QJsonDocument &doc);
/* Signals related */ /* Signals related */
void triggerVarsChanged(); void triggerVarsChanged();
void triggerFunctionRenamed(const QString &prevName, const QString &newName); void triggerFunctionRenamed(const QString &prevName, const QString &newName);
@ -495,6 +501,10 @@ public:
void triggerAsmOptionsChanged(); void triggerAsmOptionsChanged();
void triggerGraphOptionsChanged(); void triggerGraphOptionsChanged();
RCoreTask *startTask(const QString &cmd);
void joinTask(RCoreTask *task);
void deleteTask(RCoreTask *task);
RCoreLocked core() const; RCoreLocked core() const;
signals: signals:

View File

@ -323,8 +323,13 @@ void MainWindow::openProject(const QString &project_name)
finalizeOpen(); finalizeOpen();
} }
#include <valgrind/callgrind.h>
void MainWindow::finalizeOpen() void MainWindow::finalizeOpen()
{ {
CALLGRIND_ZERO_STATS;
CALLGRIND_START_INSTRUMENTATION;
core->getOpcodes(); core->getOpcodes();
// Set settings to override any incorrect saved in the project // Set settings to override any incorrect saved in the project
@ -341,6 +346,9 @@ void MainWindow::finalizeOpen()
// Add fortune message // Add fortune message
addOutput("\n" + core->cmd("fo")); addOutput("\n" + core->cmd("fo"));
showMaximized(); showMaximized();
CALLGRIND_DUMP_STATS;
CALLGRIND_STOP_INSTRUMENTATION;
} }
bool MainWindow::saveProject(bool quit) bool MainWindow::saveProject(bool quit)

View File

@ -4,5 +4,11 @@
void StringsTask::runTask() void StringsTask::runTask()
{ {
auto strings = Core()->getAllStrings(); auto strings = Core()->getAllStrings();
/*RCoreTask *task = Core()->startTask("izzj");
Core()->joinTask(task);
QList<StringDescription> strings = Core()->parseStringsJson(task->msg->res);*/
emit stringSearchFinished(strings); emit stringSearchFinished(strings);
} }