mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-22 04:46:11 +00:00
Use rizin instead of Qt to parse JSON (#2902)
Qt truncates integers to 52-bit, corrupting e.g. memory addresses. Use rizin's JSON parser, which can parse integers whose size is up to 64 bits.
This commit is contained in:
parent
ddaa02c0f8
commit
518014ee19
@ -47,7 +47,7 @@ Example:
|
|||||||
|
|
||||||
.. code:: cpp
|
.. code:: cpp
|
||||||
|
|
||||||
QJsonArray array = Core()->cmdj("pdj 1 @ main").array();
|
CutterJson array = Core()->cmdj("pdj 1 @ main");
|
||||||
|
|
||||||
Seek the Current File
|
Seek the Current File
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -4,6 +4,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CutterConfig.h.in"
|
|||||||
set(SOURCES
|
set(SOURCES
|
||||||
Main.cpp
|
Main.cpp
|
||||||
core/Cutter.cpp
|
core/Cutter.cpp
|
||||||
|
core/CutterJson.cpp
|
||||||
dialogs/EditStringDialog.cpp
|
dialogs/EditStringDialog.cpp
|
||||||
dialogs/WriteCommandsDialogs.cpp
|
dialogs/WriteCommandsDialogs.cpp
|
||||||
widgets/DisassemblerGraphView.cpp
|
widgets/DisassemblerGraphView.cpp
|
||||||
@ -153,6 +154,7 @@ set(HEADER_FILES
|
|||||||
core/Cutter.h
|
core/Cutter.h
|
||||||
core/CutterCommon.h
|
core/CutterCommon.h
|
||||||
core/CutterDescriptions.h
|
core/CutterDescriptions.h
|
||||||
|
core/CutterJson.h
|
||||||
dialogs/EditStringDialog.h
|
dialogs/EditStringDialog.h
|
||||||
dialogs/WriteCommandsDialogs.h
|
dialogs/WriteCommandsDialogs.h
|
||||||
widgets/DisassemblerGraphView.h
|
widgets/DisassemblerGraphView.h
|
||||||
|
@ -12,13 +12,13 @@ void openIssue()
|
|||||||
// Pull in info needed for git issue
|
// Pull in info needed for git issue
|
||||||
osInfo = QSysInfo::productType() + " "
|
osInfo = QSysInfo::productType() + " "
|
||||||
+ (QSysInfo::productVersion() == "unknown" ? "" : QSysInfo::productVersion());
|
+ (QSysInfo::productVersion() == "unknown" ? "" : QSysInfo::productVersion());
|
||||||
QJsonDocument docu = Core()->getFileInfo();
|
CutterJson docu = Core()->getFileInfo();
|
||||||
QJsonObject coreObj = docu.object()["core"].toObject();
|
CutterJson coreObj = docu["core"];
|
||||||
QJsonObject binObj = docu.object()["bin"].toObject();
|
CutterJson binObj = docu["bin"];
|
||||||
if (!binObj.QJsonObject::isEmpty()) {
|
if (binObj.size()) {
|
||||||
format = coreObj["format"].toString();
|
format = coreObj["format"].toString();
|
||||||
arch = binObj["arch"].toString();
|
arch = binObj["arch"].toString();
|
||||||
if (!binObj["type"].isUndefined()) {
|
if (binObj["type"].valid()) {
|
||||||
type = coreObj["type"].toString();
|
type = coreObj["type"].toString();
|
||||||
} else {
|
} else {
|
||||||
type = "N/A";
|
type = "N/A";
|
||||||
|
@ -128,22 +128,34 @@ bool ColorThemeWorker::isThemeExist(const QString &name) const
|
|||||||
QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
|
QJsonDocument ColorThemeWorker::getTheme(const QString &themeName) const
|
||||||
{
|
{
|
||||||
int r, g, b, a;
|
int r, g, b, a;
|
||||||
|
CutterJson rzTheme;
|
||||||
QVariantMap theme;
|
QVariantMap theme;
|
||||||
QString curr = Config()->getColorTheme();
|
QString curr = Config()->getColorTheme();
|
||||||
|
|
||||||
if (themeName != curr) {
|
if (themeName != curr) {
|
||||||
RzCoreLocked core(Core());
|
RzCoreLocked core(Core());
|
||||||
rz_core_theme_load(core, themeName.toUtf8().constData());
|
rz_core_theme_load(core, themeName.toUtf8().constData());
|
||||||
theme = Core()->cmdj("ecj").object().toVariantMap();
|
rzTheme = Core()->cmdj("ecj");
|
||||||
rz_core_theme_load(core, curr.toUtf8().constData());
|
rz_core_theme_load(core, curr.toUtf8().constData());
|
||||||
} else {
|
} else {
|
||||||
theme = Core()->cmdj("ecj").object().toVariantMap();
|
rzTheme = Core()->cmdj("ecj");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = theme.begin(); it != theme.end(); it++) {
|
for (CutterJson value : rzTheme) {
|
||||||
auto arr = it.value().toList();
|
QJsonArray arr;
|
||||||
QColor(arr[0].toInt(), arr[1].toInt(), arr[2].toInt()).getRgb(&r, &g, &b, &a);
|
int count = 0;
|
||||||
theme[it.key()] = QJsonArray({ r, g, b, a });
|
for (CutterJson element : value) {
|
||||||
|
arr.append(element.toSt64());
|
||||||
|
count++;
|
||||||
|
if (count >= 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (count < 3) {
|
||||||
|
arr.append(0);
|
||||||
|
}
|
||||||
|
arr.append(255);
|
||||||
|
theme[value.key()] = arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorFlags colorFlags = ColorFlags::DarkFlag;
|
ColorFlags colorFlags = ColorFlags::DarkFlag;
|
||||||
@ -278,9 +290,8 @@ bool ColorThemeWorker::isFileTheme(const QString &filePath, bool *ok) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none";
|
const QString colors = "black|red|white|green|magenta|yellow|cyan|blue|gray|none";
|
||||||
QString options = (Core()->cmdj("ecj").object().keys() << cutterSpecificOptions)
|
QString options =
|
||||||
.join('|')
|
(Core()->cmdj("ecj").keys() << cutterSpecificOptions).join('|').replace(".", "\\.");
|
||||||
.replace(".", "\\.");
|
|
||||||
|
|
||||||
QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*")
|
QString pattern = QString("((ec\\s+(%1)\\s+(((rgb:|#)[0-9a-fA-F]{3,8})|(%2))))\\s*")
|
||||||
.arg(options)
|
.arg(options)
|
||||||
@ -315,7 +326,7 @@ QStringList ColorThemeWorker::customThemes() const
|
|||||||
const QStringList &ColorThemeWorker::getRizinSpecificOptions()
|
const QStringList &ColorThemeWorker::getRizinSpecificOptions()
|
||||||
{
|
{
|
||||||
if (rizinSpecificOptions.isEmpty()) {
|
if (rizinSpecificOptions.isEmpty()) {
|
||||||
rizinSpecificOptions = Core()->cmdj("ecj").object().keys();
|
rizinSpecificOptions = Core()->cmdj("ecj").keys();
|
||||||
}
|
}
|
||||||
return rizinSpecificOptions;
|
return rizinSpecificOptions;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include "Cutter.h"
|
#include "Cutter.h"
|
||||||
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
|
||||||
#define ThemeWorker() (ColorThemeWorker::instance())
|
#define ThemeWorker() (ColorThemeWorker::instance())
|
||||||
|
@ -33,40 +33,37 @@ void JSDecDecompiler::decompileAt(RVA addr)
|
|||||||
}
|
}
|
||||||
task = new RizinCmdTask("pddj @ " + QString::number(addr));
|
task = new RizinCmdTask("pddj @ " + QString::number(addr));
|
||||||
connect(task, &RizinCmdTask::finished, this, [this]() {
|
connect(task, &RizinCmdTask::finished, this, [this]() {
|
||||||
QJsonObject json = task->getResultJson().object();
|
CutterJson json = task->getResultJson();
|
||||||
delete task;
|
delete task;
|
||||||
task = nullptr;
|
task = nullptr;
|
||||||
if (json.isEmpty()) {
|
if (!json.size()) {
|
||||||
emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from jsdec")));
|
emit finished(Decompiler::makeWarning(tr("Failed to parse JSON from jsdec")));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RzAnnotatedCode *code = rz_annotated_code_new(nullptr);
|
RzAnnotatedCode *code = rz_annotated_code_new(nullptr);
|
||||||
QString codeString = "";
|
QString codeString = "";
|
||||||
for (const auto &line : json["log"].toArray()) {
|
for (auto line : json["log"]) {
|
||||||
if (!line.isString()) {
|
if (line.type() != RZ_JSON_STRING) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
codeString.append(line.toString() + "\n");
|
codeString.append(line.toString() + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto linesArray = json["lines"].toArray();
|
for (auto lineObject : json["lines"]) {
|
||||||
for (const auto &line : linesArray) {
|
if (!lineObject.size()) {
|
||||||
QJsonObject lineObject = line.toObject();
|
|
||||||
if (lineObject.isEmpty()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RzCodeAnnotation annotationi = {};
|
RzCodeAnnotation annotationi = {};
|
||||||
annotationi.start = codeString.length();
|
annotationi.start = codeString.length();
|
||||||
codeString.append(lineObject["str"].toString() + "\n");
|
codeString.append(lineObject["str"].toString() + "\n");
|
||||||
annotationi.end = codeString.length();
|
annotationi.end = codeString.length();
|
||||||
bool ok;
|
|
||||||
annotationi.type = RZ_CODE_ANNOTATION_TYPE_OFFSET;
|
annotationi.type = RZ_CODE_ANNOTATION_TYPE_OFFSET;
|
||||||
annotationi.offset.offset = lineObject["offset"].toVariant().toULongLong(&ok);
|
annotationi.offset.offset = lineObject["offset"].toUt64();
|
||||||
rz_annotated_code_add_annotation(code, &annotationi);
|
rz_annotated_code_add_annotation(code, &annotationi);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &line : json["errors"].toArray()) {
|
for (auto line : json["errors"]) {
|
||||||
if (!line.isString()) {
|
if (line.type() != RZ_JSON_STRING) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
codeString.append(line.toString() + "\n");
|
codeString.append(line.toString() + "\n");
|
||||||
|
@ -78,11 +78,10 @@ bool IOModesController::prepareForWriting()
|
|||||||
bool IOModesController::allChangesComitted()
|
bool IOModesController::allChangesComitted()
|
||||||
{
|
{
|
||||||
// Get a list of available write changes
|
// Get a list of available write changes
|
||||||
QJsonArray changes = Core()->cmdj("wcj").array();
|
CutterJson changes = Core()->cmdj("wcj");
|
||||||
|
|
||||||
// Check if there is a change which isn't written to the file
|
// Check if there is a change which isn't written to the file
|
||||||
for (const QJsonValue &value : changes) {
|
for (CutterJson changeObject : changes) {
|
||||||
QJsonObject changeObject = value.toObject();
|
|
||||||
if (!changeObject["written"].toBool()) {
|
if (!changeObject["written"].toBool()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -54,13 +54,15 @@ QString RizinCmdTask::getResult()
|
|||||||
return QString::fromUtf8(res);
|
return QString::fromUtf8(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonDocument RizinCmdTask::getResultJson()
|
CutterJson RizinCmdTask::getResultJson()
|
||||||
{
|
{
|
||||||
const char *res = rz_core_cmd_task_get_result(task);
|
const char *res = rz_core_cmd_task_get_result(task);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return QJsonDocument();
|
return CutterJson();
|
||||||
}
|
}
|
||||||
return Core()->parseJson(res, nullptr);
|
char *copy = static_cast<char *>(rz_mem_alloc(strlen(res) + 1));
|
||||||
|
strcpy(copy, res);
|
||||||
|
return Core()->parseJson(copy, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *RizinCmdTask::getResultRaw()
|
const char *RizinCmdTask::getResultRaw()
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
explicit RizinCmdTask(const QString &cmd, bool transient = true);
|
explicit RizinCmdTask(const QString &cmd, bool transient = true);
|
||||||
|
|
||||||
QString getResult();
|
QString getResult();
|
||||||
QJsonDocument getResultJson();
|
CutterJson getResultJson();
|
||||||
const char *getResultRaw();
|
const char *getResultRaw();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ void Cutter::initializeSettings()
|
|||||||
|
|
||||||
static void removeObsoleteOptionsFromCustomThemes()
|
static void removeObsoleteOptionsFromCustomThemes()
|
||||||
{
|
{
|
||||||
const QStringList options = Core()->cmdj("ecj").object().keys()
|
const QStringList options = Core()->cmdj("ecj").keys()
|
||||||
<< ColorThemeWorker::cutterSpecificOptions;
|
<< ColorThemeWorker::cutterSpecificOptions;
|
||||||
RzList *themes_list = rz_core_theme_list(Core()->core());
|
RzList *themes_list = rz_core_theme_list(Core()->core());
|
||||||
RzListIter *th_iter;
|
RzListIter *th_iter;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -3,15 +3,16 @@
|
|||||||
|
|
||||||
#include "core/CutterCommon.h"
|
#include "core/CutterCommon.h"
|
||||||
#include "core/CutterDescriptions.h"
|
#include "core/CutterDescriptions.h"
|
||||||
|
#include "core/CutterJson.h"
|
||||||
#include "common/BasicInstructionHighlighter.h"
|
#include "common/BasicInstructionHighlighter.h"
|
||||||
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QSharedPointer>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QErrorMessage>
|
#include <QErrorMessage>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@ -34,6 +35,29 @@ class RizinTaskDialog;
|
|||||||
|
|
||||||
class RzCoreLocked;
|
class RzCoreLocked;
|
||||||
|
|
||||||
|
struct CUTTER_EXPORT AddrRefs
|
||||||
|
{
|
||||||
|
RVA addr;
|
||||||
|
QString mapname;
|
||||||
|
QString section;
|
||||||
|
QString reg;
|
||||||
|
QString fcn;
|
||||||
|
QString type;
|
||||||
|
QString asm_op;
|
||||||
|
QString perms;
|
||||||
|
ut64 value;
|
||||||
|
bool has_value;
|
||||||
|
QString string;
|
||||||
|
QSharedPointer<AddrRefs> ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CUTTER_EXPORT RegisterRef
|
||||||
|
{
|
||||||
|
ut64 value;
|
||||||
|
AddrRefs ref;
|
||||||
|
QString name;
|
||||||
|
};
|
||||||
|
|
||||||
class CUTTER_EXPORT CutterCore : public QObject
|
class CUTTER_EXPORT CutterCore : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -124,16 +148,16 @@ public:
|
|||||||
seekSilent(oldOffset);
|
seekSilent(oldOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonDocument cmdj(const char *str);
|
CutterJson cmdj(const char *str);
|
||||||
QJsonDocument cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
|
CutterJson cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
|
||||||
QJsonDocument cmdjAt(const char *str, RVA address);
|
CutterJson cmdjAt(const char *str, RVA address);
|
||||||
QStringList cmdList(const char *str)
|
QStringList cmdList(const char *str)
|
||||||
{
|
{
|
||||||
return cmd(str).split(QLatin1Char('\n'), CUTTER_QT_SKIP_EMPTY_PARTS);
|
return cmd(str).split(QLatin1Char('\n'), CUTTER_QT_SKIP_EMPTY_PARTS);
|
||||||
}
|
}
|
||||||
QStringList cmdList(const QString &str) { return cmdList(str.toUtf8().constData()); }
|
QStringList cmdList(const QString &str) { return cmdList(str.toUtf8().constData()); }
|
||||||
QString cmdTask(const QString &str);
|
QString cmdTask(const QString &str);
|
||||||
QJsonDocument cmdjTask(const QString &str);
|
CutterJson cmdjTask(const QString &str);
|
||||||
/**
|
/**
|
||||||
* @brief send a command to Rizin and check for ESIL errors
|
* @brief send a command to Rizin and check for ESIL errors
|
||||||
* @param command the command you want to execute
|
* @param command the command you want to execute
|
||||||
@ -159,8 +183,8 @@ public:
|
|||||||
QString getRizinVersionReadable();
|
QString getRizinVersionReadable();
|
||||||
QString getVersionInformation();
|
QString getVersionInformation();
|
||||||
|
|
||||||
QJsonDocument parseJson(const char *res, const char *cmd = nullptr);
|
CutterJson parseJson(char *res, const char *cmd = nullptr);
|
||||||
QJsonDocument parseJson(const char *res, const QString &cmd = QString())
|
CutterJson parseJson(char *res, const QString &cmd = QString())
|
||||||
{
|
{
|
||||||
return parseJson(res, cmd.isNull() ? nullptr : cmd.toLocal8Bit().constData());
|
return parseJson(res, cmd.isNull() ? nullptr : cmd.toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
@ -376,8 +400,8 @@ public:
|
|||||||
bool sdbSet(QString path, QString key, QString val);
|
bool sdbSet(QString path, QString key, QString val);
|
||||||
|
|
||||||
/* Debug */
|
/* Debug */
|
||||||
QJsonDocument getRegistersInfo();
|
CutterJson getRegistersInfo();
|
||||||
QJsonDocument getRegisterValues();
|
CutterJson getRegisterValues();
|
||||||
QString getRegisterName(QString registerRole);
|
QString getRegisterName(QString registerRole);
|
||||||
RVA getProgramCounterValue();
|
RVA getProgramCounterValue();
|
||||||
void setRegister(QString regName, QString regValue);
|
void setRegister(QString regName, QString regValue);
|
||||||
@ -391,32 +415,32 @@ public:
|
|||||||
* @param size number of bytes to scan
|
* @param size number of bytes to scan
|
||||||
* @param depth telescoping depth
|
* @param depth telescoping depth
|
||||||
*/
|
*/
|
||||||
QList<QJsonObject> getStack(int size = 0x100, int depth = 6);
|
QList<AddrRefs> getStack(int size = 0x100, int depth = 6);
|
||||||
/**
|
/**
|
||||||
* @brief Recursively dereferences pointers starting at the specified address
|
* @brief Recursively dereferences pointers starting at the specified address
|
||||||
* up to a given depth
|
* up to a given depth
|
||||||
* @param addr telescoping addr
|
* @param addr telescoping addr
|
||||||
* @param depth telescoping depth
|
* @param depth telescoping depth
|
||||||
*/
|
*/
|
||||||
QJsonObject getAddrRefs(RVA addr, int depth);
|
AddrRefs getAddrRefs(RVA addr, int depth);
|
||||||
/**
|
/**
|
||||||
* @brief return a RefDescription with a formatted ref string and configured colors
|
* @brief return a RefDescription with a formatted ref string and configured colors
|
||||||
* @param ref the "ref" JSON node from getAddrRefs
|
* @param ref the "ref" JSON node from getAddrRefs
|
||||||
*/
|
*/
|
||||||
RefDescription formatRefDesc(QJsonObject ref);
|
RefDescription formatRefDesc(const AddrRefs &ref);
|
||||||
/**
|
/**
|
||||||
* @brief Get a list of a given process's threads
|
* @brief Get a list of a given process's threads
|
||||||
* @param pid The pid of the process, -1 for the currently debugged process
|
* @param pid The pid of the process, -1 for the currently debugged process
|
||||||
* @return JSON object result of dptj
|
* @return JSON object result of dptj
|
||||||
*/
|
*/
|
||||||
QJsonDocument getProcessThreads(int pid);
|
CutterJson getProcessThreads(int pid);
|
||||||
/**
|
/**
|
||||||
* @brief Get a list of a given process's child processes
|
* @brief Get a list of a given process's child processes
|
||||||
* @param pid The pid of the process, -1 for the currently debugged process
|
* @param pid The pid of the process, -1 for the currently debugged process
|
||||||
* @return JSON object result of dptj
|
* @return JSON object result of dptj
|
||||||
*/
|
*/
|
||||||
QJsonDocument getChildProcesses(int pid);
|
CutterJson getChildProcesses(int pid);
|
||||||
QJsonDocument getBacktrace();
|
CutterJson getBacktrace();
|
||||||
/**
|
/**
|
||||||
* @brief Get a list of heap chunks
|
* @brief Get a list of heap chunks
|
||||||
* Uses RZ_API rz_heap_chunks_list to get vector of chunks
|
* Uses RZ_API rz_heap_chunks_list to get vector of chunks
|
||||||
@ -532,9 +556,9 @@ public:
|
|||||||
bool registerDecompiler(Decompiler *decompiler);
|
bool registerDecompiler(Decompiler *decompiler);
|
||||||
|
|
||||||
RVA getOffsetJump(RVA addr);
|
RVA getOffsetJump(RVA addr);
|
||||||
QJsonDocument getFileInfo();
|
CutterJson getFileInfo();
|
||||||
QJsonDocument getSignatureInfo();
|
CutterJson getSignatureInfo();
|
||||||
QJsonDocument getFileVersionInfo();
|
CutterJson getFileVersionInfo();
|
||||||
QStringList getStats();
|
QStringList getStats();
|
||||||
void setGraphEmpty(bool empty);
|
void setGraphEmpty(bool empty);
|
||||||
bool isGraphEmpty();
|
bool isGraphEmpty();
|
||||||
@ -631,7 +655,7 @@ public:
|
|||||||
* @brief returns a list of reg values and their telescoped references
|
* @brief returns a list of reg values and their telescoped references
|
||||||
* @param depth telescoping depth
|
* @param depth telescoping depth
|
||||||
*/
|
*/
|
||||||
QList<QJsonObject> getRegisterRefs(int depth = 6);
|
QList<RegisterRef> getRegisterRefs(int depth = 6);
|
||||||
QVector<RegisterRefValueDescription> getRegisterRefValues();
|
QVector<RegisterRefValueDescription> getRegisterRefValues();
|
||||||
QList<VariableDescription> getVariables(RVA at);
|
QList<VariableDescription> getVariables(RVA at);
|
||||||
/**
|
/**
|
||||||
@ -649,7 +673,7 @@ 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());
|
const QString &filterType = QString());
|
||||||
|
|
||||||
QList<StringDescription> parseStringsJson(const QJsonDocument &doc);
|
QList<StringDescription> parseStringsJson(const CutterJson &doc);
|
||||||
|
|
||||||
void handleREvent(int type, void *data);
|
void handleREvent(int type, void *data);
|
||||||
|
|
||||||
|
28
src/core/CutterJson.cpp
Normal file
28
src/core/CutterJson.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "core/CutterJson.h"
|
||||||
|
|
||||||
|
CutterJson CutterJson::last() const
|
||||||
|
{
|
||||||
|
if (!has_children()) {
|
||||||
|
return CutterJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
const RzJson *last = value->children.first;
|
||||||
|
while (last->next) {
|
||||||
|
last = last->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CutterJson(last, owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList CutterJson::keys() const
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
|
||||||
|
if (value && value->type == RZ_JSON_OBJECT) {
|
||||||
|
for (const RzJson *child = value->children.first; child; child = child->next) {
|
||||||
|
list.append(child->key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
119
src/core/CutterJson.h
Normal file
119
src/core/CutterJson.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#ifndef CUTTER_JSON_H
|
||||||
|
#define CUTTER_JSON_H
|
||||||
|
|
||||||
|
#include "core/CutterCommon.h"
|
||||||
|
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <rz_project.h>
|
||||||
|
|
||||||
|
class CutterJsonOwner;
|
||||||
|
|
||||||
|
class CUTTER_EXPORT CutterJson
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
iterator(const RzJson *value, QSharedPointer<CutterJsonOwner> owner)
|
||||||
|
: value(value), owner(owner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CutterJson operator*() const { return CutterJson(value, owner); }
|
||||||
|
|
||||||
|
bool operator!=(const iterator &other) const { return value != other.value; }
|
||||||
|
|
||||||
|
iterator &operator++()
|
||||||
|
{
|
||||||
|
value = value->next;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const RzJson *value;
|
||||||
|
QSharedPointer<CutterJsonOwner> owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
CutterJson() : value(nullptr), owner(nullptr) {}
|
||||||
|
|
||||||
|
CutterJson(const RzJson *value, QSharedPointer<CutterJsonOwner> owner)
|
||||||
|
: value(value), owner(owner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CutterJson first() const
|
||||||
|
{
|
||||||
|
return CutterJson(has_children() ? value->children.first : nullptr, owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
CutterJson last() const;
|
||||||
|
|
||||||
|
CutterJson operator[](const QString &key) const
|
||||||
|
{
|
||||||
|
QByteArray utf8 = key.toUtf8();
|
||||||
|
return (*this)[utf8.data()];
|
||||||
|
}
|
||||||
|
|
||||||
|
CutterJson operator[](const char *key) const
|
||||||
|
{
|
||||||
|
return CutterJson(
|
||||||
|
value && value->type == RZ_JSON_OBJECT ? rz_json_get(value, key) : nullptr, owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator begin() const
|
||||||
|
{
|
||||||
|
return iterator(has_children() ? value->children.first : nullptr, owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() const { return iterator(nullptr, nullptr); }
|
||||||
|
|
||||||
|
bool toBool() const { return value && value->type == RZ_JSON_BOOLEAN && value->num.u_value; }
|
||||||
|
QString toJson() const { return rz_json_as_string(value); }
|
||||||
|
st64 toSt64() const { return value && value->type == RZ_JSON_INTEGER ? value->num.s_value : 0; }
|
||||||
|
ut64 toUt64() const { return value && value->type == RZ_JSON_INTEGER ? value->num.u_value : 0; }
|
||||||
|
|
||||||
|
RVA toRVA() const
|
||||||
|
{
|
||||||
|
return value && value->type == RZ_JSON_INTEGER ? value->num.u_value : RVA_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString toString() const
|
||||||
|
{
|
||||||
|
return value && value->type == RZ_JSON_STRING ? QString(value->str_value) : QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString key() const { return value ? value->key : QString(); }
|
||||||
|
QStringList keys() const;
|
||||||
|
size_t size() const { return has_children() ? value->children.count : 0; }
|
||||||
|
RzJsonType type() const { return value ? value->type : RZ_JSON_NULL; }
|
||||||
|
bool valid() const { return value ? true : false; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool has_children() const
|
||||||
|
{
|
||||||
|
return value && (value->type == RZ_JSON_OBJECT || value->type == RZ_JSON_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RzJson *value;
|
||||||
|
QSharedPointer<CutterJsonOwner> owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CUTTER_EXPORT CutterJsonOwner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CutterJsonOwner(RzJson *value, char *text) : value(value), text(text) {}
|
||||||
|
|
||||||
|
virtual ~CutterJsonOwner()
|
||||||
|
{
|
||||||
|
rz_json_free(value);
|
||||||
|
rz_mem_free(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
RzJson *value;
|
||||||
|
char *text;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CUTTER_JSON_H
|
@ -24,12 +24,12 @@ VersionInfoDialog::~VersionInfoDialog() {}
|
|||||||
void VersionInfoDialog::fillVersionInfo()
|
void VersionInfoDialog::fillVersionInfo()
|
||||||
{
|
{
|
||||||
|
|
||||||
QJsonDocument doc = Core()->getFileVersionInfo();
|
CutterJson doc = Core()->getFileVersionInfo();
|
||||||
|
|
||||||
// Case ELF
|
// Case ELF
|
||||||
if (doc.object().contains("verneed")) {
|
if (doc["verneed"].valid()) {
|
||||||
QJsonObject verneed = doc.object()["verneed"].toArray().first().toObject();
|
CutterJson verneed = doc["verneed"].first();
|
||||||
QJsonObject versym = doc.object()["versym"].toArray().first().toObject();
|
CutterJson versym = doc["versym"].first();
|
||||||
|
|
||||||
// Set labels
|
// Set labels
|
||||||
ui->leftLabel->setText("Version symbols");
|
ui->leftLabel->setText("Version symbols");
|
||||||
@ -43,17 +43,17 @@ void VersionInfoDialog::fillVersionInfo()
|
|||||||
|
|
||||||
QTreeWidgetItem *addrItemL = new QTreeWidgetItem();
|
QTreeWidgetItem *addrItemL = new QTreeWidgetItem();
|
||||||
addrItemL->setText(0, "Address:");
|
addrItemL->setText(0, "Address:");
|
||||||
addrItemL->setText(1, RzAddressString(versym["address"].toDouble()));
|
addrItemL->setText(1, RzAddressString(versym["address"].toRVA()));
|
||||||
ui->leftTreeWidget->addTopLevelItem(addrItemL);
|
ui->leftTreeWidget->addTopLevelItem(addrItemL);
|
||||||
|
|
||||||
QTreeWidgetItem *offItemL = new QTreeWidgetItem();
|
QTreeWidgetItem *offItemL = new QTreeWidgetItem();
|
||||||
offItemL->setText(0, "Offset:");
|
offItemL->setText(0, "Offset:");
|
||||||
offItemL->setText(1, RzAddressString(versym["offset"].toDouble()));
|
offItemL->setText(1, RzAddressString(versym["offset"].toRVA()));
|
||||||
ui->leftTreeWidget->addTopLevelItem(offItemL);
|
ui->leftTreeWidget->addTopLevelItem(offItemL);
|
||||||
|
|
||||||
QTreeWidgetItem *linkItemL = new QTreeWidgetItem();
|
QTreeWidgetItem *linkItemL = new QTreeWidgetItem();
|
||||||
linkItemL->setText(0, "Link:");
|
linkItemL->setText(0, "Link:");
|
||||||
linkItemL->setText(1, QString::number(versym["link"].toDouble()));
|
linkItemL->setText(1, QString::number(versym["link"].toRVA()));
|
||||||
ui->leftTreeWidget->addTopLevelItem(linkItemL);
|
ui->leftTreeWidget->addTopLevelItem(linkItemL);
|
||||||
|
|
||||||
QTreeWidgetItem *linkNameItemL = new QTreeWidgetItem();
|
QTreeWidgetItem *linkNameItemL = new QTreeWidgetItem();
|
||||||
@ -63,10 +63,9 @@ void VersionInfoDialog::fillVersionInfo()
|
|||||||
|
|
||||||
QTreeWidgetItem *entriesItemL = new QTreeWidgetItem();
|
QTreeWidgetItem *entriesItemL = new QTreeWidgetItem();
|
||||||
entriesItemL->setText(0, "Entries:");
|
entriesItemL->setText(0, "Entries:");
|
||||||
for (QJsonValue val : versym["entries"].toArray()) {
|
for (CutterJson obj : versym["entries"]) {
|
||||||
QJsonObject obj = val.toObject();
|
|
||||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
||||||
tempItem->setText(0, RzAddressString(obj["idx"].toDouble()));
|
tempItem->setText(0, RzAddressString(obj["idx"].toRVA()));
|
||||||
tempItem->setText(1, obj["value"].toString());
|
tempItem->setText(1, obj["value"].toString());
|
||||||
entriesItemL->addChild(tempItem);
|
entriesItemL->addChild(tempItem);
|
||||||
}
|
}
|
||||||
@ -83,17 +82,17 @@ void VersionInfoDialog::fillVersionInfo()
|
|||||||
|
|
||||||
QTreeWidgetItem *addrItemR = new QTreeWidgetItem();
|
QTreeWidgetItem *addrItemR = new QTreeWidgetItem();
|
||||||
addrItemR->setText(0, "Address:");
|
addrItemR->setText(0, "Address:");
|
||||||
addrItemR->setText(1, RzAddressString(verneed["address"].toDouble()));
|
addrItemR->setText(1, RzAddressString(verneed["address"].toRVA()));
|
||||||
ui->rightTreeWidget->addTopLevelItem(addrItemR);
|
ui->rightTreeWidget->addTopLevelItem(addrItemR);
|
||||||
|
|
||||||
QTreeWidgetItem *offItemR = new QTreeWidgetItem();
|
QTreeWidgetItem *offItemR = new QTreeWidgetItem();
|
||||||
offItemR->setText(0, "Offset:");
|
offItemR->setText(0, "Offset:");
|
||||||
offItemR->setText(1, RzAddressString(verneed["offset"].toDouble()));
|
offItemR->setText(1, RzAddressString(verneed["offset"].toRVA()));
|
||||||
ui->rightTreeWidget->addTopLevelItem(offItemR);
|
ui->rightTreeWidget->addTopLevelItem(offItemR);
|
||||||
|
|
||||||
QTreeWidgetItem *linkItemR = new QTreeWidgetItem();
|
QTreeWidgetItem *linkItemR = new QTreeWidgetItem();
|
||||||
linkItemR->setText(0, "Link:");
|
linkItemR->setText(0, "Link:");
|
||||||
linkItemR->setText(1, QString::number(verneed["link"].toDouble()));
|
linkItemR->setText(1, QString::number(verneed["link"].toSt64()));
|
||||||
ui->rightTreeWidget->addTopLevelItem(linkItemR);
|
ui->rightTreeWidget->addTopLevelItem(linkItemR);
|
||||||
|
|
||||||
QTreeWidgetItem *linkNameItemR = new QTreeWidgetItem();
|
QTreeWidgetItem *linkNameItemR = new QTreeWidgetItem();
|
||||||
@ -103,24 +102,22 @@ void VersionInfoDialog::fillVersionInfo()
|
|||||||
|
|
||||||
QTreeWidgetItem *entriesItemR = new QTreeWidgetItem();
|
QTreeWidgetItem *entriesItemR = new QTreeWidgetItem();
|
||||||
entriesItemR->setText(0, "Entries:");
|
entriesItemR->setText(0, "Entries:");
|
||||||
for (QJsonValue parentVal : verneed["entries"].toArray()) {
|
for (CutterJson parentObj : verneed["entries"]) {
|
||||||
QJsonObject parentObj = parentVal.toObject();
|
|
||||||
QTreeWidgetItem *parentItem = new QTreeWidgetItem();
|
QTreeWidgetItem *parentItem = new QTreeWidgetItem();
|
||||||
QString parentString;
|
QString parentString;
|
||||||
parentItem->setText(0, RzAddressString(parentObj["idx"].toDouble()));
|
parentItem->setText(0, RzAddressString(parentObj["idx"].toRVA()));
|
||||||
parentString.append("Version: " + QString::number(parentObj["vn_version"].toDouble())
|
parentString.append("Version: " + QString::number(parentObj["vn_version"].toSt64())
|
||||||
+ "\t");
|
+ "\t");
|
||||||
parentString.append("File: " + parentObj["file_name"].toString());
|
parentString.append("File: " + parentObj["file_name"].toString());
|
||||||
parentItem->setText(1, parentString);
|
parentItem->setText(1, parentString);
|
||||||
|
|
||||||
for (QJsonValue childVal : parentObj["vernaux"].toArray()) {
|
for (CutterJson childObj : parentObj["vernaux"]) {
|
||||||
QJsonObject childObj = childVal.toObject();
|
|
||||||
QTreeWidgetItem *childItem = new QTreeWidgetItem();
|
QTreeWidgetItem *childItem = new QTreeWidgetItem();
|
||||||
QString childString;
|
QString childString;
|
||||||
childItem->setText(0, RzAddressString(childObj["idx"].toDouble()));
|
childItem->setText(0, RzAddressString(childObj["idx"].toRVA()));
|
||||||
childString.append("Name: " + childObj["name"].toString() + "\t");
|
childString.append("Name: " + childObj["name"].toString() + "\t");
|
||||||
childString.append("Flags: " + childObj["flags"].toString() + "\t");
|
childString.append("Flags: " + childObj["flags"].toString() + "\t");
|
||||||
childString.append("Version: " + QString::number(childObj["version"].toDouble()));
|
childString.append("Version: " + QString::number(childObj["version"].toSt64()));
|
||||||
childItem->setText(1, childString);
|
childItem->setText(1, childString);
|
||||||
parentItem->addChild(childItem);
|
parentItem->addChild(childItem);
|
||||||
}
|
}
|
||||||
@ -134,22 +131,22 @@ void VersionInfoDialog::fillVersionInfo()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Case PE
|
// Case PE
|
||||||
else if (doc.object().contains("VS_FIXEDFILEINFO")) {
|
else if (doc["VS_FIXEDFILEINFO"].valid()) {
|
||||||
QJsonObject vs = doc.object()["VS_FIXEDFILEINFO"].toObject();
|
CutterJson vs = doc["VS_FIXEDFILEINFO"];
|
||||||
QJsonObject strings = doc.object()["StringTable"].toObject();
|
CutterJson strings = doc["StringTable"];
|
||||||
|
|
||||||
// Set labels
|
// Set labels
|
||||||
ui->leftLabel->setText("VS Fixed file info");
|
ui->leftLabel->setText("VS Fixed file info");
|
||||||
ui->rightLabel->setText("String table");
|
ui->rightLabel->setText("String table");
|
||||||
|
|
||||||
// Left tree
|
// Left tree
|
||||||
for (QString key : vs.keys()) {
|
for (CutterJson property : vs) {
|
||||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
||||||
tempItem->setText(0, key);
|
tempItem->setText(0, property.key());
|
||||||
if (vs[key].isDouble())
|
if (property.type() == RZ_JSON_INTEGER)
|
||||||
tempItem->setText(1, RzHexString(vs[key].toDouble()));
|
tempItem->setText(1, RzHexString(property.toRVA()));
|
||||||
else
|
else
|
||||||
tempItem->setText(1, vs[key].toString());
|
tempItem->setText(1, property.toString());
|
||||||
ui->leftTreeWidget->addTopLevelItem(tempItem);
|
ui->leftTreeWidget->addTopLevelItem(tempItem);
|
||||||
|
|
||||||
// Adjust columns to content
|
// Adjust columns to content
|
||||||
@ -157,10 +154,10 @@ void VersionInfoDialog::fillVersionInfo()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Right tree
|
// Right tree
|
||||||
for (QString key : strings.keys()) {
|
for (CutterJson property : strings) {
|
||||||
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
|
||||||
tempItem->setText(0, key);
|
tempItem->setText(0, property.key());
|
||||||
tempItem->setText(1, strings[key].toString());
|
tempItem->setText(1, property.toString());
|
||||||
ui->rightTreeWidget->addTopLevelItem(tempItem);
|
ui->rightTreeWidget->addTopLevelItem(tempItem);
|
||||||
|
|
||||||
// Adjust columns to content
|
// Adjust columns to content
|
||||||
|
@ -314,15 +314,15 @@ void DisassemblyContextMenu::addDebugMenu()
|
|||||||
QVector<DisassemblyContextMenu::ThingUsedHere> DisassemblyContextMenu::getThingUsedHere(RVA offset)
|
QVector<DisassemblyContextMenu::ThingUsedHere> DisassemblyContextMenu::getThingUsedHere(RVA offset)
|
||||||
{
|
{
|
||||||
QVector<ThingUsedHere> result;
|
QVector<ThingUsedHere> result;
|
||||||
const QJsonArray array = Core()->cmdj("anj @ " + QString::number(offset)).array();
|
const CutterJson array = Core()->cmdj("anj @ " + QString::number(offset));
|
||||||
result.reserve(array.size());
|
result.reserve(array.size());
|
||||||
for (const auto &thing : array) {
|
for (const auto &thing : array) {
|
||||||
auto obj = thing.toObject();
|
auto obj = thing;
|
||||||
RVA offset = obj["offset"].toVariant().toULongLong();
|
RVA offset = obj["offset"].toRVA();
|
||||||
QString name;
|
QString name;
|
||||||
|
|
||||||
// If real names display is enabled, show flag's real name instead of full flag name
|
// If real names display is enabled, show flag's real name instead of full flag name
|
||||||
if (Config()->getConfigBool("asm.flags.real") && obj.contains("realname")) {
|
if (Config()->getConfigBool("asm.flags.real") && obj["realname"].valid()) {
|
||||||
name = obj["realname"].toString();
|
name = obj["realname"].toString();
|
||||||
} else {
|
} else {
|
||||||
name = obj["name"].toString();
|
name = obj["name"].toString();
|
||||||
@ -482,31 +482,26 @@ void DisassemblyContextMenu::setupRenaming()
|
|||||||
void DisassemblyContextMenu::aboutToShowSlot()
|
void DisassemblyContextMenu::aboutToShowSlot()
|
||||||
{
|
{
|
||||||
// check if set immediate base menu makes sense
|
// check if set immediate base menu makes sense
|
||||||
QJsonObject instObject =
|
CutterJson instObject = Core()->cmdj("aoj @ " + QString::number(offset)).first();
|
||||||
Core()->cmdj("aoj @ " + QString::number(offset)).array().first().toObject();
|
bool immBase = instObject["val"].valid() || instObject["ptr"].valid();
|
||||||
auto keys = instObject.keys();
|
|
||||||
bool immBase = keys.contains("val") || keys.contains("ptr");
|
|
||||||
setBaseMenu->menuAction()->setVisible(immBase);
|
setBaseMenu->menuAction()->setVisible(immBase);
|
||||||
setBitsMenu->menuAction()->setVisible(true);
|
setBitsMenu->menuAction()->setVisible(true);
|
||||||
|
|
||||||
// Create structure offset menu if it makes sense
|
// Create structure offset menu if it makes sense
|
||||||
QString memBaseReg; // Base register
|
QString memBaseReg; // Base register
|
||||||
QVariant memDisp; // Displacement
|
st64 memDisp; // Displacement
|
||||||
if (instObject.contains("opex") && instObject["opex"].toObject().contains("operands")) {
|
|
||||||
// Loop through both the operands of the instruction
|
// Loop through both the operands of the instruction
|
||||||
for (const QJsonValue value : instObject["opex"].toObject()["operands"].toArray()) {
|
for (const CutterJson operand : instObject["opex"]["operands"]) {
|
||||||
QJsonObject operand = value.toObject();
|
if (operand["type"].toString() == "mem" && !operand["base"].toString().contains("bp")
|
||||||
if (operand.contains("type") && operand["type"].toString() == "mem"
|
&& operand["disp"].toSt64() > 0) {
|
||||||
&& operand.contains("base") && !operand["base"].toString().contains("bp")
|
|
||||||
&& operand.contains("disp") && operand["disp"].toVariant().toLongLong() > 0) {
|
|
||||||
|
|
||||||
// The current operand is the one which has an immediate displacement
|
// The current operand is the one which has an immediate displacement
|
||||||
memBaseReg = operand["base"].toString();
|
memBaseReg = operand["base"].toString();
|
||||||
memDisp = operand["disp"].toVariant();
|
memDisp = operand["disp"].toSt64();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (memBaseReg.isEmpty()) {
|
if (memBaseReg.isEmpty()) {
|
||||||
// hide structure offset menu
|
// hide structure offset menu
|
||||||
structureOffsetMenu->menuAction()->setVisible(false);
|
structureOffsetMenu->menuAction()->setVisible(false);
|
||||||
@ -517,7 +512,7 @@ void DisassemblyContextMenu::aboutToShowSlot()
|
|||||||
|
|
||||||
// Get the possible offsets using the "ahts" command
|
// Get the possible offsets using the "ahts" command
|
||||||
// TODO: add ahtj command to Rizin and then use it here
|
// TODO: add ahtj command to Rizin and then use it here
|
||||||
QStringList ret = Core()->cmdList("ahts " + memDisp.toString());
|
QStringList ret = Core()->cmdList("ahts " + QString::number(memDisp));
|
||||||
for (const QString &val : ret) {
|
for (const QString &val : ret) {
|
||||||
if (val.isEmpty()) {
|
if (val.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
@ -714,12 +709,12 @@ void DisassemblyContextMenu::showReverseJmpQuery()
|
|||||||
{
|
{
|
||||||
QString type;
|
QString type;
|
||||||
|
|
||||||
QJsonArray array = Core()->cmdj("pdj 1 @ " + RzAddressString(offset)).array();
|
CutterJson array = Core()->cmdj("pdj 1 @ " + RzAddressString(offset));
|
||||||
if (array.isEmpty()) {
|
if (!array.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = array.first().toObject()["type"].toString();
|
type = array.first()["type"].toString();
|
||||||
if (type == "cjmp") {
|
if (type == "cjmp") {
|
||||||
actionJmpReverse.setVisible(true);
|
actionJmpReverse.setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,13 +44,11 @@ void BacktraceWidget::updateContents()
|
|||||||
|
|
||||||
void BacktraceWidget::setBacktraceGrid()
|
void BacktraceWidget::setBacktraceGrid()
|
||||||
{
|
{
|
||||||
QJsonArray backtraceValues = Core()->getBacktrace().array();
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const QJsonValue &value : backtraceValues) {
|
for (CutterJson backtraceItem : Core()->getBacktrace()) {
|
||||||
QJsonObject backtraceItem = value.toObject();
|
QString progCounter = RzAddressString(backtraceItem["pc"].toRVA());
|
||||||
QString progCounter = RzAddressString(backtraceItem["pc"].toVariant().toULongLong());
|
QString stackPointer = RzAddressString(backtraceItem["sp"].toRVA());
|
||||||
QString stackPointer = RzAddressString(backtraceItem["sp"].toVariant().toULongLong());
|
st64 frameSize = backtraceItem["frame_size"].toSt64();
|
||||||
int frameSize = backtraceItem["frame_size"].toVariant().toInt();
|
|
||||||
QString funcName = backtraceItem["fname"].toString();
|
QString funcName = backtraceItem["fname"].toString();
|
||||||
QString desc = backtraceItem["desc"].toString();
|
QString desc = backtraceItem["desc"].toString();
|
||||||
|
|
||||||
|
@ -77,8 +77,7 @@ void CallGraphView::loadCurrentGraph()
|
|||||||
blockContent.clear();
|
blockContent.clear();
|
||||||
blocks.clear();
|
blocks.clear();
|
||||||
|
|
||||||
QJsonDocument functionsDoc = Core()->cmdj(global ? "agCj" : QString("agcj @ %1").arg(address));
|
CutterJson nodes = Core()->cmdj(global ? "agCj" : QString("agcj @ %1").arg(address));
|
||||||
auto nodes = functionsDoc.array();
|
|
||||||
|
|
||||||
QHash<QString, uint64_t> idMapping;
|
QHash<QString, uint64_t> idMapping;
|
||||||
|
|
||||||
@ -91,11 +90,10 @@ void CallGraphView::loadCurrentGraph()
|
|||||||
return itemId;
|
return itemId;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const QJsonValueRef &value : nodes) {
|
for (CutterJson block : nodes) {
|
||||||
QJsonObject block = value.toObject();
|
QString name = block["name"].toString();
|
||||||
QString name = block["name"].toVariant().toString();
|
|
||||||
|
|
||||||
auto edges = block["imports"].toArray();
|
auto edges = block["imports"];
|
||||||
GraphLayout::GraphBlock layoutBlock;
|
GraphLayout::GraphBlock layoutBlock;
|
||||||
layoutBlock.entry = getId(name);
|
layoutBlock.entry = getId(name);
|
||||||
for (auto edge : edges) {
|
for (auto edge : edges) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QListView>
|
#include <QListView>
|
||||||
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
|
@ -32,16 +32,16 @@ Dashboard::~Dashboard() {}
|
|||||||
|
|
||||||
void Dashboard::updateContents()
|
void Dashboard::updateContents()
|
||||||
{
|
{
|
||||||
QJsonDocument docu = Core()->getFileInfo();
|
CutterJson docu = Core()->getFileInfo();
|
||||||
QJsonObject item = docu.object()["core"].toObject();
|
CutterJson item = docu["core"];
|
||||||
QJsonObject item2 = docu.object()["bin"].toObject();
|
CutterJson item2 = docu["bin"];
|
||||||
|
|
||||||
setPlainText(this->ui->fileEdit, item["file"].toString());
|
setPlainText(this->ui->fileEdit, item["file"].toString());
|
||||||
setPlainText(this->ui->formatEdit, item["format"].toString());
|
setPlainText(this->ui->formatEdit, item["format"].toString());
|
||||||
setPlainText(this->ui->modeEdit, item["mode"].toString());
|
setPlainText(this->ui->modeEdit, item["mode"].toString());
|
||||||
setPlainText(this->ui->typeEdit, item["type"].toString());
|
setPlainText(this->ui->typeEdit, item["type"].toString());
|
||||||
setPlainText(this->ui->sizeEdit, qhelpers::formatBytecount(item["size"].toDouble()));
|
setPlainText(this->ui->sizeEdit, qhelpers::formatBytecount(item["size"].toUt64()));
|
||||||
setPlainText(this->ui->fdEdit, QString::number(item["fd"].toDouble()));
|
setPlainText(this->ui->fdEdit, QString::number(item["fd"].toUt64()));
|
||||||
|
|
||||||
setPlainText(this->ui->archEdit, item2["arch"].toString());
|
setPlainText(this->ui->archEdit, item2["arch"].toString());
|
||||||
setPlainText(this->ui->langEdit, item2["lang"].toString().toUpper());
|
setPlainText(this->ui->langEdit, item2["lang"].toString().toUpper());
|
||||||
@ -52,7 +52,7 @@ void Dashboard::updateContents()
|
|||||||
setPlainText(this->ui->endianEdit, item2["endian"].toString());
|
setPlainText(this->ui->endianEdit, item2["endian"].toString());
|
||||||
setPlainText(this->ui->compilationDateEdit, item2["compiled"].toString());
|
setPlainText(this->ui->compilationDateEdit, item2["compiled"].toString());
|
||||||
setPlainText(this->ui->compilerEdit, item2["compiler"].toString());
|
setPlainText(this->ui->compilerEdit, item2["compiler"].toString());
|
||||||
setPlainText(this->ui->bitsEdit, QString::number(item2["bits"].toDouble()));
|
setPlainText(this->ui->bitsEdit, QString::number(item2["bits"].toUt64()));
|
||||||
|
|
||||||
if (!item2["relro"].toString().isEmpty()) {
|
if (!item2["relro"].toString().isEmpty()) {
|
||||||
QString relro = item2["relro"].toString().section(QLatin1Char(' '), 0, 0);
|
QString relro = item2["relro"].toString().section(QLatin1Char(' '), 0, 0);
|
||||||
@ -62,7 +62,7 @@ void Dashboard::updateContents()
|
|||||||
setPlainText(this->ui->relroEdit, "N/A");
|
setPlainText(this->ui->relroEdit, "N/A");
|
||||||
}
|
}
|
||||||
|
|
||||||
setPlainText(this->ui->baddrEdit, RzAddressString(item2["baddr"].toVariant().toULongLong()));
|
setPlainText(this->ui->baddrEdit, RzAddressString(item2["baddr"].toRVA()));
|
||||||
|
|
||||||
// set booleans
|
// set booleans
|
||||||
setBool(this->ui->vaEdit, item2, "va");
|
setBool(this->ui->vaEdit, item2, "va");
|
||||||
@ -110,16 +110,16 @@ void Dashboard::updateContents()
|
|||||||
hashesLayout->addRow(new QLabel(label), hashLineEdit);
|
hashesLayout->addRow(new QLabel(label), hashLineEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject analinfo = Core()->cmdj("aaij").object();
|
CutterJson analinfo = Core()->cmdj("aaij");
|
||||||
setPlainText(ui->functionsLineEdit, QString::number(analinfo["fcns"].toInt()));
|
setPlainText(ui->functionsLineEdit, QString::number(analinfo["fcns"].toSt64()));
|
||||||
setPlainText(ui->xRefsLineEdit, QString::number(analinfo["xrefs"].toInt()));
|
setPlainText(ui->xRefsLineEdit, QString::number(analinfo["xrefs"].toSt64()));
|
||||||
setPlainText(ui->callsLineEdit, QString::number(analinfo["calls"].toInt()));
|
setPlainText(ui->callsLineEdit, QString::number(analinfo["calls"].toSt64()));
|
||||||
setPlainText(ui->stringsLineEdit, QString::number(analinfo["strings"].toInt()));
|
setPlainText(ui->stringsLineEdit, QString::number(analinfo["strings"].toSt64()));
|
||||||
setPlainText(ui->symbolsLineEdit, QString::number(analinfo["symbols"].toInt()));
|
setPlainText(ui->symbolsLineEdit, QString::number(analinfo["symbols"].toSt64()));
|
||||||
setPlainText(ui->importsLineEdit, QString::number(analinfo["imports"].toInt()));
|
setPlainText(ui->importsLineEdit, QString::number(analinfo["imports"].toSt64()));
|
||||||
setPlainText(ui->coverageLineEdit, QString::number(analinfo["covrage"].toInt()) + " bytes");
|
setPlainText(ui->coverageLineEdit, QString::number(analinfo["covrage"].toSt64()) + " bytes");
|
||||||
setPlainText(ui->codeSizeLineEdit, QString::number(analinfo["codesz"].toInt()) + " bytes");
|
setPlainText(ui->codeSizeLineEdit, QString::number(analinfo["codesz"].toSt64()) + " bytes");
|
||||||
setPlainText(ui->percentageLineEdit, QString::number(analinfo["percent"].toInt()) + "%");
|
setPlainText(ui->percentageLineEdit, QString::number(analinfo["percent"].toSt64()) + "%");
|
||||||
|
|
||||||
QStringList libs = Core()->cmdList("il");
|
QStringList libs = Core()->cmdList("il");
|
||||||
if (!libs.isEmpty()) {
|
if (!libs.isEmpty()) {
|
||||||
@ -155,10 +155,10 @@ void Dashboard::updateContents()
|
|||||||
QStringList stats = Core()->getStats();
|
QStringList stats = Core()->getStats();
|
||||||
|
|
||||||
// Check if signature info and version info available
|
// Check if signature info and version info available
|
||||||
if (Core()->getSignatureInfo().isEmpty()) {
|
if (!Core()->getSignatureInfo().size()) {
|
||||||
ui->certificateButton->setEnabled(false);
|
ui->certificateButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
if (Core()->getFileVersionInfo().isEmpty()) {
|
if (!Core()->getFileVersionInfo().size()) {
|
||||||
ui->versioninfoButton->setEnabled(false);
|
ui->versioninfoButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,8 +173,7 @@ void Dashboard::on_certificateButton_clicked()
|
|||||||
viewDialog = new QDialog(this);
|
viewDialog = new QDialog(this);
|
||||||
view = new CutterTreeView(viewDialog);
|
view = new CutterTreeView(viewDialog);
|
||||||
model = new JsonModel();
|
model = new JsonModel();
|
||||||
QJsonDocument qjsonCertificatesDoc = Core()->getSignatureInfo();
|
qstrCertificates = Core()->getSignatureInfo().toJson();
|
||||||
qstrCertificates = qjsonCertificatesDoc.toJson(QJsonDocument::Compact);
|
|
||||||
}
|
}
|
||||||
if (!viewDialog->isVisible()) {
|
if (!viewDialog->isVisible()) {
|
||||||
std::string strCertificates = qstrCertificates.toUtf8().constData();
|
std::string strCertificates = qstrCertificates.toUtf8().constData();
|
||||||
@ -230,9 +229,9 @@ void Dashboard::setPlainText(QLineEdit *textBox, const QString &text)
|
|||||||
* @param textBox
|
* @param textBox
|
||||||
* @param isTrue
|
* @param isTrue
|
||||||
*/
|
*/
|
||||||
void Dashboard::setBool(QLineEdit *textBox, const QJsonObject &jsonObject, const QString &key)
|
void Dashboard::setBool(QLineEdit *textBox, const CutterJson &jsonObject, const char *key)
|
||||||
{
|
{
|
||||||
if (jsonObject.contains(key)) {
|
if (jsonObject[key].valid()) {
|
||||||
if (jsonObject[key].toBool()) {
|
if (jsonObject[key].toBool()) {
|
||||||
setPlainText(textBox, tr("True"));
|
setPlainText(textBox, tr("True"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "core/Cutter.h"
|
||||||
#include "CutterDockWidget.h"
|
#include "CutterDockWidget.h"
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -32,7 +33,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::Dashboard> ui;
|
std::unique_ptr<Ui::Dashboard> ui;
|
||||||
void setPlainText(QLineEdit *textBox, const QString &text);
|
void setPlainText(QLineEdit *textBox, const QString &text);
|
||||||
void setBool(QLineEdit *textBox, const QJsonObject &jsonObject, const QString &key);
|
void setBool(QLineEdit *textBox, const CutterJson &jsonObject, const char *key);
|
||||||
|
|
||||||
QWidget *hashesWidget = nullptr;
|
QWidget *hashesWidget = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -182,12 +182,11 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
.set("asm.lines", false)
|
.set("asm.lines", false)
|
||||||
.set("asm.lines.fcn", false);
|
.set("asm.lines.fcn", false);
|
||||||
|
|
||||||
QJsonArray functions;
|
CutterJson functions;
|
||||||
RzAnalysisFunction *fcn = Core()->functionIn(seekable->getOffset());
|
RzAnalysisFunction *fcn = Core()->functionIn(seekable->getOffset());
|
||||||
if (fcn) {
|
if (fcn) {
|
||||||
currentFcnAddr = fcn->addr;
|
currentFcnAddr = fcn->addr;
|
||||||
QJsonDocument functionsDoc = Core()->cmdj("agJ " + RzAddressString(fcn->addr));
|
functions = Core()->cmdj("agJ " + RzAddressString(fcn->addr));
|
||||||
functions = functionsDoc.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
disassembly_blocks.clear();
|
disassembly_blocks.clear();
|
||||||
@ -198,7 +197,7 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
highlight_token = nullptr;
|
highlight_token = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
emptyGraph = functions.isEmpty();
|
emptyGraph = !functions.size();
|
||||||
if (emptyGraph) {
|
if (emptyGraph) {
|
||||||
// If there's no function to print, just add a message
|
// If there's no function to print, just add a message
|
||||||
if (!emptyText) {
|
if (!emptyText) {
|
||||||
@ -215,8 +214,7 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
// Refresh global "empty graph" variable so other widget know there is nothing to show here
|
// Refresh global "empty graph" variable so other widget know there is nothing to show here
|
||||||
Core()->setGraphEmpty(emptyGraph);
|
Core()->setGraphEmpty(emptyGraph);
|
||||||
|
|
||||||
QJsonValue funcRef = functions.first();
|
CutterJson func = functions.first();
|
||||||
QJsonObject func = funcRef.toObject();
|
|
||||||
|
|
||||||
windowTitle = tr("Graph");
|
windowTitle = tr("Graph");
|
||||||
QString funcName = func["name"].toString().trimmed();
|
QString funcName = func["name"].toString().trimmed();
|
||||||
@ -227,15 +225,14 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
}
|
}
|
||||||
emit nameChanged(windowTitle);
|
emit nameChanged(windowTitle);
|
||||||
|
|
||||||
RVA entry = func["offset"].toVariant().toULongLong();
|
RVA entry = func["offset"].toRVA();
|
||||||
|
|
||||||
setEntry(entry);
|
setEntry(entry);
|
||||||
for (const QJsonValueRef &value : func["blocks"].toArray()) {
|
for (CutterJson block : func["blocks"]) {
|
||||||
QJsonObject block = value.toObject();
|
RVA block_entry = block["offset"].toRVA();
|
||||||
RVA block_entry = block["offset"].toVariant().toULongLong();
|
RVA block_size = block["size"].toRVA();
|
||||||
RVA block_size = block["size"].toVariant().toULongLong();
|
RVA block_fail = block["fail"].toRVA();
|
||||||
RVA block_fail = block["fail"].toVariant().toULongLong();
|
RVA block_jump = block["jump"].toRVA();
|
||||||
RVA block_jump = block["jump"].toVariant().toULongLong();
|
|
||||||
|
|
||||||
DisassemblyBlock db;
|
DisassemblyBlock db;
|
||||||
GraphBlock gb;
|
GraphBlock gb;
|
||||||
@ -259,30 +256,29 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
gb.edges.emplace_back(block_jump);
|
gb.edges.emplace_back(block_jump);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject switchOp = block["switchop"].toObject();
|
CutterJson switchOp = block["switchop"];
|
||||||
if (!switchOp.isEmpty()) {
|
if (switchOp.size()) {
|
||||||
QJsonArray caseArray = switchOp["cases"].toArray();
|
for (CutterJson caseOp : switchOp["cases"]) {
|
||||||
for (QJsonValue caseOpValue : caseArray) {
|
RVA caseJump = caseOp["jump"].toRVA();
|
||||||
QJsonObject caseOp = caseOpValue.toObject();
|
if (caseJump == RVA_INVALID) {
|
||||||
bool ok;
|
|
||||||
RVA caseJump = caseOp["jump"].toVariant().toULongLong(&ok);
|
|
||||||
if (!ok) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
gb.edges.emplace_back(caseJump);
|
gb.edges.emplace_back(caseJump);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonArray opArray = block["ops"].toArray();
|
CutterJson opArray = block["ops"];
|
||||||
for (int opIndex = 0; opIndex < opArray.size(); opIndex++) {
|
CutterJson::iterator iterator = opArray.begin();
|
||||||
QJsonObject op = opArray[opIndex].toObject();
|
while (iterator != opArray.end()) {
|
||||||
|
CutterJson op = *iterator;
|
||||||
Instr i;
|
Instr i;
|
||||||
i.addr = op["offset"].toVariant().toULongLong();
|
i.addr = op["offset"].toUt64();
|
||||||
|
|
||||||
if (opIndex < opArray.size() - 1) {
|
++iterator;
|
||||||
|
|
||||||
|
if (iterator != opArray.end()) {
|
||||||
// get instruction size from distance to next instruction ...
|
// get instruction size from distance to next instruction ...
|
||||||
RVA nextOffset =
|
RVA nextOffset = (*iterator)["offset"].toRVA();
|
||||||
opArray[opIndex + 1].toObject()["offset"].toVariant().toULongLong();
|
|
||||||
i.size = nextOffset - i.addr;
|
i.size = nextOffset - i.addr;
|
||||||
} else {
|
} else {
|
||||||
// or to the end of the block.
|
// or to the end of the block.
|
||||||
@ -314,7 +310,7 @@ void DisassemblerGraphView::loadCurrentGraph()
|
|||||||
}
|
}
|
||||||
cleanupEdges(blocks);
|
cleanupEdges(blocks);
|
||||||
|
|
||||||
if (!func["blocks"].toArray().isEmpty()) {
|
if (func["blocks"].size()) {
|
||||||
computeGraphPlacement();
|
computeGraphPlacement();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,7 +562,7 @@ void FunctionsWidget::refreshTree()
|
|||||||
importAddresses.insert(import.plt);
|
importAddresses.insert(import.plt);
|
||||||
}
|
}
|
||||||
|
|
||||||
mainAdress = (ut64)Core()->cmdj("iMj").object()["vaddr"].toInt();
|
mainAdress = (ut64)Core()->cmdj("iMj")["vaddr"].toUt64();
|
||||||
|
|
||||||
functionModel->updateCurrentIndex();
|
functionModel->updateCurrentIndex();
|
||||||
functionModel->endResetModel();
|
functionModel->endResetModel();
|
||||||
|
@ -106,14 +106,12 @@ QString ProcessesWidget::translateStatus(QString status)
|
|||||||
|
|
||||||
void ProcessesWidget::setProcessesGrid()
|
void ProcessesWidget::setProcessesGrid()
|
||||||
{
|
{
|
||||||
QJsonArray processesValues = Core()->getChildProcesses(DEBUGGED_PID).array();
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
QFont font;
|
QFont font;
|
||||||
|
|
||||||
for (const QJsonValue &value : processesValues) {
|
for (CutterJson processesItem : Core()->getChildProcesses(DEBUGGED_PID)) {
|
||||||
QJsonObject processesItem = value.toObject();
|
st64 pid = processesItem["pid"].toSt64();
|
||||||
int pid = processesItem["pid"].toVariant().toInt();
|
st64 uid = processesItem["uid"].toSt64();
|
||||||
int uid = processesItem["uid"].toVariant().toInt();
|
|
||||||
QString status = translateStatus(processesItem["status"].toString());
|
QString status = translateStatus(processesItem["status"].toString());
|
||||||
QString path = processesItem["path"].toString();
|
QString path = processesItem["path"].toString();
|
||||||
bool current = processesItem["current"].toBool();
|
bool current = processesItem["current"].toBool();
|
||||||
@ -162,10 +160,9 @@ void ProcessesWidget::onActivated(const QModelIndex &index)
|
|||||||
|
|
||||||
// Verify that the selected pid is still in the processes list since dp= will
|
// Verify that the selected pid is still in the processes list since dp= will
|
||||||
// attach to any given id. If it isn't found simply update the UI.
|
// attach to any given id. If it isn't found simply update the UI.
|
||||||
QJsonArray processesValues = Core()->getChildProcesses(DEBUGGED_PID).array();
|
for (CutterJson value : Core()->getChildProcesses(DEBUGGED_PID)) {
|
||||||
for (QJsonValue value : processesValues) {
|
QString status = value["status"].toString();
|
||||||
QString status = value.toObject()["status"].toString();
|
if (pid == value["pid"].toSt64()) {
|
||||||
if (pid == value.toObject()["pid"].toInt()) {
|
|
||||||
if (QString(QChar(RZ_DBG_PROC_ZOMBIE)) == status
|
if (QString(QChar(RZ_DBG_PROC_ZOMBIE)) == status
|
||||||
|| QString(QChar(RZ_DBG_PROC_DEAD)) == status) {
|
|| QString(QChar(RZ_DBG_PROC_DEAD)) == status) {
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
|
@ -184,14 +184,13 @@ void RegisterRefsWidget::refreshRegisterRef()
|
|||||||
|
|
||||||
registerRefModel->beginResetModel();
|
registerRefModel->beginResetModel();
|
||||||
|
|
||||||
QList<QJsonObject> regRefs = Core()->getRegisterRefs();
|
|
||||||
registerRefs.clear();
|
registerRefs.clear();
|
||||||
for (const QJsonObject ® : regRefs) {
|
for (const RegisterRef ® : Core()->getRegisterRefs()) {
|
||||||
RegisterRefDescription desc;
|
RegisterRefDescription desc;
|
||||||
|
|
||||||
desc.value = RzAddressString(reg["value"].toVariant().toULongLong());
|
desc.value = RzAddressString(reg.value);
|
||||||
desc.reg = reg["name"].toVariant().toString();
|
desc.reg = reg.name;
|
||||||
desc.refDesc = Core()->formatRefDesc(reg["ref"].toObject());
|
desc.refDesc = Core()->formatRefDesc(reg.ref);
|
||||||
|
|
||||||
registerRefs.push_back(desc);
|
registerRefs.push_back(desc);
|
||||||
}
|
}
|
||||||
|
@ -96,12 +96,11 @@ void GenericRizinGraphView::loadCurrentGraph()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonDocument functionsDoc = Core()->cmdj(QString("%1j").arg(graphCommand));
|
CutterJson functionsDoc = Core()->cmdj(QString("%1j").arg(graphCommand));
|
||||||
auto nodes = functionsDoc.object()["nodes"].toArray();
|
auto nodes = functionsDoc["nodes"];
|
||||||
|
|
||||||
for (const QJsonValueRef &value : nodes) {
|
for (CutterJson block : nodes) {
|
||||||
QJsonObject block = value.toObject();
|
uint64_t id = block["id"].toUt64();
|
||||||
uint64_t id = block["id"].toVariant().toULongLong();
|
|
||||||
|
|
||||||
QString content;
|
QString content;
|
||||||
QString title = block["title"].toString();
|
QString title = block["title"].toString();
|
||||||
@ -112,11 +111,11 @@ void GenericRizinGraphView::loadCurrentGraph()
|
|||||||
content = title + body;
|
content = title + body;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto edges = block["out_nodes"].toArray();
|
auto edges = block["out_nodes"];
|
||||||
GraphLayout::GraphBlock layoutBlock;
|
GraphLayout::GraphBlock layoutBlock;
|
||||||
layoutBlock.entry = id;
|
layoutBlock.entry = id;
|
||||||
for (auto edge : edges) {
|
for (auto edge : edges) {
|
||||||
auto targetId = edge.toVariant().toULongLong();
|
auto targetId = edge.toUt64();
|
||||||
layoutBlock.edges.emplace_back(targetId);
|
layoutBlock.edges.emplace_back(targetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,16 +145,16 @@ StackModel::StackModel(QObject *parent) : QAbstractTableModel(parent) {}
|
|||||||
|
|
||||||
void StackModel::reload()
|
void StackModel::reload()
|
||||||
{
|
{
|
||||||
QList<QJsonObject> stackItems = Core()->getStack();
|
QList<AddrRefs> stackItems = Core()->getStack();
|
||||||
|
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
values.clear();
|
values.clear();
|
||||||
for (const QJsonObject &stackItem : stackItems) {
|
for (const AddrRefs &stackItem : stackItems) {
|
||||||
Item item;
|
Item item;
|
||||||
|
|
||||||
item.offset = stackItem["addr"].toVariant().toULongLong();
|
item.offset = stackItem.addr;
|
||||||
item.value = RzAddressString(stackItem["value"].toVariant().toULongLong());
|
item.value = RzAddressString(stackItem.value);
|
||||||
item.refDesc = Core()->formatRefDesc(stackItem["ref"].toObject());
|
item.refDesc = Core()->formatRefDesc(*stackItem.ref);
|
||||||
|
|
||||||
values.push_back(item);
|
values.push_back(item);
|
||||||
}
|
}
|
||||||
|
@ -104,13 +104,11 @@ QString ThreadsWidget::translateStatus(QString status)
|
|||||||
|
|
||||||
void ThreadsWidget::setThreadsGrid()
|
void ThreadsWidget::setThreadsGrid()
|
||||||
{
|
{
|
||||||
QJsonArray threadsValues = Core()->getProcessThreads(DEBUGGED_PID).array();
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
QFont font;
|
QFont font;
|
||||||
|
|
||||||
for (const QJsonValue &value : threadsValues) {
|
for (CutterJson threadsItem : Core()->getProcessThreads(DEBUGGED_PID)) {
|
||||||
QJsonObject threadsItem = value.toObject();
|
st64 pid = threadsItem["pid"].toSt64();
|
||||||
int pid = threadsItem["pid"].toVariant().toInt();
|
|
||||||
QString status = translateStatus(threadsItem["status"].toString());
|
QString status = translateStatus(threadsItem["status"].toString());
|
||||||
QString path = threadsItem["path"].toString();
|
QString path = threadsItem["path"].toString();
|
||||||
bool current = threadsItem["current"].toBool();
|
bool current = threadsItem["current"].toBool();
|
||||||
@ -152,9 +150,8 @@ void ThreadsWidget::onActivated(const QModelIndex &index)
|
|||||||
|
|
||||||
// Verify that the selected tid is still in the threads list since dpt= will
|
// Verify that the selected tid is still in the threads list since dpt= will
|
||||||
// attach to any given id. If it isn't found simply update the UI.
|
// attach to any given id. If it isn't found simply update the UI.
|
||||||
QJsonArray threadsValues = Core()->getProcessThreads(DEBUGGED_PID).array();
|
for (CutterJson value : Core()->getProcessThreads(DEBUGGED_PID)) {
|
||||||
for (QJsonValue value : threadsValues) {
|
if (tid == value["pid"].toSt64()) {
|
||||||
if (tid == value.toObject()["pid"].toInt()) {
|
|
||||||
Core()->setCurrentDebugThread(tid);
|
Core()->setCurrentDebugThread(tid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user