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