1
0
Fork 0

GUI: allow decompiling from the graph (for non-contiguous ranges)

This commit is contained in:
mrexodia 2017-02-18 22:48:45 +01:00
parent c30932646e
commit 2268d364a7
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
11 changed files with 46 additions and 18 deletions

View File

@ -41,6 +41,7 @@ public:
void* winId;
QWidget* scriptView;
ReferenceManager* referenceManager;
QWidget* snowmanView;
signals:
void disassembleAt(dsint va, dsint eip);

View File

@ -23,6 +23,7 @@
#include "SourceViewerManager.h"
#include "MiscUtil.h"
#include "DataCopyDialog.h"
#include "SnowmanView.h"
CPUDisassembly::CPUDisassembly(CPUWidget* parent) : Disassembly(parent)
{
@ -1796,7 +1797,7 @@ void CPUDisassembly::decompileSelectionSlot()
dsint addr = rvaToVa(getSelectionStart());
dsint size = getSelectionSize();
emit displaySnowmanWidget();
emit decompileAt(addr, addr + size);
DecompileAt(Bridge::getBridge()->snowmanView, addr, addr + size);
}
void CPUDisassembly::decompileFunctionSlot()
@ -1810,7 +1811,7 @@ void CPUDisassembly::decompileFunctionSlot()
DbgDisasmFastAt(end, &info);
end += info.size - 1;
emit displaySnowmanWidget();
emit decompileAt(start, end);
DecompileAt(Bridge::getBridge()->snowmanView, start, end);
}
}

View File

@ -32,7 +32,6 @@ signals:
void displayReferencesWidget();
void displaySourceManagerWidget();
void showPatches();
void decompileAt(dsint start, dsint end);
void displaySnowmanWidget();
void displayLogWidget();
void displayGraphWidget();

View File

@ -5,6 +5,7 @@
#include "GotoDialog.h"
#include "XrefBrowseDialog.h"
#include "LineEditDialog.h"
#include "SnowmanView.h"
#include <vector>
#include <QPainter>
#include <QScrollBar>
@ -1479,6 +1480,7 @@ void DisassemblerGraphView::setupContextMenu()
gotoMenu->addAction(makeShortcutAction(DIcon("cbp.png"), tr("Origin"), SLOT(gotoOriginSlot()), "ActionGotoOrigin"));
mMenuBuilder->addMenu(makeMenu(DIcon("goto.png"), tr("Go to")), gotoMenu);
mMenuBuilder->addAction(makeShortcutAction(DIcon("xrefs.png"), tr("Xrefs..."), SLOT(xrefSlot()), "ActionXrefs"));
mMenuBuilder->addAction(makeShortcutAction(DIcon("snowman.png"), tr("Decompile"), SLOT(decompileSlot()), "ActionGraphDecompile"));
mMenuBuilder->addSeparator();
mMenuBuilder->addAction(mToggleOverview = makeShortcutAction(DIcon("graph.png"), tr("&Overview"), SLOT(toggleOverviewSlot()), "ActionGraphToggleOverview"));
mMenuBuilder->addAction(mToggleSyncOrigin = makeShortcutAction(DIcon("lock.png"), tr("&Sync with origin"), SLOT(toggleSyncOriginSlot()), "ActionGraphSyncOrigin"));
@ -1690,3 +1692,26 @@ void DisassemblerGraphView::xrefSlot()
mXrefDlg->setup(this->get_cursor_pos(), "graph");
mXrefDlg->showNormal();
}
void DisassemblerGraphView::decompileSlot()
{
std::vector<SnowmanRange> ranges;
ranges.reserve(currentGraph.nodes.size());
SnowmanRange r;
for(const auto & nodeIt : currentGraph.nodes)
{
const BridgeCFNode & node = nodeIt.second;
r.start = node.instrs.empty() ? node.start : node.instrs[0].addr;
r.end = node.instrs.empty() ? node.end : node.instrs[node.instrs.size() - 1].addr;
BASIC_INSTRUCTION_INFO info;
DbgDisasmFastAt(r.end, &info);
r.end += info.size - 1;
ranges.push_back(r);
}
std::sort(ranges.begin(), ranges.end(), [](const SnowmanRange & a, const SnowmanRange & b)
{
return a.start > b.start;
});
emit displaySnowmanWidget();
DecompileRanges(Bridge::getBridge()->snowmanView, ranges.data(), ranges.size());
}

View File

@ -235,6 +235,9 @@ public:
bool navigate(duint addr);
void fontChanged();
signals:
void displaySnowmanWidget();
public slots:
void updateTimerEvent();
void loadGraphSlot(BridgeCFGraphList* graph, duint addr);
@ -257,6 +260,7 @@ public slots:
void setCommentSlot();
void setLabelSlot();
void xrefSlot();
void decompileSlot();
private:
QString status;

View File

@ -178,9 +178,10 @@ MainWindow::MainWindow(QWidget* parent)
// Snowman view (decompiler)
mSnowmanView = CreateSnowman(this);
if(!mSnowmanView)
mSnowmanView = (SnowmanView*)new QLabel("<center>Snowman is disabled...</center>", this);
mSnowmanView = new QLabel("<center>Snowman is disabled...</center>", this);
mSnowmanView->setWindowTitle(tr("Snowman"));
mSnowmanView->setWindowIcon(DIcon("snowman.png"));
Bridge::getBridge()->snowmanView = mSnowmanView;
// Notes manager
mNotesManager = new NotesManager(this);
@ -325,7 +326,8 @@ MainWindow::MainWindow(QWidget* parent)
connect(mCpuWidget->getDisasmWidget(), SIGNAL(displayLogWidget()), this, SLOT(displayLogWidget()));
connect(mCpuWidget->getDisasmWidget(), SIGNAL(displayGraphWidget()), this, SLOT(displayGraphWidget()));
connect(mCpuWidget->getDisasmWidget(), SIGNAL(showPatches()), this, SLOT(patchWindow()));
connect(mCpuWidget->getDisasmWidget(), SIGNAL(decompileAt(dsint, dsint)), this, SLOT(decompileAt(dsint, dsint)));
connect(mGraphView, SIGNAL(displaySnowmanWidget()), this, SLOT(displaySnowmanWidget()));
connect(mCpuWidget->getDumpWidget(), SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget()));
@ -1545,11 +1547,6 @@ void MainWindow::displayManual()
SimpleErrorBox(this, tr("Error"), tr("Manual cannot be opened. Please check if x64dbg.chm exists and ensure there is no other problems with your system."));
}
void MainWindow::decompileAt(dsint start, dsint end)
{
DecompileAt(mSnowmanView, start, end);
}
void MainWindow::canClose()
{
bCanClose = true;

View File

@ -25,7 +25,6 @@ class DebugStatusLabel;
class LogStatusLabel;
class UpdateChecker;
class SourceViewerManager;
class SnowmanView;
class HandlesView;
class MainWindowCloseThread;
class TimeWastedCounter;
@ -133,7 +132,6 @@ public slots:
void displayAttach();
void changeCommandLine();
void displayManual();
void decompileAt(dsint start, dsint end);
void canClose();
void addQWidgetTab(QWidget* qWidget, QString nativeName);
void addQWidgetTab(QWidget* qWidget);
@ -172,7 +170,7 @@ private:
ThreadView* mThreadView;
PatchDialog* mPatchDialog;
CalculatorDialog* mCalculatorDialog;
SnowmanView* mSnowmanView;
QWidget* mSnowmanView;
HandlesView* mHandlesView;
NotesManager* mNotesManager;
DisassemblerGraphView* mGraphView;

View File

@ -3,13 +3,15 @@
#include <QWidget>
class SnowmanView : public QWidget
struct SnowmanRange
{
Q_OBJECT
duint start;
duint end;
};
extern "C" __declspec(dllexport) SnowmanView* CreateSnowman(QWidget* parent);
extern "C" __declspec(dllexport) void DecompileAt(SnowmanView* snowman, dsint start, dsint end);
extern "C" __declspec(dllexport) void CloseSnowman(SnowmanView* snowman);
extern "C" __declspec(dllimport) QWidget* CreateSnowman(QWidget* parent);
extern "C" __declspec(dllimport) void DecompileAt(QWidget* snowman, dsint start, dsint end);
extern "C" __declspec(dllimport) void DecompileRanges(QWidget* snowman, const SnowmanRange* ranges, duint count);
extern "C" __declspec(dllimport) void CloseSnowman(QWidget* snowman);
#endif // SNOWMANVIEW_H

View File

@ -502,6 +502,7 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
defaultShortcuts.insert("ActionGraphSaveImage", Shortcut(tr("Actions -> Graph -> Save as image"), "I"));
defaultShortcuts.insert("ActionGraphToggleOverview", Shortcut(tr("Actions -> Graph -> Toggle overview"), "O"));
defaultShortcuts.insert("ActionGraphSyncOrigin", Shortcut(tr("Actions -> Graph -> Toggle sync with origin"), "S"));
defaultShortcuts.insert("ActionGraphDecompile", Shortcut(tr("Actions -> Graph -> Decompile"), "Tab"));
defaultShortcuts.insert("ActionIncrementx87Stack", Shortcut(tr("Actions -> Increment x87 Stack")));
defaultShortcuts.insert("ActionDecrementx87Stack", Shortcut(tr("Actions -> Decrement x87 Stack")));
defaultShortcuts.insert("ActionPush", Shortcut(tr("Actions -> Push")));