mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 10:56:11 +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);
|
||||
|
||||
if (JSDecDecompiler::isAvailable()) {
|
||||
Core()->registerDecompiler(new JSDecDecompiler(Core()));
|
||||
}
|
||||
|
||||
#if CUTTER_RZGHIDRA_STATIC
|
||||
Core()->registerDecompiler(new RzGhidraDecompiler(Core()));
|
||||
#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)
|
||||
{
|
||||
std::string temporary = warningMessage.toStdString();
|
||||
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);
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -62,7 +62,7 @@ CutterJson RizinCmdTask::getResultJson()
|
||||
}
|
||||
char *copy = static_cast<char *>(rz_mem_alloc(strlen(res) + 1));
|
||||
strcpy(copy, res);
|
||||
return Core()->parseJson(copy, nullptr);
|
||||
return Core()->parseJson("task", copy, nullptr);
|
||||
}
|
||||
|
||||
const char *RizinCmdTask::getResultRaw()
|
||||
|
@ -273,6 +273,7 @@ void CutterCore::loadCutterRC()
|
||||
}
|
||||
qInfo() << tr("Loading initialization file from ") << cutterRCFilePath;
|
||||
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;
|
||||
rz_core_cmd_file(core, cutterRCFilePath.toUtf8().constData());
|
||||
rz_cons_flush();
|
||||
}
|
||||
|
||||
QList<QString> CutterCore::sdbList(QString path)
|
||||
@ -473,19 +475,7 @@ QString CutterCore::cmdRaw(const char *cmd)
|
||||
{
|
||||
QString res;
|
||||
CORE_LOCK();
|
||||
rz_cons_push();
|
||||
|
||||
// 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;
|
||||
return rz_core_cmd_str(core, cmd);
|
||||
}
|
||||
|
||||
CutterJson CutterCore::cmdj(const char *str)
|
||||
@ -496,7 +486,7 @@ CutterJson CutterCore::cmdj(const char *str)
|
||||
res = rz_core_cmd_str(core, str);
|
||||
}
|
||||
|
||||
return parseJson(res, str);
|
||||
return parseJson("cmdj", res, str);
|
||||
}
|
||||
|
||||
QString CutterCore::cmdTask(const QString &str)
|
||||
@ -507,9 +497,9 @@ QString CutterCore::cmdTask(const QString &str)
|
||||
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();
|
||||
}
|
||||
|
||||
@ -517,18 +507,11 @@ CutterJson CutterCore::parseJson(char *res, const char *cmd)
|
||||
|
||||
if (!doc) {
|
||||
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 {
|
||||
eprintf("Failed to parse JSON\n");
|
||||
}
|
||||
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: Failed to parse JSON %s\n", name, res);
|
||||
}
|
||||
RZ_LOG_ERROR("%s: %s\n", name, 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);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// Not loading RzBin info coz va = false
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
@ -621,6 +603,7 @@ bool CutterCore::loadFile(QString path, ut64 baddr, ut64 mapaddr, int perms, int
|
||||
}
|
||||
}
|
||||
|
||||
rz_cons_flush();
|
||||
fflush(stdout);
|
||||
return true;
|
||||
}
|
||||
@ -1390,7 +1373,7 @@ CutterJson CutterCore::getSignatureInfo()
|
||||
if (!signature) {
|
||||
return {};
|
||||
}
|
||||
return parseJson(signature, nullptr);
|
||||
return parseJson("signature", signature, nullptr);
|
||||
}
|
||||
|
||||
bool CutterCore::existsFileInfo()
|
||||
@ -4333,6 +4316,7 @@ void CutterCore::loadScript(const QString &scriptname)
|
||||
{
|
||||
CORE_LOCK();
|
||||
rz_core_cmd_file(core, scriptname.toUtf8().constData());
|
||||
rz_cons_flush();
|
||||
}
|
||||
triggerRefreshAll();
|
||||
}
|
||||
|
@ -183,10 +183,10 @@ public:
|
||||
QString getRizinVersionReadable(const char *program = nullptr);
|
||||
QString getVersionInformation();
|
||||
|
||||
CutterJson parseJson(char *res, const char *cmd = nullptr);
|
||||
CutterJson parseJson(char *res, const QString &cmd = QString())
|
||||
CutterJson parseJson(const char *name, char *res, const char *cmd = nullptr);
|
||||
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);
|
||||
|
@ -520,7 +520,7 @@ void DisassemblyContextMenu::aboutToShowSlot()
|
||||
|
||||
if (ab && ab->op) {
|
||||
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
|
||||
for (const CutterJson operand : operands) {
|
||||
|
@ -193,11 +193,11 @@ void GraphvizLayout::CalculateLayout(std::unordered_map<ut64, GraphBlock> &block
|
||||
if (it != edges.end()) {
|
||||
auto e = it->second;
|
||||
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];
|
||||
edge.polyline.clear();
|
||||
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));
|
||||
}
|
||||
QPointF last(0, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user