mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 19:06:10 +00:00
Remove JSDec as decompiler and use rizin C api
This commit is contained in:
parent
c20d2c61d6
commit
2106551d00
@ -120,10 +120,6 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
|||||||
|
|
||||||
Config()->setOutputRedirectionEnabled(clOptions.outputRedirectionEnabled);
|
Config()->setOutputRedirectionEnabled(clOptions.outputRedirectionEnabled);
|
||||||
|
|
||||||
if (JSDecDecompiler::isAvailable()) {
|
|
||||||
Core()->registerDecompiler(new JSDecDecompiler(Core()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CUTTER_RZGHIDRA_STATIC
|
#if CUTTER_RZGHIDRA_STATIC
|
||||||
Core()->registerDecompiler(new RzGhidraDecompiler(Core()));
|
Core()->registerDecompiler(new RzGhidraDecompiler(Core()));
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,107 +10,8 @@ Decompiler::Decompiler(const QString &id, const QString &name, QObject *parent)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *jsonToStrdup(const CutterJson &str)
|
|
||||||
{
|
|
||||||
const RzJson *j = str.lowLevelValue();
|
|
||||||
if (!j || j->type != RZ_JSON_STRING) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return rz_str_dup(j->str_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static RzAnnotatedCode *parseJsonCode(CutterJson &json)
|
|
||||||
{
|
|
||||||
char *raw_code = jsonToStrdup(json["code"]);
|
|
||||||
if (!raw_code) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
RzAnnotatedCode *code = rz_annotated_code_new(raw_code);
|
|
||||||
if (!code) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
for (const auto &jsonAnnotation : json["annotations"]) {
|
|
||||||
RzCodeAnnotation annotation = {};
|
|
||||||
annotation.start = jsonAnnotation["start"].toUt64();
|
|
||||||
annotation.end = jsonAnnotation["end"].toUt64();
|
|
||||||
QString type = jsonAnnotation["type"].toString();
|
|
||||||
if (type == "offset") {
|
|
||||||
annotation.type = RZ_CODE_ANNOTATION_TYPE_OFFSET;
|
|
||||||
annotation.offset.offset = jsonAnnotation["offset"].toString().toULongLong();
|
|
||||||
} else if (type == "function_name") {
|
|
||||||
annotation.type = RZ_CODE_ANNOTATION_TYPE_FUNCTION_NAME;
|
|
||||||
annotation.reference.name = jsonToStrdup(jsonAnnotation["name"]);
|
|
||||||
annotation.reference.offset = jsonAnnotation["offset"].toString().toULongLong();
|
|
||||||
} else if (type == "global_variable") {
|
|
||||||
annotation.type = RZ_CODE_ANNOTATION_TYPE_GLOBAL_VARIABLE;
|
|
||||||
annotation.reference.offset = jsonAnnotation["offset"].toString().toULongLong();
|
|
||||||
} else if (type == "constant_variable") {
|
|
||||||
annotation.type = RZ_CODE_ANNOTATION_TYPE_CONSTANT_VARIABLE;
|
|
||||||
annotation.reference.offset = jsonAnnotation["offset"].toString().toULongLong();
|
|
||||||
} else if (type == "local_variable") {
|
|
||||||
annotation.type = RZ_CODE_ANNOTATION_TYPE_LOCAL_VARIABLE;
|
|
||||||
annotation.variable.name = jsonToStrdup(jsonAnnotation["name"]);
|
|
||||||
} else if (type == "function_parameter") {
|
|
||||||
annotation.type = RZ_CODE_ANNOTATION_TYPE_FUNCTION_PARAMETER;
|
|
||||||
annotation.variable.name = jsonToStrdup(jsonAnnotation["name"]);
|
|
||||||
} else if (type == "syntax_highlight") {
|
|
||||||
annotation.type = RZ_CODE_ANNOTATION_TYPE_SYNTAX_HIGHLIGHT;
|
|
||||||
QString highlightType = jsonAnnotation["syntax_highlight"].toString();
|
|
||||||
if (highlightType == "keyword") {
|
|
||||||
annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_KEYWORD;
|
|
||||||
} else if (highlightType == "comment") {
|
|
||||||
annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_COMMENT;
|
|
||||||
} else if (highlightType == "datatype") {
|
|
||||||
annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_DATATYPE;
|
|
||||||
} else if (highlightType == "function_name") {
|
|
||||||
annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_NAME;
|
|
||||||
} else if (highlightType == "function_parameter") {
|
|
||||||
annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_FUNCTION_PARAMETER;
|
|
||||||
} else if (highlightType == "local_variable") {
|
|
||||||
annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_LOCAL_VARIABLE;
|
|
||||||
} else if (highlightType == "constant_variable") {
|
|
||||||
annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_CONSTANT_VARIABLE;
|
|
||||||
} else if (highlightType == "global_variable") {
|
|
||||||
annotation.syntax_highlight.type = RZ_SYNTAX_HIGHLIGHT_TYPE_GLOBAL_VARIABLE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rz_annotated_code_add_annotation(code, &annotation);
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage)
|
RzAnnotatedCode *Decompiler::makeWarning(QString warningMessage)
|
||||||
{
|
{
|
||||||
std::string temporary = warningMessage.toStdString();
|
std::string temporary = warningMessage.toStdString();
|
||||||
return rz_annotated_code_new(strdup(temporary.c_str()));
|
return rz_annotated_code_new(strdup(temporary.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
JSDecDecompiler::JSDecDecompiler(QObject *parent) : Decompiler("jsdec", "jsdec", parent)
|
|
||||||
{
|
|
||||||
task = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JSDecDecompiler::isAvailable()
|
|
||||||
{
|
|
||||||
return Core()->getConfigVariableSpaces().contains("jsdec");
|
|
||||||
}
|
|
||||||
|
|
||||||
void JSDecDecompiler::decompileAt(RVA addr)
|
|
||||||
{
|
|
||||||
if (task) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
task = new RizinCmdTask("pddA @ " + QString::number(addr));
|
|
||||||
connect(task, &RizinCmdTask::finished, this, [this]() {
|
|
||||||
CutterJson json = task->getResultJson();
|
|
||||||
delete task;
|
|
||||||
task = nullptr;
|
|
||||||
if (!json.size()) {
|
|
||||||
emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from jsdec")));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RzAnnotatedCode *code = parseJsonCode(json);
|
|
||||||
emit finished(code);
|
|
||||||
});
|
|
||||||
task->startTask();
|
|
||||||
}
|
|
||||||
|
@ -37,20 +37,4 @@ signals:
|
|||||||
void finished(RzAnnotatedCode *codeDecompiled);
|
void finished(RzAnnotatedCode *codeDecompiled);
|
||||||
};
|
};
|
||||||
|
|
||||||
class JSDecDecompiler : public Decompiler
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
RizinCmdTask *task;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit JSDecDecompiler(QObject *parent = nullptr);
|
|
||||||
void decompileAt(RVA addr) override;
|
|
||||||
|
|
||||||
bool isRunning() override { return task != nullptr; }
|
|
||||||
|
|
||||||
static bool isAvailable();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // DECOMPILER_H
|
#endif // DECOMPILER_H
|
||||||
|
@ -62,7 +62,7 @@ CutterJson RizinCmdTask::getResultJson()
|
|||||||
}
|
}
|
||||||
char *copy = static_cast<char *>(rz_mem_alloc(strlen(res) + 1));
|
char *copy = static_cast<char *>(rz_mem_alloc(strlen(res) + 1));
|
||||||
strcpy(copy, res);
|
strcpy(copy, res);
|
||||||
return Core()->parseJson(copy, nullptr);
|
return Core()->parseJson("task", copy, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *RizinCmdTask::getResultRaw()
|
const char *RizinCmdTask::getResultRaw()
|
||||||
|
@ -273,6 +273,7 @@ void CutterCore::loadCutterRC()
|
|||||||
}
|
}
|
||||||
qInfo() << tr("Loading initialization file from ") << cutterRCFilePath;
|
qInfo() << tr("Loading initialization file from ") << cutterRCFilePath;
|
||||||
rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
|
rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
|
||||||
|
rz_cons_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,6 +287,7 @@ void CutterCore::loadDefaultCutterRC()
|
|||||||
}
|
}
|
||||||
qInfo() << tr("Loading initialization file from ") << cutterRCFilePath;
|
qInfo() << tr("Loading initialization file from ") << cutterRCFilePath;
|
||||||
rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
|
rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
|
||||||
|
rz_cons_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QString> CutterCore::sdbList(QString path)
|
QList<QString> CutterCore::sdbList(QString path)
|
||||||
@ -473,19 +475,7 @@ QString CutterCore::cmdRaw(const char *cmd)
|
|||||||
{
|
{
|
||||||
QString res;
|
QString res;
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
rz_cons_push();
|
return rz_core_cmd_str(core, cmd);
|
||||||
|
|
||||||
// rz_core_cmd does not return the output of the command
|
|
||||||
rz_core_cmd(core, cmd, 0);
|
|
||||||
|
|
||||||
// we grab the output straight from rz_cons
|
|
||||||
res = rz_cons_get_buffer();
|
|
||||||
|
|
||||||
// cleaning up
|
|
||||||
rz_cons_pop();
|
|
||||||
rz_cons_echo(NULL);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CutterJson CutterCore::cmdj(const char *str)
|
CutterJson CutterCore::cmdj(const char *str)
|
||||||
@ -496,7 +486,7 @@ CutterJson CutterCore::cmdj(const char *str)
|
|||||||
res = rz_core_cmd_str(core, str);
|
res = rz_core_cmd_str(core, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parseJson(res, str);
|
return parseJson("cmdj", res, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CutterCore::cmdTask(const QString &str)
|
QString CutterCore::cmdTask(const QString &str)
|
||||||
@ -507,9 +497,9 @@ QString CutterCore::cmdTask(const QString &str)
|
|||||||
return task.getResult();
|
return task.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
CutterJson CutterCore::parseJson(char *res, const char *cmd)
|
CutterJson CutterCore::parseJson(const char *name, char *res, const char *cmd)
|
||||||
{
|
{
|
||||||
if (!res) {
|
if (RZ_STR_ISEMPTY(res)) {
|
||||||
return CutterJson();
|
return CutterJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,18 +507,11 @@ CutterJson CutterCore::parseJson(char *res, const char *cmd)
|
|||||||
|
|
||||||
if (!doc) {
|
if (!doc) {
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
eprintf("Failed to parse JSON for command \"%s\"\n", cmd);
|
RZ_LOG_ERROR("%s: Failed to parse JSON for command \"%s\"\n%s\n", name, cmd, res);
|
||||||
} else {
|
} else {
|
||||||
eprintf("Failed to parse JSON\n");
|
RZ_LOG_ERROR("%s: Failed to parse JSON %s\n", name, res);
|
||||||
}
|
|
||||||
const int MAX_JSON_DUMP_SIZE = 8 * 1024;
|
|
||||||
size_t originalSize = strlen(res);
|
|
||||||
if (originalSize > MAX_JSON_DUMP_SIZE) {
|
|
||||||
res[MAX_JSON_DUMP_SIZE] = 0;
|
|
||||||
eprintf("%zu bytes total: %s ...\n", originalSize, res);
|
|
||||||
} else {
|
|
||||||
eprintf("%s\n", res);
|
|
||||||
}
|
}
|
||||||
|
RZ_LOG_ERROR("%s: %s\n", name, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CutterJson(doc, QSharedPointer<CutterJsonOwner>::create(doc, res));
|
return CutterJson(doc, QSharedPointer<CutterJsonOwner>::create(doc, res));
|
||||||
@ -602,8 +585,6 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int
|
|||||||
rz_bin_select_idx(core->bin, NULL, idx);
|
rz_bin_select_idx(core->bin, NULL, idx);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
|
||||||
// Not loading RzBin info coz va = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto iod = core->io ? core->io->desc : NULL;
|
auto iod = core->io ? core->io->desc : NULL;
|
||||||
@ -611,7 +592,8 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int
|
|||||||
core->file && iod && (core->file->fd == iod->fd) && iod->plugin && iod->plugin->isdbg;
|
core->file && iod && (core->file->fd == iod->fd) && iod->plugin && iod->plugin->isdbg;
|
||||||
|
|
||||||
if (!debug && rz_flag_get(core->flags, "entry0")) {
|
if (!debug && rz_flag_get(core->flags, "entry0")) {
|
||||||
rz_core_cmd0(core, "s entry0");
|
ut64 addr = rz_num_math(core->num, "entry0");
|
||||||
|
rz_core_seek_and_save(core, addr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (perms & RZ_PERM_W) {
|
if (perms & RZ_PERM_W) {
|
||||||
@ -621,6 +603,7 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rz_cons_flush();
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1390,7 +1373,7 @@ CutterJson CutterCore::getSignatureInfo()
|
|||||||
if (!signature) {
|
if (!signature) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return parseJson(signature, nullptr);
|
return parseJson("signature", signature, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CutterCore::existsFileInfo()
|
bool CutterCore::existsFileInfo()
|
||||||
@ -4333,6 +4316,7 @@ void CutterCore::loadScript(const QString &scriptname)
|
|||||||
{
|
{
|
||||||
CORE_LOCK();
|
CORE_LOCK();
|
||||||
rz_core_cmd_file(core, scriptname.toUtf8().constData());
|
rz_core_cmd_file(core, scriptname.toUtf8().constData());
|
||||||
|
rz_cons_flush();
|
||||||
}
|
}
|
||||||
triggerRefreshAll();
|
triggerRefreshAll();
|
||||||
}
|
}
|
||||||
|
@ -183,10 +183,10 @@ public:
|
|||||||
QString getRizinVersionReadable(const char *program = nullptr);
|
QString getRizinVersionReadable(const char *program = nullptr);
|
||||||
QString getVersionInformation();
|
QString getVersionInformation();
|
||||||
|
|
||||||
CutterJson parseJson(char *res, const char *cmd = nullptr);
|
CutterJson parseJson(const char *name, char *res, const char *cmd = nullptr);
|
||||||
CutterJson parseJson(char *res, const QString &cmd = QString())
|
CutterJson parseJson(const char *name, char *res, const QString &cmd = QString())
|
||||||
{
|
{
|
||||||
return parseJson(res, cmd.isNull() ? nullptr : cmd.toLocal8Bit().constData());
|
return parseJson(name, res, cmd.isNull() ? nullptr : cmd.toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList autocomplete(const QString &cmd, RzLinePromptType promptType, size_t limit = 4096);
|
QStringList autocomplete(const QString &cmd, RzLinePromptType promptType, size_t limit = 4096);
|
||||||
|
@ -520,7 +520,7 @@ void DisassemblyContextMenu::aboutToShowSlot()
|
|||||||
|
|
||||||
if (ab && ab->op) {
|
if (ab && ab->op) {
|
||||||
const char *opexstr = RZ_STRBUF_SAFEGET(&ab->op->opex);
|
const char *opexstr = RZ_STRBUF_SAFEGET(&ab->op->opex);
|
||||||
CutterJson operands = Core()->parseJson(strdup(opexstr), nullptr);
|
CutterJson operands = Core()->parseJson("opex", strdup(opexstr), nullptr);
|
||||||
|
|
||||||
// Loop through both the operands of the instruction
|
// Loop through both the operands of the instruction
|
||||||
for (const CutterJson operand : operands) {
|
for (const CutterJson operand : operands) {
|
||||||
|
@ -193,11 +193,11 @@ void GraphvizLayout::CalculateLayout(std::unordered_map<ut64, GraphBlock> &block
|
|||||||
if (it != edges.end()) {
|
if (it != edges.end()) {
|
||||||
auto e = it->second;
|
auto e = it->second;
|
||||||
if (auto spl = ED_spl(e)) {
|
if (auto spl = ED_spl(e)) {
|
||||||
for (int i = 0; i < 1 && i < spl->size; i++) {
|
for (size_t i = 0; i < 1 && i < spl->size; i++) {
|
||||||
auto bz = spl->list[i];
|
auto bz = spl->list[i];
|
||||||
edge.polyline.clear();
|
edge.polyline.clear();
|
||||||
edge.polyline.reserve(bz.size + 1);
|
edge.polyline.reserve(bz.size + 1);
|
||||||
for (int j = 0; j < bz.size; j++) {
|
for (size_t j = 0; j < bz.size; j++) {
|
||||||
edge.polyline.push_back(QPointF(bz.list[j].x, bz.list[j].y));
|
edge.polyline.push_back(QPointF(bz.list[j].x, bz.list[j].y));
|
||||||
}
|
}
|
||||||
QPointF last(0, 0);
|
QPointF last(0, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user