mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-21 12:26:11 +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),
|
||||
commentsDock(nullptr),
|
||||
stringsDock(nullptr),
|
||||
pseudocodeDock(nullptr),
|
||||
flagsDock(nullptr),
|
||||
dashboardDock(nullptr),
|
||||
gotoEntry(nullptr),
|
||||
@ -191,6 +192,9 @@ void MainWindow::initUI()
|
||||
hexdumpDock = new HexdumpWidget(tr("Hexdump"), this);
|
||||
dockWidgets.push_back(hexdumpDock);
|
||||
|
||||
pseudocodeDock = new PseudocodeWidget(tr("Pseudocode"), this);
|
||||
dockWidgets.push_back(pseudocodeDock);
|
||||
|
||||
// Add graph view as dockable
|
||||
graphDock = new QDockWidget(tr("Graph"), this);
|
||||
graphDock->setObjectName("Graph");
|
||||
@ -659,6 +663,7 @@ void MainWindow::restoreDocks()
|
||||
tabifyDockWidget(dashboardDock, disassemblyDock);
|
||||
tabifyDockWidget(dashboardDock, graphDock);
|
||||
tabifyDockWidget(dashboardDock, hexdumpDock);
|
||||
tabifyDockWidget(dashboardDock, pseudocodeDock);
|
||||
tabifyDockWidget(dashboardDock, entrypointDock);
|
||||
tabifyDockWidget(dashboardDock, flagsDock);
|
||||
tabifyDockWidget(dashboardDock, stringsDock);
|
||||
@ -695,6 +700,7 @@ void MainWindow::showDefaultDocks()
|
||||
disassemblyDock,
|
||||
sidebarDock,
|
||||
hexdumpDock,
|
||||
pseudocodeDock,
|
||||
dashboardDock
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "widgets/DisassemblerGraphView.h"
|
||||
#include "widgets/SidebarWidget.h"
|
||||
#include "widgets/HexdumpWidget.h"
|
||||
#include "widgets/PseudocodeWidget.h"
|
||||
#include "utils/Configuration.h"
|
||||
|
||||
#include <QMainWindow>
|
||||
@ -169,6 +170,7 @@ private:
|
||||
DisassemblyWidget *disassemblyDock;
|
||||
SidebarWidget *sidebarDock;
|
||||
HexdumpWidget *hexdumpDock;
|
||||
PseudocodeWidget *pseudocodeDock;
|
||||
QDockWidget *graphDock;
|
||||
DisassemblerGraphView *graphView;
|
||||
QDockWidget *asmDock;
|
||||
|
@ -721,6 +721,11 @@ RVA CutterCore::getOffsetJump(RVA addr)
|
||||
return value;
|
||||
}
|
||||
|
||||
QString CutterCore::getDecompiledCode(RVA addr)
|
||||
{
|
||||
return cmd("pdc @ " + QString::number(addr));
|
||||
}
|
||||
|
||||
QString CutterCore::getDecompiledCode(QString addr)
|
||||
{
|
||||
return cmd("pdc @ " + addr);
|
||||
|
@ -225,8 +225,8 @@ public:
|
||||
RVA prevOpAddr(RVA startAddr, int count);
|
||||
RVA nextOpAddr(RVA startAddr, int count);
|
||||
|
||||
// Disassembly/Graph/Hexdump view priority
|
||||
enum class MemoryWidgetType { Disassembly, Graph, Hexdump };
|
||||
// Disassembly/Graph/Hexdump/Pseudocode view priority
|
||||
enum class MemoryWidgetType { Disassembly, Graph, Hexdump, Pseudocode };
|
||||
MemoryWidgetType getMemoryWidgetPriority() const { return memoryWidgetPriority; }
|
||||
void setMemoryWidgetPriority(MemoryWidgetType type) { memoryWidgetPriority = type; }
|
||||
void triggerRaisePrioritizedMemoryWidget() { emit raisePrioritizedMemoryWidget(memoryWidgetPriority); }
|
||||
@ -262,6 +262,7 @@ public:
|
||||
QList<QList<QString>> get_exec_sections();
|
||||
QString getOffsetInfo(QString addr);
|
||||
RVA getOffsetJump(RVA addr);
|
||||
QString getDecompiledCode(RVA addr);
|
||||
QString getDecompiledCode(QString addr);
|
||||
QString getFileInfo();
|
||||
QStringList getStats();
|
||||
|
@ -79,7 +79,8 @@ SOURCES += \
|
||||
utils/Colors.cpp \
|
||||
dialogs/SaveProjectDialog.cpp \
|
||||
utils/TempConfig.cpp \
|
||||
utils/SvgIconEngine.cpp
|
||||
utils/SvgIconEngine.cpp \
|
||||
widgets/PseudocodeWidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
cutter.h \
|
||||
@ -129,7 +130,8 @@ HEADERS += \
|
||||
utils/Colors.h \
|
||||
dialogs/SaveProjectDialog.h \
|
||||
utils/TempConfig.h \
|
||||
utils/SvgIconEngine.h
|
||||
utils/SvgIconEngine.h \
|
||||
widgets/PseudocodeWidget.h
|
||||
|
||||
FORMS += \
|
||||
dialogs/AboutDialog.ui \
|
||||
@ -159,7 +161,8 @@ FORMS += \
|
||||
widgets/SymbolsWidget.ui \
|
||||
widgets/SidebarWidget.ui \
|
||||
widgets/HexdumpWidget.ui \
|
||||
dialogs/SaveProjectDialog.ui
|
||||
dialogs/SaveProjectDialog.ui \
|
||||
widgets/PseudocodeWidget.ui
|
||||
|
||||
RESOURCES += \
|
||||
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