Add RizinFunctionTask and common base class with RizinCmdTask (#2520)

This commit is contained in:
Florian Märkl 2020-12-18 10:47:50 +01:00 committed by GitHub
parent 37ec41ffae
commit 5bf513c45b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 106 additions and 52 deletions

View File

@ -33,8 +33,8 @@ void R2DecDecompiler::decompileAt(RVA addr)
if (task) {
return;
}
task = new RizinTask("pddj @ " + QString::number(addr));
connect(task, &RizinTask::finished, this, [this]() {
task = new RizinCmdTask("pddj @ " + QString::number(addr));
connect(task, &RizinCmdTask::finished, this, [this]() {
QJsonObject json = task->getResultJson().object();
delete task;
task = nullptr;

View File

@ -42,7 +42,7 @@ class R2DecDecompiler: public Decompiler
Q_OBJECT
private:
RizinTask *task;
RizinCmdTask *task;
public:
explicit R2DecDecompiler(QObject *parent = nullptr);

View File

@ -2,6 +2,8 @@
#include "DecompilerHighlighter.h"
#include "common/Configuration.h"
#include <memory>
DecompilerHighlighter::DecompilerHighlighter(QTextDocument *parent)
: QSyntaxHighlighter(parent)
{

View File

@ -2,29 +2,11 @@
#include "RizinTask.h"
#include <rz_core.h>
RizinTask::RizinTask(const QString &cmd, bool transient)
{
task = rz_core_cmd_task_new(Core()->core(),
cmd.toLocal8Bit().constData(),
static_cast<RzCoreCmdTaskFinished>(&RizinTask::taskFinishedCallback),
this);
task->transient = transient;
rz_core_task_incref(task);
}
RizinTask::~RizinTask()
{
if (task) {
rz_core_task_decref(task);
}
void RizinTask::taskFinishedCallback(const char *, void *user)
{
reinterpret_cast<RizinTask *>(user)->taskFinished();
}
void RizinTask::taskFinished()
{
emit finished();
}
}
void RizinTask::startTask()
@ -42,25 +24,67 @@ void RizinTask::joinTask()
rz_core_task_join(&Core()->core_->tasks, nullptr, task->id);
}
QString RizinTask::getResult()
void RizinTask::taskFinished()
{
emit finished();
}
// RizinCmdTask
RizinCmdTask::RizinCmdTask(const QString &cmd, bool transient)
{
task = rz_core_cmd_task_new(Core()->core(),
cmd.toLocal8Bit().constData(),
static_cast<RzCoreCmdTaskFinished>(&RizinCmdTask::taskFinishedCallback),
this);
task->transient = transient;
rz_core_task_incref(task);
}
void RizinCmdTask::taskFinishedCallback(const char *, void *user)
{
reinterpret_cast<RizinCmdTask *>(user)->taskFinished();
}
QString RizinCmdTask::getResult()
{
const char *res = rz_core_cmd_task_get_result(task);
if(!res) {
if (!res) {
return nullptr;
}
return QString::fromUtf8(res);
}
QJsonDocument RizinTask::getResultJson()
QJsonDocument RizinCmdTask::getResultJson()
{
const char *res = rz_core_cmd_task_get_result(task);
if(!res) {
if (!res) {
return QJsonDocument();
}
return Core()->parseJson(res, nullptr);
}
const char *RizinTask::getResultRaw()
const char *RizinCmdTask::getResultRaw()
{
return rz_core_cmd_task_get_result(task);
}
// RizinFunctionTask
RizinFunctionTask::RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool transient)
: fcn(fcn), res(nullptr)
{
task = rz_core_function_task_new(Core()->core(),
static_cast<RzCoreTaskFunction>(&RizinFunctionTask::runner),
this);
task->transient = transient;
rz_core_task_incref(task);
}
void *RizinFunctionTask::runner(RzCore *core, void *user)
{
RizinFunctionTask *task = reinterpret_cast<RizinFunctionTask *>(user);
task->res = task->fcn(core);
task->taskFinished();
return nullptr;
}

View File

@ -4,32 +4,58 @@
#include "core/Cutter.h"
class RizinTask: public QObject
class CUTTER_EXPORT RizinTask: public QObject
{
Q_OBJECT
private:
protected:
RzCoreTask *task;
static void taskFinishedCallback(const char *, void *user);
RizinTask() {}
void taskFinished();
public:
using Ptr = QSharedPointer<RizinTask>;
explicit RizinTask(const QString &cmd, bool transient = true);
~RizinTask();
virtual ~RizinTask();
void startTask();
void breakTask();
void joinTask();
QString getResult();
QJsonDocument getResultJson();
const char *getResultRaw();
signals:
void finished();
};
class CUTTER_EXPORT RizinCmdTask: public RizinTask
{
Q_OBJECT
private:
static void taskFinishedCallback(const char *, void *user);
public:
explicit RizinCmdTask(const QString &cmd, bool transient = true);
QString getResult();
QJsonDocument getResultJson();
const char *getResultRaw();
};
class CUTTER_EXPORT RizinFunctionTask: public RizinTask
{
Q_OBJECT
private:
std::function<void *(RzCore *)> fcn;
void *res;
static void *runner(RzCore *core, void *user);
public:
explicit RizinFunctionTask(std::function<void *(RzCore *)> fcn, bool transient = true);
void *getResult() { return res; }
};
#endif // RZTASK_H

View File

@ -15,6 +15,7 @@
#include "common/Configuration.h"
#include "common/AsyncTask.h"
#include "common/RizinTask.h"
#include "dialogs/RizinTaskDialog.h"
#include "common/Json.h"
#include "core/Cutter.h"
#include "Decompiler.h"
@ -394,7 +395,7 @@ bool CutterCore::isDebugTaskInProgress()
return false;
}
bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinTask> &task)
bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask> &task)
{
asyncCmd(command, task);
@ -402,7 +403,7 @@ bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinTask> &ta
return false;
}
connect(task.data(), &RizinTask::finished, task.data(), [this, task] () {
connect(task.data(), &RizinCmdTask::finished, task.data(), [this, task] () {
QString res = task.data()->getResult();
if (res.contains(QStringLiteral("[ESIL] Stopped execution in an invalid instruction"))) {
@ -413,7 +414,7 @@ bool CutterCore::asyncCmdEsil(const char *command, QSharedPointer<RizinTask> &ta
return true;
}
bool CutterCore::asyncCmd(const char *str, QSharedPointer<RizinTask> &task)
bool CutterCore::asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task)
{
if (!task.isNull()) {
return false;
@ -423,8 +424,8 @@ bool CutterCore::asyncCmd(const char *str, QSharedPointer<RizinTask> &task)
RVA offset = core->offset;
task = QSharedPointer<RizinTask>(new RizinTask(str, true));
connect(task.data(), &RizinTask::finished, task.data(), [this, offset, task] () {
task = QSharedPointer<RizinCmdTask>(new RizinCmdTask(str, true));
connect(task.data(), &RizinCmdTask::finished, task.data(), [this, offset, task] () {
CORE_LOCK();
if (offset != core->offset) {
@ -494,7 +495,7 @@ QJsonDocument CutterCore::cmdjAt(const char *str, RVA address)
QString CutterCore::cmdTask(const QString &str)
{
RizinTask task(str);
RizinCmdTask task(str);
task.startTask();
task.joinTask();
return task.getResult();
@ -502,7 +503,7 @@ QString CutterCore::cmdTask(const QString &str)
QJsonDocument CutterCore::cmdjTask(const QString &str)
{
RizinTask task(str);
RizinCmdTask task(str);
task.startTask();
task.joinTask();
return parseJson(task.getResultRaw(), str);

View File

@ -21,12 +21,11 @@ class BasicInstructionHighlighter;
class CutterCore;
class Decompiler;
class RizinTask;
class RizinCmdTask;
class RizinTaskDialog;
#include "common/BasicBlockHighlighter.h"
#include "common/RizinTask.h"
#include "common/Helpers.h"
#include "dialogs/RizinTaskDialog.h"
#include <rz_project.h>
@ -75,8 +74,8 @@ public:
* Once you have setup connections you can start the task with task->startTask()
* If you want to seek to an address, you should use CutterCore::seek.
*/
bool asyncCmd(const char *str, QSharedPointer<RizinTask> &task);
bool asyncCmd(const QString &str, QSharedPointer<RizinTask> &task) { return asyncCmd(str.toUtf8().constData(), task); }
bool asyncCmd(const char *str, QSharedPointer<RizinCmdTask> &task);
bool asyncCmd(const QString &str, QSharedPointer<RizinCmdTask> &task) { return asyncCmd(str.toUtf8().constData(), task); }
/**
* @brief Execute a Rizin command \a cmd. By nature, the API
@ -132,8 +131,8 @@ public:
* Once you have setup connections you can start the task with task->startTask()
* If you want to seek to an address, you should use CutterCore::seek.
*/
bool asyncCmdEsil(const char *command, QSharedPointer<RizinTask> &task);
bool asyncCmdEsil(const QString &command, QSharedPointer<RizinTask> &task) { return asyncCmdEsil(command.toUtf8().constData(), task); }
bool asyncCmdEsil(const char *command, QSharedPointer<RizinCmdTask> &task);
bool asyncCmdEsil(const QString &command, QSharedPointer<RizinCmdTask> &task) { return asyncCmdEsil(command.toUtf8().constData(), task); }
QString getVersionInformation();
QJsonDocument parseJson(const char *res, const char *cmd = nullptr);
@ -725,7 +724,7 @@ private:
bool iocache = false;
BasicInstructionHighlighter biHighlighter;
QSharedPointer<RizinTask> debugTask;
QSharedPointer<RizinCmdTask> debugTask;
RizinTaskDialog *debugTaskDialog;
QVector<QString> getCutterRCFilePaths() const;

View File

@ -4,6 +4,8 @@
#include "core/Cutter.h"
#include "GraphLayout.h"
#include <memory>
/**
* @brief Adapter for converting vertical graph layout into horizontal one.
*/