mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-19 03:16:10 +00:00
* Add basic Pseudocode tab (Fixes #142) * Add missing include to fix Windows build * PseudocodeWidget: Move refreshPseudocode to slots to silence warning
This commit is contained in:
parent
3f05e55bbe
commit
8bc7213b8c
@ -99,6 +99,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
relocsDock(nullptr),
|
relocsDock(nullptr),
|
||||||
commentsDock(nullptr),
|
commentsDock(nullptr),
|
||||||
stringsDock(nullptr),
|
stringsDock(nullptr),
|
||||||
|
pseudocodeDock(nullptr),
|
||||||
flagsDock(nullptr),
|
flagsDock(nullptr),
|
||||||
dashboardDock(nullptr),
|
dashboardDock(nullptr),
|
||||||
gotoEntry(nullptr),
|
gotoEntry(nullptr),
|
||||||
@ -191,6 +192,9 @@ void MainWindow::initUI()
|
|||||||
hexdumpDock = new HexdumpWidget(tr("Hexdump"), this);
|
hexdumpDock = new HexdumpWidget(tr("Hexdump"), this);
|
||||||
dockWidgets.push_back(hexdumpDock);
|
dockWidgets.push_back(hexdumpDock);
|
||||||
|
|
||||||
|
pseudocodeDock = new PseudocodeWidget(tr("Pseudocode"), this);
|
||||||
|
dockWidgets.push_back(pseudocodeDock);
|
||||||
|
|
||||||
// Add graph view as dockable
|
// Add graph view as dockable
|
||||||
graphDock = new QDockWidget(tr("Graph"), this);
|
graphDock = new QDockWidget(tr("Graph"), this);
|
||||||
graphDock->setObjectName("Graph");
|
graphDock->setObjectName("Graph");
|
||||||
@ -659,6 +663,7 @@ void MainWindow::restoreDocks()
|
|||||||
tabifyDockWidget(dashboardDock, disassemblyDock);
|
tabifyDockWidget(dashboardDock, disassemblyDock);
|
||||||
tabifyDockWidget(dashboardDock, graphDock);
|
tabifyDockWidget(dashboardDock, graphDock);
|
||||||
tabifyDockWidget(dashboardDock, hexdumpDock);
|
tabifyDockWidget(dashboardDock, hexdumpDock);
|
||||||
|
tabifyDockWidget(dashboardDock, pseudocodeDock);
|
||||||
tabifyDockWidget(dashboardDock, entrypointDock);
|
tabifyDockWidget(dashboardDock, entrypointDock);
|
||||||
tabifyDockWidget(dashboardDock, flagsDock);
|
tabifyDockWidget(dashboardDock, flagsDock);
|
||||||
tabifyDockWidget(dashboardDock, stringsDock);
|
tabifyDockWidget(dashboardDock, stringsDock);
|
||||||
@ -695,6 +700,7 @@ void MainWindow::showDefaultDocks()
|
|||||||
disassemblyDock,
|
disassemblyDock,
|
||||||
sidebarDock,
|
sidebarDock,
|
||||||
hexdumpDock,
|
hexdumpDock,
|
||||||
|
pseudocodeDock,
|
||||||
dashboardDock
|
dashboardDock
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "widgets/DisassemblerGraphView.h"
|
#include "widgets/DisassemblerGraphView.h"
|
||||||
#include "widgets/SidebarWidget.h"
|
#include "widgets/SidebarWidget.h"
|
||||||
#include "widgets/HexdumpWidget.h"
|
#include "widgets/HexdumpWidget.h"
|
||||||
|
#include "widgets/PseudocodeWidget.h"
|
||||||
#include "utils/Configuration.h"
|
#include "utils/Configuration.h"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
@ -169,6 +170,7 @@ private:
|
|||||||
DisassemblyWidget *disassemblyDock;
|
DisassemblyWidget *disassemblyDock;
|
||||||
SidebarWidget *sidebarDock;
|
SidebarWidget *sidebarDock;
|
||||||
HexdumpWidget *hexdumpDock;
|
HexdumpWidget *hexdumpDock;
|
||||||
|
PseudocodeWidget *pseudocodeDock;
|
||||||
QDockWidget *graphDock;
|
QDockWidget *graphDock;
|
||||||
DisassemblerGraphView *graphView;
|
DisassemblerGraphView *graphView;
|
||||||
QDockWidget *asmDock;
|
QDockWidget *asmDock;
|
||||||
|
@ -721,6 +721,11 @@ RVA CutterCore::getOffsetJump(RVA addr)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString CutterCore::getDecompiledCode(RVA addr)
|
||||||
|
{
|
||||||
|
return cmd("pdc @ " + QString::number(addr));
|
||||||
|
}
|
||||||
|
|
||||||
QString CutterCore::getDecompiledCode(QString addr)
|
QString CutterCore::getDecompiledCode(QString addr)
|
||||||
{
|
{
|
||||||
return cmd("pdc @ " + addr);
|
return cmd("pdc @ " + addr);
|
||||||
|
@ -225,8 +225,8 @@ public:
|
|||||||
RVA prevOpAddr(RVA startAddr, int count);
|
RVA prevOpAddr(RVA startAddr, int count);
|
||||||
RVA nextOpAddr(RVA startAddr, int count);
|
RVA nextOpAddr(RVA startAddr, int count);
|
||||||
|
|
||||||
// Disassembly/Graph/Hexdump view priority
|
// Disassembly/Graph/Hexdump/Pseudocode view priority
|
||||||
enum class MemoryWidgetType { Disassembly, Graph, Hexdump };
|
enum class MemoryWidgetType { Disassembly, Graph, Hexdump, Pseudocode };
|
||||||
MemoryWidgetType getMemoryWidgetPriority() const { return memoryWidgetPriority; }
|
MemoryWidgetType getMemoryWidgetPriority() const { return memoryWidgetPriority; }
|
||||||
void setMemoryWidgetPriority(MemoryWidgetType type) { memoryWidgetPriority = type; }
|
void setMemoryWidgetPriority(MemoryWidgetType type) { memoryWidgetPriority = type; }
|
||||||
void triggerRaisePrioritizedMemoryWidget() { emit raisePrioritizedMemoryWidget(memoryWidgetPriority); }
|
void triggerRaisePrioritizedMemoryWidget() { emit raisePrioritizedMemoryWidget(memoryWidgetPriority); }
|
||||||
@ -262,6 +262,7 @@ public:
|
|||||||
QList<QList<QString>> get_exec_sections();
|
QList<QList<QString>> get_exec_sections();
|
||||||
QString getOffsetInfo(QString addr);
|
QString getOffsetInfo(QString addr);
|
||||||
RVA getOffsetJump(RVA addr);
|
RVA getOffsetJump(RVA addr);
|
||||||
|
QString getDecompiledCode(RVA addr);
|
||||||
QString getDecompiledCode(QString addr);
|
QString getDecompiledCode(QString addr);
|
||||||
QString getFileInfo();
|
QString getFileInfo();
|
||||||
QStringList getStats();
|
QStringList getStats();
|
||||||
|
@ -79,7 +79,8 @@ SOURCES += \
|
|||||||
utils/Colors.cpp \
|
utils/Colors.cpp \
|
||||||
dialogs/SaveProjectDialog.cpp \
|
dialogs/SaveProjectDialog.cpp \
|
||||||
utils/TempConfig.cpp \
|
utils/TempConfig.cpp \
|
||||||
utils/SvgIconEngine.cpp
|
utils/SvgIconEngine.cpp \
|
||||||
|
widgets/PseudocodeWidget.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
cutter.h \
|
cutter.h \
|
||||||
@ -129,7 +130,8 @@ HEADERS += \
|
|||||||
utils/Colors.h \
|
utils/Colors.h \
|
||||||
dialogs/SaveProjectDialog.h \
|
dialogs/SaveProjectDialog.h \
|
||||||
utils/TempConfig.h \
|
utils/TempConfig.h \
|
||||||
utils/SvgIconEngine.h
|
utils/SvgIconEngine.h \
|
||||||
|
widgets/PseudocodeWidget.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
dialogs/AboutDialog.ui \
|
dialogs/AboutDialog.ui \
|
||||||
@ -159,7 +161,8 @@ FORMS += \
|
|||||||
widgets/SymbolsWidget.ui \
|
widgets/SymbolsWidget.ui \
|
||||||
widgets/SidebarWidget.ui \
|
widgets/SidebarWidget.ui \
|
||||||
widgets/HexdumpWidget.ui \
|
widgets/HexdumpWidget.ui \
|
||||||
dialogs/SaveProjectDialog.ui
|
dialogs/SaveProjectDialog.ui \
|
||||||
|
widgets/PseudocodeWidget.ui
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources.qrc
|
resources.qrc
|
||||||
|
103
src/widgets/PseudocodeWidget.cpp
Normal file
103
src/widgets/PseudocodeWidget.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#include "PseudocodeWidget.h"
|
||||||
|
#include "ui_PseudocodeWidget.h"
|
||||||
|
|
||||||
|
#include "utils/Configuration.h"
|
||||||
|
#include "utils/Helpers.h"
|
||||||
|
#include "utils/TempConfig.h"
|
||||||
|
|
||||||
|
PseudocodeWidget::PseudocodeWidget(QWidget *parent, Qt::WindowFlags flags) :
|
||||||
|
QDockWidget(parent, flags),
|
||||||
|
ui(new Ui::PseudocodeWidget)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
setupFonts();
|
||||||
|
colorsUpdatedSlot();
|
||||||
|
|
||||||
|
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdated()));
|
||||||
|
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
|
||||||
|
|
||||||
|
connect(Core(), SIGNAL(commentsChanged()), this, SLOT(refreshPseudocode()));
|
||||||
|
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshPseudocode()));
|
||||||
|
connect(Core(), SIGNAL(functionRenamed(QString, QString)), this, SLOT(refreshPseudocode()));
|
||||||
|
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshPseudocode()));
|
||||||
|
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshPseudocode()));
|
||||||
|
connect(Core(), &CutterCore::instructionChanged, this, [this](RVA offset) {
|
||||||
|
refreshPseudocode();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
connect(Core(), SIGNAL(seekChanged(RVA)), this, SLOT(on_seekChanged(RVA)));
|
||||||
|
connect(Core(), SIGNAL(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)), this, SLOT(raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType)));
|
||||||
|
connect(this, &QDockWidget::visibilityChanged, this, [](bool visibility) {
|
||||||
|
if (visibility)
|
||||||
|
{
|
||||||
|
Core()->setMemoryWidgetPriority(CutterCore::MemoryWidgetType::Pseudocode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get alerted when there's a refresh
|
||||||
|
connect(Core(), &CutterCore::refreshAll, this, [this]() {
|
||||||
|
refresh(Core()->getOffset());
|
||||||
|
});
|
||||||
|
|
||||||
|
refresh(Core()->getOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
PseudocodeWidget::PseudocodeWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags)
|
||||||
|
: PseudocodeWidget(parent, flags)
|
||||||
|
{
|
||||||
|
setWindowTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
PseudocodeWidget::~PseudocodeWidget() {}
|
||||||
|
|
||||||
|
|
||||||
|
void PseudocodeWidget::on_seekChanged(RVA addr)
|
||||||
|
{
|
||||||
|
refresh(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PseudocodeWidget::refresh(RVA addr)
|
||||||
|
{
|
||||||
|
QString decompiledCode = Core()->getDecompiledCode(addr);
|
||||||
|
if (decompiledCode.length() == 0)
|
||||||
|
{
|
||||||
|
decompiledCode = tr("Cannot decompile at") + " " + RAddressString(addr) + " " + tr("(Not a function?)");
|
||||||
|
}
|
||||||
|
ui->pseudocodeTextBrowser->setText(decompiledCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PseudocodeWidget::refreshPseudocode()
|
||||||
|
{
|
||||||
|
refresh(Core()->getOffset());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PseudocodeWidget::raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type)
|
||||||
|
{
|
||||||
|
if (type == CutterCore::MemoryWidgetType::Pseudocode)
|
||||||
|
{
|
||||||
|
raise();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PseudocodeWidget::setupFonts()
|
||||||
|
{
|
||||||
|
QFont font = Config()->getFont();
|
||||||
|
ui->pseudocodeTextBrowser->setFont(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PseudocodeWidget::fontsUpdated()
|
||||||
|
{
|
||||||
|
setupFonts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PseudocodeWidget::colorsUpdatedSlot()
|
||||||
|
{
|
||||||
|
QString styleSheet = QString("QTextBrowser { background-color: %1; color: %2; }")
|
||||||
|
.arg(ConfigColor("gui.background").name())
|
||||||
|
.arg(ConfigColor("btext").name());
|
||||||
|
ui->pseudocodeTextBrowser->setStyleSheet(styleSheet);
|
||||||
|
}
|
40
src/widgets/PseudocodeWidget.h
Normal file
40
src/widgets/PseudocodeWidget.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef PSEUDOCODEWIDGET_H
|
||||||
|
#define PSEUDOCODEWIDGET_H
|
||||||
|
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "ui_PseudocodeWidget.h"
|
||||||
|
#include "cutter.h"
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class PseudocodeWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PseudocodeWidget : public QDockWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PseudocodeWidget(const QString &title, QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
|
||||||
|
explicit PseudocodeWidget(QWidget *parent = nullptr, Qt::WindowFlags flags = 0);
|
||||||
|
~PseudocodeWidget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Ui::PseudocodeWidget> ui;
|
||||||
|
void refresh(RVA addr);
|
||||||
|
void setupFonts();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
private slots:
|
||||||
|
void on_seekChanged(RVA addr);
|
||||||
|
void raisePrioritizedMemoryWidget(CutterCore::MemoryWidgetType type);
|
||||||
|
void fontsUpdated();
|
||||||
|
void colorsUpdatedSlot();
|
||||||
|
void refreshPseudocode();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PSEUDOCODEWIDGET_H
|
23
src/widgets/PseudocodeWidget.ui
Normal file
23
src/widgets/PseudocodeWidget.ui
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>PseudocodeWidget</class>
|
||||||
|
<widget class="QDockWidget" name="PseudocodeWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>686</width>
|
||||||
|
<height>646</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="toolTipDuration">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QTextBrowser" name="pseudocodeTextBrowser"/>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
Loading…
Reference in New Issue
Block a user