1
0
Fork 0

prototype of #890 (preview call or jump destination) (#910)

* prototype of #890 (preview call or jump destination

* resolve issue with call dword ptr ds:[MessageBoxA]

* tidy up headers

* hide tooltip when mouse is outside disassembly view
This commit is contained in:
Torusrxxx 2016-08-04 11:16:52 +00:00 committed by Duncan Ogilvie
parent 376d59185b
commit 1a10ded9a3
76 changed files with 567 additions and 169 deletions

View File

@ -25,7 +25,7 @@ void stackupdateseh()
if(ExHandlerGetSEH(SEHList))
{
STACK_COMMENT comment;
strcpy_s(comment.color, "#AE81FF"); //TODO: customize this color
strcpy_s(comment.color, "!sehclr"); // Special token for SEH chain color.
auto count = SEHList.size();
for(duint i = 0; i < count; i++)
{
@ -104,7 +104,7 @@ bool stackcommentget(duint addr, STACK_COMMENT* comment)
}
else
sprintf_s(comment->comment, "return to %s from ???", returnToAddr);
strcpy_s(comment->color, "#ff0000"); //TODO: customize this color
strcpy_s(comment->color, "!rtnclr"); // Special token for return address color;
return true;
}

View File

@ -1,4 +1,5 @@
#pragma once
#ifndef _DBG_TYPES_H_
#define _DBG_TYPES_H_
/***************************************************************/
//
@ -38,4 +39,5 @@ typedef unsigned int uint32;
typedef long long int64;
typedef unsigned long long uint64;
typedef unsigned char byte_t;
typedef unsigned char byte_t;
#endif //_DBG_TYPES_H_

View File

@ -2,6 +2,25 @@
#include <QStyleOptionButton>
#include "Configuration.h"
#include "ColumnReorderDialog.h"
#include "CachedFontMetrics.h"
AbstractTableScrollBar::AbstractTableScrollBar(QScrollBar* scrollbar)
{
setOrientation(scrollbar->orientation());
setParent(scrollbar->parentWidget());
}
void AbstractTableScrollBar::enterEvent(QEvent* event)
{
Q_UNUSED(event);
QApplication::setOverrideCursor(Qt::ArrowCursor);
}
void AbstractTableScrollBar::leaveEvent(QEvent* event)
{
Q_UNUSED(event);
QApplication::restoreOverrideCursor();
}
AbstractTableView::AbstractTableView(QWidget* parent)
: QAbstractScrollArea(parent),

View File

@ -12,31 +12,18 @@
#include "Configuration.h"
#include "MenuBuilder.h"
#include "QActionLambda.h"
#include "CachedFontMetrics.h"
#include "MiscUtil.h"
class CachedFontMetrics;
//Hacky class that fixes a really annoying cursor problem
class AbstractTableScrollBar : public QScrollBar
{
Q_OBJECT
public:
AbstractTableScrollBar(QScrollBar* scrollbar)
{
setOrientation(scrollbar->orientation());
setParent(scrollbar->parentWidget());
}
void enterEvent(QEvent* event)
{
Q_UNUSED(event);
QApplication::setOverrideCursor(Qt::ArrowCursor);
}
void leaveEvent(QEvent* event)
{
Q_UNUSED(event);
QApplication::restoreOverrideCursor();
}
AbstractTableScrollBar(QScrollBar* scrollbar);
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
};
class AbstractTableView : public QAbstractScrollArea

View File

@ -2,8 +2,10 @@
#include "Configuration.h"
#include "Bridge.h"
#include "MainWindow.h"
#include "QBeaEngine.h"
#include "MemoryPage.h"
Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent)
Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent), mDisassemblyPopup(this)
{
mMemPage = new MemoryPage(0, 0);
@ -28,6 +30,8 @@ Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent)
mDisasm = new QBeaEngine(maxModuleSize);
mDisasm->UpdateConfig();
mCodeFoldingManager = nullptr;
mPopupEnabled = true;
mIsLastInstDisplayed = false;
mGuiState = Disassembly::NoState;
@ -406,7 +410,8 @@ QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffse
funcsize += charwidth;
//draw jump arrows
int jumpsize = paintJumpsGraphic(painter, x + funcsize, y - 1, wRVA, mInstBuffer.at(rowOffset).branchType != Instruction_t::BranchType::None); //jump line
Instruction_t::BranchType branchType = mInstBuffer.at(rowOffset).branchType;
int jumpsize = paintJumpsGraphic(painter, x + funcsize, y - 1, wRVA, branchType != Instruction_t::None && branchType != Instruction_t::Call); //jump line
//draw bytes
RichTextPainter::List richBytes;
@ -635,6 +640,32 @@ void Disassembly::mouseMoveEvent(QMouseEvent* event)
}
}
}
else if(mGuiState == Disassembly::NoState)
{
if(!mHighlightingMode && mPopupEnabled)
{
bool popupShown = false;
if(event->y() > getHeaderHeight() && getColumnIndexFromX(event->x()) == 2)
{
int rowOffset = getIndexOffsetFromY(transY(event->y()));
if(rowOffset < mInstBuffer.size())
{
auto & instruction = mInstBuffer[rowOffset];
if(instruction.branchType != Instruction_t::None)
{
duint addr = instruction.branchDestination;
if(addr != 0 && (addr - mMemPage->getBase() < mInstBuffer.front().rva || addr - mMemPage->getBase() > mInstBuffer.back().rva))
{
ShowDisassemblyPopup(addr, event->x(), event->y());
popupShown = true;
}
}
}
}
if(popupShown == false)
ShowDisassemblyPopup(0, 0, 0); // hide popup
}
}
if(wAccept == true)
AbstractTableView::mouseMoveEvent(event);
@ -748,6 +779,12 @@ void Disassembly::mouseReleaseEvent(QMouseEvent* event)
AbstractTableView::mouseReleaseEvent(event);
}
void Disassembly::leaveEvent(QEvent* event)
{
Q_UNUSED(event);
ShowDisassemblyPopup(0, 0, 0);
}
/************************************************************************************
Keyboard Management
************************************************************************************/
@ -869,7 +906,7 @@ int Disassembly::paintJumpsGraphic(QPainter* painter, int x, int y, dsint addr,
GraphicDump_t wPict = GD_Nothing;
if(branchType != Instruction_t::None)
if(branchType != Instruction_t::None && branchType != Instruction_t::Call)
{
dsint base = mMemPage->getBase();
dsint destVA = DbgGetBranchDestination(rvaToVa(selHeadRVA));
@ -1217,24 +1254,34 @@ dsint Disassembly::getPreviousInstructionRVA(dsint rva, duint count)
*
* @param[in] rva Instruction RVA
* @param[in] count Instruction count
* @param[in] isGlobal Whether it rejects rva beyond current page
*
* @return RVA of count-th instructions after the given instruction RVA.
*/
dsint Disassembly::getNextInstructionRVA(dsint rva, duint count)
dsint Disassembly::getNextInstructionRVA(dsint rva, duint count, bool isGlobal)
{
QByteArray wBuffer;
dsint wRemainingBytes;
dsint wMaxByteCountToRead;
dsint wNewRVA;
if(mMemPage->getSize() < (duint)rva)
return rva;
wRemainingBytes = mMemPage->getSize() - rva;
if(!isGlobal)
{
if(mMemPage->getSize() < (duint)rva)
return rva;
wRemainingBytes = mMemPage->getSize() - rva;
wMaxByteCountToRead = 16 * (count + 1);
if(mCodeFoldingManager)
wMaxByteCountToRead += mCodeFoldingManager->getFoldedSize(rvaToVa(rva), rvaToVa(rva + wMaxByteCountToRead));
wMaxByteCountToRead = wRemainingBytes > wMaxByteCountToRead ? wMaxByteCountToRead : wRemainingBytes;
wMaxByteCountToRead = 16 * (count + 1);
if(mCodeFoldingManager)
wMaxByteCountToRead += mCodeFoldingManager->getFoldedSize(rvaToVa(rva), rvaToVa(rva + wMaxByteCountToRead));
wMaxByteCountToRead = wRemainingBytes > wMaxByteCountToRead ? wMaxByteCountToRead : wRemainingBytes;
}
else
{
wMaxByteCountToRead = 16 * (count + 1);
if(mCodeFoldingManager)
wMaxByteCountToRead += mCodeFoldingManager->getFoldedSize(rvaToVa(rva), rvaToVa(rva + wMaxByteCountToRead));
}
wBuffer.resize(wMaxByteCountToRead);
mMemPage->read(wBuffer.data(), rva, wBuffer.size());
@ -1860,3 +1907,18 @@ void Disassembly::unfold(dsint rva)
viewport()->update();
}
}
void Disassembly::ShowDisassemblyPopup(duint addr, int x, int y)
{
if(mDisassemblyPopup.getAddress() == addr)
return;
if(DbgMemIsValidReadPtr(addr))
{
mDisassemblyPopup.move(mapToGlobal(QPoint(x + 20, y + mFontMetrics->height() * 2)));
mDisassemblyPopup.setAddress(addr);
mDisassemblyPopup.show();
}
else
mDisassemblyPopup.hide();
}

View File

@ -2,9 +2,11 @@
#define DISASSEMBLY_H
#include "AbstractTableView.h"
#include "QBeaEngine.h"
#include "MemoryPage.h"
#include "CodeFolding.h"
#include "DisassemblyPopup.h"
class CodeFoldingHelper;
class QBeaEngine;
class MemoryPage;
class Disassembly : public AbstractTableView
{
@ -24,6 +26,7 @@ public:
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void leaveEvent(QEvent* event) override;
// Keyboard Management
void keyPressEvent(QKeyEvent* event);
@ -50,7 +53,7 @@ public:
// Instructions Management
dsint getPreviousInstructionRVA(dsint rva, duint count);
dsint getNextInstructionRVA(dsint rva, duint count);
dsint getNextInstructionRVA(dsint rva, duint count, bool isGlobal = false);
dsint getInstructionRVA(dsint index, dsint count);
Instruction_t DisassembleAt(dsint rva);
Instruction_t DisassembleAt(dsint rva, dsint count);
@ -100,6 +103,7 @@ public:
//misc
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
void unfold(dsint rva);
void ShowDisassemblyPopup(duint addr, int x, int y);
signals:
void selectionChanged(dsint parVA);
@ -203,11 +207,13 @@ protected:
duint mRvaDisplayBase;
dsint mRvaDisplayPageBase;
bool mHighlightingMode;
bool mPopupEnabled;
MemoryPage* mMemPage;
QBeaEngine* mDisasm;
bool mShowMnemonicBrief;
XREF_INFO mXrefInfo;
CodeFoldingHelper* mCodeFoldingManager;
DisassemblyPopup mDisassemblyPopup;
};
#endif // DISASSEMBLY_H

View File

@ -152,7 +152,7 @@ ulong QBeaEngine::DisassembleNext(byte_t* data, duint base, duint size, duint ip
}
else
{
if(!cp.DisassembleSafe(0, pdata, (int)size))
if(!cp.DisassembleSafe(ip + base, pdata, (int)size))
cmdsize = 1;
else
cmdsize = cp.Size();
@ -198,7 +198,7 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
return DecodeDataAt(data, size, origBase, origInstRVA, type);
auto branchType = Instruction_t::None;
if(success && (cp.InGroup(CS_GRP_JUMP) || cp.IsLoop()))
if(success && (cp.InGroup(CS_GRP_JUMP) || cp.IsLoop() || cp.InGroup(CS_GRP_CALL)))
{
switch(cp.GetId())
{
@ -206,6 +206,10 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
case X86_INS_LJMP:
branchType = Instruction_t::Unconditional;
break;
case X86_INS_CALL:
case X86_INS_LCALL:
branchType = Instruction_t::Call;
break;
default:
branchType = Instruction_t::Conditional;
break;
@ -221,7 +225,7 @@ Instruction_t QBeaEngine::DisassembleAt(byte_t* data, duint size, duint origBase
else
wInst.length = len;
wInst.branchType = branchType;
wInst.branchDestination = cp.BranchDestination();
wInst.branchDestination = DbgGetBranchDestination(origBase + origInstRVA);
wInst.tokens = cap;
return wInst;

View File

@ -13,7 +13,8 @@ struct Instruction_t
{
None,
Conditional,
Unconditional
Unconditional,
Call
};
Instruction_t()

View File

@ -1,6 +1,7 @@
#include "capstone_gui.h"
#include "Configuration.h"
#include "StringUtil.h"
#include "CachedFontMetrics.h"
CapstoneTokenizer::CapstoneTokenizer(int maxModuleLength)
: _maxModuleLength(maxModuleLength),
@ -451,9 +452,7 @@ bool CapstoneTokenizer::tokenizeImmOperand(const cs_x86_op & op)
duint value = duint(op.imm);
auto valueType = TokenType::Value;
if(_cp.InGroup(CS_GRP_JUMP) || _cp.InGroup(CS_GRP_CALL) || _cp.IsLoop())
{
valueType = TokenType::Address;
}
auto tokenValue = TokenValue(op.size, value);
addToken(valueType, printValue(tokenValue, true, _maxModuleLength), tokenValue);
return true;

View File

@ -518,6 +518,8 @@ void AppearanceDialog::colorInfoListInit()
colorInfoListAppend(tr("Addresses"), "StackAddressColor", "StackAddressBackgroundColor");
colorInfoListAppend(tr("Selected Addresses"), "StackSelectedAddressColor", "StackSelectedAddressBackgroundColor");
colorInfoListAppend(tr("Labels"), "StackLabelColor", "StackLabelBackgroundColor");
colorInfoListAppend(tr("Return To Comment"), "StackReturnToColor", "");
colorInfoListAppend(tr("SEH Chain Comment"), "StackSEHChainColor", "");
colorInfoListAppend(tr("User Stack Frame Line"), "StackFrameColor", "");
colorInfoListAppend(tr("System Stack Frame Line"), "StackFrameSystemColor", "");

View File

@ -2,7 +2,10 @@
#define ATTACHDIALOG_H
#include <QDialog>
#include "SearchListView.h"
class SearchListView;
class QMenu;
class QAction;
namespace Ui
{

View File

@ -3,6 +3,7 @@
#include "Bridge.h"
#include "Breakpoints.h"
#include "LineEditDialog.h"
#include "StdTable.h"
BreakpointsView::BreakpointsView(QWidget* parent) : QWidget(parent)
{

View File

@ -4,7 +4,9 @@
#include <QWidget>
#include <QVBoxLayout>
#include <QSplitter>
#include "StdTable.h"
#include "Imports.h"
class StdTable;
class BreakpointsView : public QWidget
{

View File

@ -1,18 +1,23 @@
#include "CPUDisassembly.h"
#include "CPUSideBar.h"
#include "CPUWidget.h"
#include "CPUMultiDump.h"
#include <QMessageBox>
#include <QDesktopServices>
#include <QClipboard>
#include "Configuration.h"
#include "Bridge.h"
#include "Imports.h"
#include "LineEditDialog.h"
#include "WordEditDialog.h"
#include "GotoDialog.h"
#include "HexEditDialog.h"
#include "YaraRuleSelectionDialog.h"
#include "AssembleDialog.h"
#include "StringUtil.h"
#include "Breakpoints.h"
#include "XrefBrowseDialog.h"
#include "SourceViewerManager.h"
#include "MiscUtil.h"
CPUDisassembly::CPUDisassembly(CPUWidget* parent) : Disassembly(parent)
@ -350,7 +355,12 @@ void CPUDisassembly::setupRightClickContextMenu()
});
mMenuBuilder->addAction(makeShortcutAction(DIcon("highlight.png"), tr("&Highlighting mode"), SLOT(enableHighlightingModeSlot()), "ActionHighlightingMode"));
mMenuBuilder->addSeparator();
QAction* togglePreview = makeShortcutAction(tr("Disable Branch Destination Preview"), SLOT(togglePreviewSlot()), "ActionToggleDestinationPreview");
mMenuBuilder->addAction(togglePreview, [this, togglePreview](QMenu*)
{
togglePreview->setText(mPopupEnabled ? tr("Disable Branch Destination Preview") : tr("Enable Branch Destination Preview"));
return true;
});
MenuBuilder* labelMenu = new MenuBuilder(this);
labelMenu->addAction(makeShortcutAction(tr("Label Current Address"), SLOT(setLabelSlot()), "ActionSetLabel"));
@ -1660,3 +1670,10 @@ void CPUDisassembly::graphSlot()
DbgCmdExecDirect(QString("graph %1").arg(ToPtrString(rvaToVa(getSelectionStart()))).toUtf8().constData());
emit displayGraphWidget();
}
void CPUDisassembly::togglePreviewSlot()
{
if(mPopupEnabled == true)
ShowDisassemblyPopup(0, 0, 0);
mPopupEnabled = !mPopupEnabled;
}

View File

@ -2,11 +2,10 @@
#define CPUDISASSEMBLY_H
#include "Disassembly.h"
#include "GotoDialog.h"
#include "SourceViewerManager.h"
// Needed forward declaration for parent container class
class CPUWidget;
class GotoDialog;
class CPUDisassembly : public Disassembly
{
@ -104,6 +103,7 @@ public slots:
void setEncodeTypeSlot();
void setEncodeTypeRangeSlot();
void graphSlot();
void togglePreviewSlot();
protected:
void paintEvent(QPaintEvent* event);

View File

@ -2,6 +2,7 @@
#include <QMessageBox>
#include <QClipboard>
#include <QFileDialog>
#include <QToolTip>
#include "Configuration.h"
#include "Bridge.h"
#include "LineEditDialog.h"
@ -10,9 +11,10 @@
#include "DataCopyDialog.h"
#include "EntropyDialog.h"
#include "CPUMultiDump.h"
#include "GotoDialog.h"
#include "CPUDisassembly.h"
#include "WordEditDialog.h"
#include "CodepageSelectionDialog.h"
#include <QToolTip>
#include "MiscUtil.h"
CPUDump::CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent) : HexDump(parent)

View File

@ -2,11 +2,11 @@
#define CPUDUMP_H
#include "HexDump.h"
#include "GotoDialog.h"
#include "CPUDisassembly.h"
//forward declaration
class CPUMultiDump;
class CPUDisassembly;
class GotoDialog;
class CPUDump : public HexDump
{

View File

@ -2,7 +2,6 @@
#define INFOBOX_H
#include "StdTable.h"
#include <QAction>
class CPUInfoBox : public StdTable
{

View File

@ -118,7 +118,7 @@ bool CPUSideBar::isJump(int i) const
{
const Instruction_t & instr = mInstrBuffer->at(i);
Instruction_t::BranchType branchType = instr.branchType;
if(branchType != Instruction_t::None)
if(branchType == Instruction_t::Unconditional || branchType == Instruction_t::Conditional)
{
duint start = mDisas->getBase();
duint end = start + mDisas->getSize();

View File

@ -6,6 +6,7 @@
#include "HexEditDialog.h"
#include "WordEditDialog.h"
#include "CPUMultiDump.h"
#include "GotoDialog.h"
CPUStack::CPUStack(CPUMultiDump* multiDump, QWidget* parent) : HexDump(parent)
{
@ -59,6 +60,8 @@ void CPUStack::updateColors()
backgroundColor = ConfigColor("StackBackgroundColor");
textColor = ConfigColor("StackTextColor");
selectionColor = ConfigColor("StackSelectionColor");
mStackReturnToColor = ConfigColor("StackReturnToColor");
mStackSEHChainColor = ConfigColor("StackSEHChainColor");
mUserStackFrameColor = ConfigColor("StackFrameColor");
mSystemStackFrameColor = ConfigColor("StackFrameSystemColor");
}
@ -366,7 +369,19 @@ void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & ric
if(wActiveStack)
{
if(*comment.color)
curData.textColor = QColor(QString(comment.color));
{
if(comment.color[0] == '!')
{
if(strcmp(comment.color, "!sehclr") == 0)
curData.textColor = QColor("#AE81FF");
else if(strcmp(comment.color, "!rtnclr") == 0)
curData.textColor = QColor("#FF0000");
else
curData.textColor = textColor;
}
else
curData.textColor = QColor(QString(comment.color));
}
else
curData.textColor = textColor;
}

View File

@ -2,10 +2,10 @@
#define CPUSTACK_H
#include "HexDump.h"
#include "GotoDialog.h"
//forward declaration
class CPUMultiDump;
class GotoDialog;
class CPUStack : public HexDump
{
@ -132,6 +132,8 @@ private:
CPUMultiDump* mMultiDump;
QColor mUserStackFrameColor;
QColor mSystemStackFrameColor;
QColor mStackReturnToColor;
QColor mStackSEHChainColor;
struct CPUCallStack
{
duint addr;

View File

@ -1,5 +1,14 @@
#include "CPUWidget.h"
#include "ui_CPUWidget.h"
#include <QTabWidget>
#include <QVBoxLayout>
#include "CPUSideBar.h"
#include "CPUDisassembly.h"
#include "CPUMultiDump.h"
#include "CPUStack.h"
#include "RegistersView.h"
#include "CPUInfoBox.h"
#include "CPUArgumentWidget.h"
#include "Configuration.h"
CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)

View File

@ -2,15 +2,15 @@
#define CPUWIDGET_H
#include <QWidget>
#include <QTabWidget>
#include <QVBoxLayout>
#include "CPUSideBar.h"
#include "CPUDisassembly.h"
#include "CPUMultiDump.h"
#include "CPUStack.h"
#include "RegistersView.h"
#include "CPUInfoBox.h"
#include "CPUArgumentWidget.h"
class QVBoxLayout;
class CPUSideBar;
class CPUDisassembly;
class CPUMultiDump;
class CPUStack;
class RegistersView;
class CPUInfoBox;
class CPUArgumentWidget;
namespace Ui
{

View File

@ -1,5 +1,6 @@
#include "CalculatorDialog.h"
#include "ui_CalculatorDialog.h"
#include "ValidateExpressionThread.h"
CalculatorDialog::CalculatorDialog(QWidget* parent) : QDialog(parent), ui(new Ui::CalculatorDialog)
{

View File

@ -2,9 +2,10 @@
#define CALCULATORDIALOG_H
#include <QDialog>
#include "ValidateExpressionThread.h"
#include "Imports.h"
class ValidateExpressionThread;
namespace Ui
{
class CalculatorDialog;

View File

@ -1,6 +1,7 @@
#include "CloseDialog.h"
#include "ui_CloseDialog.h"
#include "MiscUtil.h"
#include <QCloseEvent>
CloseDialog::CloseDialog(QWidget* parent) : QDialog(parent), ui(new Ui::CloseDialog)
{

View File

@ -2,7 +2,8 @@
#define CLOSEDIALOG_H
#include <QDialog>
#include <QCloseEvent>
class QCloseEvent;
namespace Ui
{

View File

@ -1,5 +1,6 @@
#include "ColumnReorderDialog.h"
#include "ui_ColumnReorderDialog.h"
#include "AbstractTableView.h"
#include <QMessageBox>
ColumnReorderDialog::ColumnReorderDialog(AbstractTableView* parent) :

View File

@ -1,9 +1,10 @@
#ifndef COLUMNREORDERDIALOG_H
#define COLUMNREORDERDIALOG_H
#include "AbstractTableView.h"
#include <QDialog>
class AbstractTableView;
namespace Ui
{
class ColumnReorderDialog;

View File

@ -1,5 +1,7 @@
#include <QVBoxLayout>
#include "CommandHelpView.h"
#include "ui_CommandHelpView.h"
#include "SearchListView.h"
CommandHelpView::CommandHelpView(QWidget* parent) : QWidget(parent), ui(new Ui::CommandHelpView)
{

View File

@ -2,8 +2,10 @@
#define COMMANDHELPVIEW_H
#include <QWidget>
#include <QVBoxLayout>
#include "SearchListView.h"
class QVBoxLayout;
class SearchListView;
class StdTable;
namespace Ui
{

View File

@ -0,0 +1,143 @@
#include "DisassemblyPopup.h"
#include "Disassembly.h"
#include "Configuration.h"
#include "StringUtil.h"
#include <QPainter>
DisassemblyPopup::DisassemblyPopup(Disassembly* parent) :
QFrame(parent, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus),
parent(parent),
mFontMetrics(nullptr)
{
addr = 0;
addrText = nullptr;
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateFont()));
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateColors()));
updateFont();
updateColors();
setFrameStyle(QFrame::Panel);
mMaxInstructions = 20;
}
DisassemblyPopup::~DisassemblyPopup()
{
}
void DisassemblyPopup::updateColors()
{
disassemblyBackgroundColor = ConfigColor("DisassemblyBackgroundColor");
labelColor = ConfigColor("DisassemblyLabelColor");
labelBackgroundColor = ConfigColor("DisassemblyLabelBackgroundColor");
commentColor = ConfigColor("DisassemblyCommentColor");
commentBackgroundColor = ConfigColor("DisassemblyCommentBackgroundColor");
commentAutoColor = ConfigColor("DisassemblyAutoCommentColor");
commentAutoBackgroundColor = ConfigColor("DisassemblyAutoCommentBackgroundColor");
}
void DisassemblyPopup::updateFont()
{
delete mFontMetrics;
setFont(ConfigFont("Disassembly"));
QFontMetricsF metrics(font());
mFontMetrics = new CachedFontMetrics(this, font());
// Update font size, used in layout calculations.
charWidth = mFontMetrics->width('W');
charHeight = metrics.height();
}
void DisassemblyPopup::paintEvent(QPaintEvent* event)
{
QRect viewportRect(0, 0, width(), height());
QPainter p(this);
p.setFont(font());
// Render background
p.fillRect(viewportRect, disassemblyBackgroundColor);
// Draw Address
p.setPen(QPen(labelColor));
int addrWidth = mFontMetrics->width(addrText);
p.fillRect(2, 1, addrWidth, charHeight, QBrush(labelBackgroundColor));
p.drawText(2, 1, addrWidth, charHeight, 0, addrText);
// Draw Comments
if(!addrComment.isEmpty())
{
int commentWidth = mFontMetrics->width(addrComment);
QBrush background = QBrush(addrCommentAuto ? commentAutoBackgroundColor : commentBackgroundColor);
p.setPen(addrCommentAuto ? commentAutoColor : commentColor);
p.fillRect(2 + addrWidth, 1, commentWidth, charHeight, background);
p.drawText(2 + addrWidth, 1, commentWidth, charHeight, 0, addrComment);
}
// Draw Instructions
int y = charHeight + 1;
for(auto & instruction : mDisassemblyToken)
{
RichTextPainter::paintRichText(&p, 2, y, mWidth - 2, charHeight, 0, instruction, mFontMetrics);
y += charHeight;
}
QFrame::paintEvent(event);
}
void DisassemblyPopup::setAddress(duint Address)
{
addr = Address;
mInstBuffer.clear();
mDisassemblyToken.clear();
if(addr != 0)
{
mWidth = 1;
// Get RVA
dsint rva = Address - parent->getBase();
// Prepare RVA of every instruction
unsigned int i = 0;
mInstBuffer.clear();
QList<dsint> rvaList;
dsint nextRva = rva;
do
{
dsint nextRva2;
rvaList.append(nextRva);
nextRva2 = parent->getNextInstructionRVA(nextRva, 1, true);
if(nextRva2 == nextRva)
break;
else
nextRva = nextRva2;
i++;
}
while(i < mMaxInstructions);
// Disassemble
parent->prepareDataCount(rvaList, &mInstBuffer);
for(auto & instruction : mInstBuffer)
{
RichTextPainter::List richText;
CapstoneTokenizer::TokenToRichText(instruction.tokens, richText, nullptr);
// Calculate width
int currentInstructionWidth = 0;
for(auto & token : richText)
currentInstructionWidth += mFontMetrics->width(token.text);
mWidth = std::max(mWidth, currentInstructionWidth);
mDisassemblyToken.push_back(std::move(richText));
}
// Address
addrText = parent->getAddrText(addr, nullptr);
// Comments
GetCommentFormat(addr, addrComment, &addrCommentAuto);
// Calculate width of address
mWidth = std::max(mWidth, mFontMetrics->width(addrText) + mFontMetrics->width(addrComment));
mWidth += charWidth * 6;
// Resize popup
resize(mWidth + 2, charHeight * int(mDisassemblyToken.size() + 1) + 2);
}
update();
}
duint DisassemblyPopup::getAddress()
{
return addr;
}
void DisassemblyPopup::hide()
{
addr = 0;
QFrame::hide();
}

View File

@ -0,0 +1,48 @@
#ifndef DISASSEMBLYPOPUP_H
#define DISASSEMBLYPOPUP_H
#include <QFrame>
#include "Imports.h"
#include "RichTextPainter.h"
#include "CachedFontMetrics.h"
#include "QBeaEngine.h"
class Disassembly;
class DisassemblyPopup : public QFrame
{
Q_OBJECT
public:
explicit DisassemblyPopup(Disassembly* parent);
~DisassemblyPopup();
void paintEvent(QPaintEvent* event);
void setAddress(duint Address);
duint getAddress();
public slots:
void hide();
void updateFont();
void updateColors();
protected:
Disassembly* parent;
CachedFontMetrics* mFontMetrics;
duint addr;
QString addrText;
QString addrComment;
bool addrCommentAuto;
int charWidth;
int charHeight;
int mWidth;
unsigned int mMaxInstructions;
QColor disassemblyBackgroundColor;
QColor labelColor;
QColor labelBackgroundColor;
QColor commentColor;
QColor commentBackgroundColor;
QColor commentAutoColor;
QColor commentAutoBackgroundColor;
QList<Instruction_t> mInstBuffer;
std::vector<RichTextPainter::List> mDisassemblyToken;
};
#endif // DISASSEMBLYPOPUP_H

View File

@ -6,6 +6,7 @@
#include <QFileDialog>
#include <QMessageBox>
#include "MiscUtil.h"
#include <QTableWidget>
FavouriteTools::FavouriteTools(QWidget* parent) :
QDialog(parent),

View File

@ -2,7 +2,8 @@
#define FAVOURITETOOLS_H
#include <QDialog>
#include <QTableWidget>
class QTableWidget;
namespace Ui
{

View File

@ -1,6 +1,9 @@
#include "HandlesView.h"
#include "Bridge.h"
#include "VersionHelpers.h"
#include "StdTable.h"
#include <QVBoxLayout>
#include <QSplitter>
HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
{

View File

@ -1,9 +1,12 @@
#ifndef HANDLESVIEW_H
#define HANDLESVIEW_H
#include "StdTable.h"
#include <QVBoxLayout>
#include <QSplitter>
#include <QWidget>
#include "Imports.h"
class StdTable;
class QVBoxLayout;
class QSplitter;
class HandlesView : public QWidget
{

View File

@ -1,3 +1,4 @@
#include <QTextCodec>
#include "HexEditDialog.h"
#include "ui_HexEditDialog.h"
#include "Configuration.h"

View File

@ -1,5 +1,5 @@
#include <QTextCodec>
#include "Configuration.h"
#include "HexLineEdit.h"
#include "ui_HexLineEdit.h"
#include "Bridge.h"

View File

@ -2,7 +2,6 @@
#define HEXLINEEDITT_H
#include <QLineEdit>
#include "Configuration.h"
namespace Ui
{

View File

@ -15,6 +15,35 @@
#include "StringUtil.h"
#include "MiscUtil.h"
#include "FavouriteTools.h"
#include "CPUDisassembly.h"
#include "CloseDialog.h"
#include "CommandLineEdit.h"
#include "TabWidget.h"
#include "CPUWidget.h"
#include "MemoryMapView.h"
#include "CallStackView.h"
#include "SEHChainView.h"
#include "LogView.h"
#include "SymbolView.h"
#include "BreakpointsView.h"
#include "ScriptView.h"
#include "ReferenceManager.h"
#include "ThreadView.h"
#include "PatchDialog.h"
#include "CalculatorDialog.h"
#include "StatusLabel.h"
#include "UpdateChecker.h"
#include "SourceViewerManager.h"
#include "SnowmanView.h"
#include "HandlesView.h"
#include "MainWindowCloseThread.h"
#include "TimeWastedCounter.h"
#include "NotesManager.h"
#include "SettingsDialog.h"
#include "DisassemblerGraphView.h"
#include "CPUMultiDump.h"
#include "CPUStack.h"
#include "GotoDialog.h"
#include "main.h"
QString MainWindow::windowTitle = "";

View File

@ -2,33 +2,35 @@
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDragEnterEvent>
#include <QComboBox>
#include "CloseDialog.h"
#include "CommandLineEdit.h"
#include "TabWidget.h"
#include "CPUWidget.h"
#include "MemoryMapView.h"
#include "CallStackView.h"
#include "SEHChainView.h"
#include "LogView.h"
#include "SymbolView.h"
#include "BreakpointsView.h"
#include "ScriptView.h"
#include "ReferenceManager.h"
#include "ThreadView.h"
#include "PatchDialog.h"
#include "CalculatorDialog.h"
#include "StatusLabel.h"
#include "UpdateChecker.h"
#include "SourceViewerManager.h"
#include "SnowmanView.h"
#include "HandlesView.h"
#include "MainWindowCloseThread.h"
#include "TimeWastedCounter.h"
#include "NotesManager.h"
#include "SettingsDialog.h"
#include "DisassemblerGraphView.h"
#include "Imports.h"
class QDragEnterEvent;
class QDropEvent;
class CloseDialog;
class CommandLineEdit;
class MHTabWidget;
class CPUWidget;
class MemoryMapView;
class CallStackView;
class SEHChainView;
class LogView;
class SymbolView;
class BreakpointsView;
class ScriptView;
class ReferenceManager;
class ThreadView;
class PatchDialog;
class CalculatorDialog;
class StatusLabel;
class UpdateChecker;
class SourceViewerManager;
class SnowmanView;
class HandlesView;
class MainWindowCloseThread;
class TimeWastedCounter;
class NotesManager;
class SettingsDialog;
class DisassemblerGraphView;
namespace Ui
{

View File

@ -1,5 +1,6 @@
#include <QClipboard>
#include <QMessageBox>
#include <QListWidget>
#include <stdint.h>
#include "RegistersView.h"
#include "Configuration.h"

View File

@ -2,7 +2,8 @@
#define SELECTFIELDS_H
#include <QDialog>
#include <QListWidget>
class QListWidget;
namespace Ui
{

View File

@ -6,6 +6,7 @@
#include "YaraRuleSelectionDialog.h"
#include "EntropyDialog.h"
#include "LineEditDialog.h"
#include <QVBoxLayout>
SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView)
{

View File

@ -2,9 +2,13 @@
#define SYMBOLVIEW_H
#include <QWidget>
#include <QVBoxLayout>
//#include <QVBoxLayout>
#include "Bridge.h"
class QMenu;
class SearchListView;
class QVBoxLayout;
namespace Ui
{
class SymbolView;

View File

@ -7,6 +7,7 @@
#include <QPaintDevice>
#include <QDrag>
#include <QMimeData>
#include <QMenu>
#include "tabbar.h"
#include "tabwidget.h"

View File

@ -3,8 +3,6 @@
// Qt includes
#include <QTabBar>
#include <QMenu>
#include <QAction>
//////////////////////////////////////////////////////////////////////////////
// Summary:

View File

@ -1,6 +1,9 @@
// Qt includes
#include "tabbar.h"
#include "tabwidget.h"
#include <QMoveEvent>
#include <QApplication>
#include <QDesktopWidget>
//////////////////////////////////////////////////////////////
// Default Constructor

View File

@ -5,9 +5,6 @@
#include <QWidget>
#include <QTabWidget>
#include <QMainWindow>
#include <QMoveEvent>
#include <QApplication>
#include <QDesktopWidget>
#include "TabBar.h"
// Qt forward class definitions

View File

@ -1,5 +1,6 @@
#include "TimeWastedCounter.h"
#include "Bridge.h"
#include <QLabel>
TimeWastedCounter::TimeWastedCounter(QObject* parent, QLabel* label)
: QObject(parent), mLabel(label)

View File

@ -2,7 +2,8 @@
#define TIMEWASTEDCOUNTER_H
#include <QObject>
#include <QLabel>
class QLabel;
class TimeWastedCounter : public QObject
{

View File

@ -1,5 +1,6 @@
#include "WordEditDialog.h"
#include "ui_WordEditDialog.h"
#include "ValidateExpressionThread.h"
WordEditDialog::WordEditDialog(QWidget* parent)
: QDialog(parent),

View File

@ -3,9 +3,11 @@
#include <QDialog>
#include <QPushButton>
#include "ValidateExpressionThread.h"
//#include "ValidateExpressionThread.h"
#include "Imports.h"
class ValidateExpressionThread;
namespace Ui
{
class WordEditDialog;

View File

@ -1,8 +1,14 @@
#ifndef IMPORTS_H
#define IMPORTS_H
#ifndef _BRIDGEMAIN_H_
#include "bridge\bridgemain.h"
#endif
#ifndef _DBGFUNCTIONS_H
#include "dbg\_dbgfunctions.h"
#endif
#ifndef _DBG_TYPES_H_
#include "dbg_types.h"
#endif
#endif // IMPORTS_H

View File

@ -6,24 +6,24 @@ MemoryPage::MemoryPage(duint parBase, duint parSize, QObject* parent) : QObject(
Q_UNUSED(parSize);
}
bool MemoryPage::read(void* parDest, duint parRVA, duint parSize) const
bool MemoryPage::read(void* parDest, dsint parRVA, duint parSize) const
{
return DbgMemRead(mBase + parRVA, reinterpret_cast<unsigned char*>(parDest), parSize);
}
bool MemoryPage::read(byte_t* parDest, duint parRVA, duint parSize) const
bool MemoryPage::read(byte_t* parDest, dsint parRVA, duint parSize) const
{
return read(reinterpret_cast<void*>(parDest), parRVA, parSize);
}
bool MemoryPage::write(const void* parDest, duint parRVA, duint parSize)
bool MemoryPage::write(const void* parDest, dsint parRVA, duint parSize)
{
bool ret = DbgFunctions()->MemPatch(mBase + parRVA, reinterpret_cast<const unsigned char*>(parDest), parSize);
GuiUpdatePatches();
return ret;
}
bool MemoryPage::write(const byte_t* parDest, duint parRVA, duint parSize)
bool MemoryPage::write(const byte_t* parDest, dsint parRVA, duint parSize)
{
return write(reinterpret_cast<const void*>(parDest), parRVA, parSize);
}

View File

@ -10,10 +10,10 @@ class MemoryPage : public QObject
public:
explicit MemoryPage(duint parBase, duint parSize, QObject* parent = 0);
bool read(void* parDest, duint parRVA, duint parSize) const;
bool read(byte_t* parDest, duint parRVA, duint parSize) const;
bool write(const void* parDest, duint parRVA, duint parSize);
bool write(const byte_t* parDest, duint parRVA, duint parSize);
bool read(void* parDest, dsint parRVA, duint parSize) const;
bool read(byte_t* parDest, dsint parRVA, duint parSize) const;
bool write(const void* parDest, dsint parRVA, duint parSize);
bool write(const byte_t* parDest, dsint parRVA, duint parSize);
duint getSize() const;
duint getBase() const;
duint va(dsint rva) const;

View File

@ -2,7 +2,8 @@
#define QENTROPYVIEW_H
#include <QGraphicsView>
#include <QGraphicsScene>
class QGraphicsScene;
class QEntropyView : public QGraphicsView
{

View File

@ -1,4 +1,5 @@
#include "ArrayCommand.h"
#include "XByteArray.h"
CharCommand::CharCommand(XByteArray* xData, Cmd cmd, int charPos, char newChar, QUndoCommand* parent) : QUndoCommand(parent)
{

View File

@ -2,7 +2,9 @@
#define ARRAYCOMMAND_H
#include <QUndoCommand>
#include "XByteArray.h"
#include <QByteArray>
class XByteArray;
class CharCommand : public QUndoCommand
{

View File

@ -1,6 +1,7 @@
#include <QtGui>
#include "QHexEdit.h"
#include "QHexEditPrivate.h"
QHexEdit::QHexEdit(QWidget* parent) : QScrollArea(parent)
{

View File

@ -2,8 +2,8 @@
#define QHEXEDIT_H
#include <QScrollArea>
#include <QHBoxLayout>
#include "QHexEditPrivate.h"
class QHexEditPrivate;
class QHexEdit : public QScrollArea
{

View File

@ -5,6 +5,7 @@
#include <QScrollArea>
#include <QUndoStack>
#include <QKeyEvent>
#include <QTimer>
#include "XByteArray.h"
class QHexEditPrivate : public QWidget

View File

@ -9,7 +9,7 @@ QByteArray & XByteArray::data()
return _data;
}
void XByteArray::setData(QByteArray data)
void XByteArray::setData(const QByteArray & data)
{
_data = data;
}

View File

@ -1,7 +1,7 @@
#ifndef XBYTEARRAY_H
#define XBYTEARRAY_H
#include <QtCore>
#include <QByteArray>
class XByteArray
{
@ -9,7 +9,7 @@ public:
explicit XByteArray();
QByteArray & data();
void setData(QByteArray data);
void setData(const QByteArray & data);
int size();
QByteArray & insert(int i, char ch);
@ -21,10 +21,6 @@ public:
QByteArray & replace(int index, const QByteArray & ba);
QByteArray & replace(int index, int length, const QByteArray & ba);
signals:
public slots:
private:
QByteArray _data; //raw byte array
};

View File

@ -153,6 +153,8 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
defaultColors.insert("StackSelectedAddressBackgroundColor", Qt::transparent);
defaultColors.insert("StackLabelColor", QColor("#FF0000"));
defaultColors.insert("StackLabelBackgroundColor", Qt::transparent);
defaultColors.insert("StackReturnToColor", QColor("#FF0000"));
defaultColors.insert("StackSEHChainColor", QColor("#AE81FF"));
defaultColors.insert("StackFrameColor", QColor("#000000"));
defaultColors.insert("StackFrameSystemColor", QColor("#0000FF"));
@ -368,6 +370,7 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
defaultShortcuts.insert("ActionHelpOnMnemonic", Shortcut(tr("Actions -> Help on Mnemonic"), "Ctrl+F1"));
defaultShortcuts.insert("ActionToggleMnemonicBrief", Shortcut(tr("Actions -> Toggle Mnemonic Brief"), "Ctrl+Shift+F1"));
defaultShortcuts.insert("ActionHighlightingMode", Shortcut(tr("Actions -> Highlighting Mode"), "Ctrl+H"));
defaultShortcuts.insert("ActionToggleDestinationPreview", Shortcut(tr("Actions -> Enable/Disable Branch Destination Preview"), "P"));
defaultShortcuts.insert("ActionFind", Shortcut(tr("Actions -> Find"), "Ctrl+F"));
defaultShortcuts.insert("ActionDecompileFunction", Shortcut(tr("Actions -> Decompile Function"), "F5"));
defaultShortcuts.insert("ActionDecompileSelection", Shortcut(tr("Actions -> Decompile Selection"), "Shift+F5"));

View File

@ -28,11 +28,8 @@ public:
QKeySequence Hotkey;
bool GlobalShortcut;
Shortcut(QString n = QString(), QString h = QString(), bool g = false)
inline Shortcut(QString n = QString(), QString h = QString(), bool g = false) : Name(n), Hotkey(h), GlobalShortcut(g)
{
Name = n;
Hotkey = QKeySequence(h);
GlobalShortcut = g;
}
};

View File

@ -2,7 +2,7 @@
#define ENCODEMAP_H
#include <QObject>
#include "bridge/bridgemain.h"
#include "Imports.h"
class EncodeMap : public QObject
{
@ -71,7 +71,7 @@ public:
}
}
bool inRange(duint addr)
inline bool inRange(duint addr)
{
return addr >= mBase && addr < mBase + mSize;
}

View File

@ -2,7 +2,6 @@
#include <windows.h>
#include "LineEditDialog.h"
#include <QMessageBox>
#include <QIcon>
void SetApplicationIcon(WId winId)
{
@ -56,8 +55,3 @@ void SimpleWarningBox(QWidget* parent, const QString & title, const QString & te
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
msg.exec();
}
DIcon::DIcon(const QString & file)
: QIcon(QString(":/icons/images/%1").arg(file))
{
}

View File

@ -1,9 +1,11 @@
#ifndef MISCUTIL_H
#define MISCUTIL_H
#include <QWidget>
#include <QIcon>
class QWidget;
class QByteArray;
void SetApplicationIcon(WId winId);
QByteArray & ByteReverse(QByteArray & array);
bool SimpleInputBox(QWidget* parent, const QString & title, QString defaultValue, QString & output);
@ -12,7 +14,7 @@ void SimpleWarningBox(QWidget* parent, const QString & title, const QString & te
struct DIcon : QIcon
{
explicit DIcon(const QString & file);
inline explicit DIcon(const QString & file) : QIcon(QString(":/icons/images/%1").arg(file)) {}
};
#endif // MISCUTIL_H

View File

@ -1,4 +1,6 @@
#include "RichTextPainter.h"
#include "CachedFontMetrics.h"
#include <QPainter>
//TODO: fix performance (possibly use QTextLayout?)
void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, CachedFontMetrics* fontMetrics)

View File

@ -3,8 +3,10 @@
#include <QString>
#include <QColor>
#include <QPainter>
#include "CachedFontMetrics.h"
#include <vector>
class CachedFontMetrics;
class QPainter;
class RichTextPainter
{

View File

@ -243,3 +243,25 @@ QString FILETIMEToDate(const FILETIME & date)
else // today
return FILETIMEToTime(localdate);
}
bool GetCommentFormat(duint addr, QString & comment, bool* autoComment)
{
comment.clear();
char commentData[MAX_COMMENT_SIZE] = "";
if(!DbgGetCommentAt(addr, commentData))
return false;
auto a = *commentData == '\1';
if(autoComment)
*autoComment = a;
if(!strstr(commentData, "{"))
{
comment = commentData + a;
return true;
}
char commentFormat[MAX_SETTING_SIZE] = "";
if(DbgFunctions()->StringFormatInline(commentData + a, MAX_SETTING_SIZE, commentFormat))
comment = commentFormat;
else
comment = commentData + a;
return true;
}

View File

@ -121,26 +121,6 @@ static QString FILETIMEToTime(const FILETIME & time)
QString FILETIMEToDate(const FILETIME & date);
static bool GetCommentFormat(duint addr, QString & comment, bool* autoComment = nullptr)
{
comment.clear();
char commentData[MAX_COMMENT_SIZE] = "";
if(!DbgGetCommentAt(addr, commentData))
return false;
auto a = *commentData == '\1';
if(autoComment)
*autoComment = a;
if(!strstr(commentData, "{"))
{
comment = commentData + a;
return true;
}
char commentFormat[MAX_SETTING_SIZE] = "";
if(DbgFunctions()->StringFormatInline(commentData + a, MAX_SETTING_SIZE, commentFormat))
comment = commentFormat;
else
comment = commentData + a;
return true;
}
bool GetCommentFormat(duint addr, QString & comment, bool* autoComment = nullptr);
#endif // STRINGUTIL_H

View File

@ -2,6 +2,9 @@
#include "capstone_wrapper.h"
#include <QTextCodec>
#include <QFile>
#include <QTranslator>
#include <QTextStream>
#include <QLibraryInfo>
MyApplication::MyApplication(int & argc, char** argv)
: QApplication(argc, argv)

View File

@ -166,7 +166,8 @@ SOURCES += \
Src/Gui/WatchView.cpp \
Src/Gui/FavouriteTools.cpp \
Src/Gui/BrowseDialog.cpp \
Src/Gui/DisassemblerGraphView.cpp
Src/Gui/DisassemblerGraphView.cpp \
Src/Gui/DisassemblyPopup.cpp
HEADERS += \
@ -269,7 +270,8 @@ HEADERS += \
Src/Gui/FavouriteTools.h \
Src/Gui/BrowseDialog.h \
Src/Gui/DisassemblerGraphView.h \
Src/Utils/ActionHelpers.h
Src/Utils/ActionHelpers.h \
Src/Gui/DisassemblyPopup.h
FORMS += \