Update Zydis in the UI and remove DisassemblyPopup
This commit is contained in:
parent
812c91d361
commit
5797dae1c3
|
@ -8,7 +8,7 @@ AbstractStdTable::AbstractStdTable(QWidget* parent) : AbstractTableView(parent)
|
|||
|
||||
connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(reloadData()));
|
||||
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequestedSlot(QPoint)));
|
||||
connect(this, SIGNAL(headerButtonPressed(int)), this, SLOT(headerButtonPressedSlot(int)));
|
||||
connect(this, SIGNAL(headerButtonPressed(duint)), this, SLOT(headerButtonPressedSlot(duint)));
|
||||
|
||||
Initialize();
|
||||
|
||||
|
@ -22,27 +22,27 @@ AbstractStdTable::AbstractStdTable(QWidget* parent) : AbstractTableView(parent)
|
|||
mExportTableCSV = makeShortcutAction(DIcon("database-export"), tr("&Export Table"), SLOT(exportTableSlot()), "ActionExport");
|
||||
}
|
||||
|
||||
QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
||||
QString AbstractStdTable::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||
{
|
||||
bool isaddr = DbgIsDebugging() && getRowCount() > 0 && col == mAddressColumn;
|
||||
bool wIsSelected = isSelected(rowBase, rowOffset);
|
||||
QString text = getCellContent(rowBase + rowOffset, col);
|
||||
bool rowSelected = isSelected(row);
|
||||
QString text = getCellContent(row, col);
|
||||
|
||||
duint wVA = isaddr ? duint(text.toULongLong(&isaddr, 16)) : 0;
|
||||
auto wIsTraced = isaddr && DbgFunctions()->GetTraceRecordHitCount(wVA) != 0;
|
||||
duint va = isaddr ? duint(text.toULongLong(&isaddr, 16)) : 0;
|
||||
auto rowTraced = isaddr && DbgFunctions()->GetTraceRecordHitCount(va) != 0;
|
||||
QColor lineBackgroundColor;
|
||||
bool isBackgroundColorSet;
|
||||
if(wIsSelected && wIsTraced)
|
||||
if(rowSelected && rowTraced)
|
||||
{
|
||||
lineBackgroundColor = mTracedSelectedAddressBackgroundColor;
|
||||
isBackgroundColorSet = true;
|
||||
}
|
||||
else if(wIsSelected)
|
||||
else if(rowSelected)
|
||||
{
|
||||
lineBackgroundColor = mSelectionColor;
|
||||
isBackgroundColorSet = true;
|
||||
}
|
||||
else if(wIsTraced)
|
||||
else if(rowTraced)
|
||||
{
|
||||
lineBackgroundColor = mTracedBackgroundColor;
|
||||
isBackgroundColorSet = true;
|
||||
|
@ -57,16 +57,16 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
|
|||
if(col == mAddressColumn && isaddr)
|
||||
{
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
if(bAddressLabel && DbgGetLabelAt(wVA, SEG_DEFAULT, label)) //has label
|
||||
if(bAddressLabel && DbgGetLabelAt(va, SEG_DEFAULT, label)) //has label
|
||||
{
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
if(DbgGetModuleAt(wVA, module) && !QString(label).startsWith("JMP.&"))
|
||||
if(DbgGetModuleAt(va, module) && !QString(label).startsWith("JMP.&"))
|
||||
text += " <" + QString(module) + "." + QString(label) + ">";
|
||||
else
|
||||
text += " <" + QString(label) + ">";
|
||||
}
|
||||
BPXTYPE bpxtype = DbgGetBpxTypeAt(wVA);
|
||||
bool isbookmark = DbgGetBookmarkAt(wVA);
|
||||
BPXTYPE bpxtype = DbgGetBpxTypeAt(va);
|
||||
bool isbookmark = DbgGetBookmarkAt(va);
|
||||
|
||||
duint cip = Bridge::getBridge()->mLastCip;
|
||||
if(bCipBase)
|
||||
|
@ -76,7 +76,7 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
|
|||
cip = base;
|
||||
}
|
||||
|
||||
if(DbgIsDebugging() && wVA == cip) //debugging + cip
|
||||
if(DbgIsDebugging() && va == cip) //debugging + cip
|
||||
{
|
||||
painter->fillRect(QRect(x, y, w, h), QBrush(mCipBackgroundColor));
|
||||
if(!isbookmark) //no bookmark
|
||||
|
@ -149,7 +149,7 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
|
|||
if(bpxtype == bp_none) //no label, no breakpoint
|
||||
{
|
||||
QColor background;
|
||||
if(wIsSelected)
|
||||
if(rowSelected)
|
||||
{
|
||||
background = mSelectedAddressBackgroundColor;
|
||||
painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor)
|
||||
|
@ -177,7 +177,7 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
|
|||
else //other cases (memory breakpoint in disassembly) -> do as normal
|
||||
{
|
||||
QColor background;
|
||||
if(wIsSelected)
|
||||
if(rowSelected)
|
||||
{
|
||||
background = mSelectedAddressBackgroundColor;
|
||||
painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor)
|
||||
|
@ -265,12 +265,12 @@ QString AbstractStdTable::paintContent(QPainter* painter, dsint rowBase, int row
|
|||
}
|
||||
}
|
||||
while(index != -1);
|
||||
QStringList split = text.split(QChar('\1'), QString::SkipEmptyParts, Qt::CaseInsensitive);
|
||||
QStringList split = text.split(QChar('\1'), Qt::SkipEmptyParts, Qt::CaseInsensitive);
|
||||
|
||||
//create rich text list
|
||||
RichTextPainter::CustomRichText_t curRichText;
|
||||
curRichText.flags = RichTextPainter::FlagColor;
|
||||
QColor textColor = getCellColor(rowBase + rowOffset, col);
|
||||
QColor textColor = getCellColor(row, col);
|
||||
QColor textBackgroundColor = Qt::transparent;
|
||||
QColor highlightColor = ConfigColor("SearchListViewHighlightColor");
|
||||
QColor highlightBackgroundColor = ConfigColor("SearchListViewHighlightBackgroundColor");
|
||||
|
@ -344,6 +344,7 @@ void AbstractStdTable::mouseMoveEvent(QMouseEvent* event)
|
|||
else
|
||||
setSingleSelection(rowIndex);
|
||||
|
||||
// TODO: only update if the selection actually changed
|
||||
updateViewport();
|
||||
|
||||
accept = false;
|
||||
|
@ -384,6 +385,7 @@ void AbstractStdTable::mousePressEvent(QMouseEvent* event)
|
|||
|
||||
mGuiState = AbstractStdTable::MultiRowsSelectionState;
|
||||
|
||||
// TODO: only update if the selection actually changed
|
||||
updateViewport();
|
||||
|
||||
accept = true;
|
||||
|
@ -413,8 +415,6 @@ void AbstractStdTable::mouseReleaseEvent(QMouseEvent* event)
|
|||
{
|
||||
mGuiState = AbstractStdTable::NoState;
|
||||
|
||||
updateViewport();
|
||||
|
||||
accept = false;
|
||||
}
|
||||
}
|
||||
|
@ -509,6 +509,7 @@ void AbstractStdTable::keyPressEvent(QKeyEvent* event)
|
|||
setTableOffset(getInitialSelection() - getNbrOfLineToPrint() + 2);
|
||||
}
|
||||
|
||||
// TODO: only update if the selection actually changed
|
||||
updateViewport();
|
||||
}
|
||||
else
|
||||
|
@ -530,19 +531,19 @@ void AbstractStdTable::enableColumnSorting(bool enabled)
|
|||
/************************************************************************************
|
||||
Selection Management
|
||||
************************************************************************************/
|
||||
void AbstractStdTable::expandSelectionUpTo(int to)
|
||||
void AbstractStdTable::expandSelectionUpTo(duint to)
|
||||
{
|
||||
if(to < mSelection.firstSelectedIndex)
|
||||
{
|
||||
mSelection.fromIndex = to;
|
||||
mSelection.toIndex = mSelection.firstSelectedIndex;
|
||||
emit selectionChangedSignal(to);
|
||||
emit selectionChanged(to);
|
||||
}
|
||||
else if(to > mSelection.firstSelectedIndex)
|
||||
{
|
||||
mSelection.fromIndex = mSelection.firstSelectedIndex;
|
||||
mSelection.toIndex = to;
|
||||
emit selectionChangedSignal(to);
|
||||
emit selectionChanged(to);
|
||||
}
|
||||
else if(to == mSelection.firstSelectedIndex)
|
||||
{
|
||||
|
@ -612,24 +613,24 @@ void AbstractStdTable::expandBottom()
|
|||
}
|
||||
}
|
||||
|
||||
void AbstractStdTable::setSingleSelection(int index)
|
||||
void AbstractStdTable::setSingleSelection(duint index)
|
||||
{
|
||||
mSelection.firstSelectedIndex = index;
|
||||
mSelection.fromIndex = index;
|
||||
mSelection.toIndex = index;
|
||||
emit selectionChangedSignal(index);
|
||||
emit selectionChanged(index);
|
||||
}
|
||||
|
||||
int AbstractStdTable::getInitialSelection() const
|
||||
duint AbstractStdTable::getInitialSelection() const
|
||||
{
|
||||
return mSelection.firstSelectedIndex;
|
||||
}
|
||||
|
||||
QList<int> AbstractStdTable::getSelection() const
|
||||
QList<duint> AbstractStdTable::getSelection() const
|
||||
{
|
||||
QList<int> selection;
|
||||
QList<duint> selection;
|
||||
selection.reserve(mSelection.toIndex - mSelection.fromIndex);
|
||||
for(int i = mSelection.fromIndex; i <= mSelection.toIndex; i++)
|
||||
for(duint i = mSelection.fromIndex; i <= mSelection.toIndex; i++)
|
||||
{
|
||||
selection.append(i);
|
||||
}
|
||||
|
@ -655,60 +656,56 @@ void AbstractStdTable::selectEnd()
|
|||
|
||||
void AbstractStdTable::selectNext()
|
||||
{
|
||||
int wNext = getInitialSelection() + 1;
|
||||
// TODO: fix the signed/unsigned
|
||||
duint next = getInitialSelection() + 1;
|
||||
|
||||
// Bounding
|
||||
wNext = wNext > getRowCount() - 1 ? getRowCount() - 1 : wNext;
|
||||
wNext = wNext < 0 ? 0 : wNext;
|
||||
next = next > getRowCount() - 1 ? getRowCount() - 1 : next;
|
||||
next = next < 0 ? 0 : next;
|
||||
|
||||
setSingleSelection(wNext);
|
||||
setSingleSelection(next);
|
||||
}
|
||||
|
||||
void AbstractStdTable::selectPrevious()
|
||||
{
|
||||
int wNext = getInitialSelection() - 1;
|
||||
duint next = getInitialSelection() - 1;
|
||||
|
||||
// Bounding
|
||||
wNext = wNext > getRowCount() - 1 ? getRowCount() - 1 : wNext;
|
||||
wNext = wNext < 0 ? 0 : wNext;
|
||||
next = next > getRowCount() - 1 ? getRowCount() - 1 : next;
|
||||
next = next < 0 ? 0 : next;
|
||||
|
||||
setSingleSelection(wNext);
|
||||
setSingleSelection(next);
|
||||
}
|
||||
|
||||
void AbstractStdTable::selectAll()
|
||||
{
|
||||
int index = 0;
|
||||
int indexEnd = getRowCount() - 1;
|
||||
duint index = 0;
|
||||
duint indexEnd = getRowCount() - 1;
|
||||
|
||||
mSelection.firstSelectedIndex = index;
|
||||
mSelection.fromIndex = index;
|
||||
mSelection.toIndex = indexEnd;
|
||||
|
||||
emit selectionChangedSignal(index);
|
||||
emit selectionChanged(index);
|
||||
}
|
||||
|
||||
bool AbstractStdTable::isSelected(int base, int offset) const
|
||||
bool AbstractStdTable::isSelected(duint row) const
|
||||
{
|
||||
int wIndex = base + offset;
|
||||
|
||||
if(wIndex >= mSelection.fromIndex && wIndex <= mSelection.toIndex)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return row >= mSelection.fromIndex && row <= mSelection.toIndex;
|
||||
}
|
||||
|
||||
bool AbstractStdTable::scrollSelect(int offset)
|
||||
bool AbstractStdTable::scrollSelect(duint row)
|
||||
{
|
||||
if(!isValidIndex(offset, 0))
|
||||
if(!isValidIndex(row, 0))
|
||||
return false;
|
||||
|
||||
int rangefrom = getTableOffset();
|
||||
int rangeto = rangefrom + getViewableRowsCount() - 1;
|
||||
if(offset < rangefrom) //offset lays before the current view
|
||||
setTableOffset(offset);
|
||||
else if(offset > (rangeto - 1)) //offset lays after the current view
|
||||
setTableOffset(offset - getViewableRowsCount() + 2);
|
||||
setSingleSelection(offset);
|
||||
auto rangefrom = getTableOffset();
|
||||
auto rangeto = rangefrom + getViewableRowsCount() - 1;
|
||||
if(row < rangefrom) //offset lays before the current view
|
||||
setTableOffset(row);
|
||||
else if(row > (rangeto - 1)) //offset lays after the current view
|
||||
setTableOffset(row - getViewableRowsCount() + 2);
|
||||
setSingleSelection(row);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -735,15 +732,15 @@ void AbstractStdTable::deleteAllColumns()
|
|||
|
||||
void AbstractStdTable::copyLineSlot()
|
||||
{
|
||||
int colCount = getColumnCount();
|
||||
auto colCount = getColumnCount();
|
||||
QString finalText = "";
|
||||
if(colCount == 1)
|
||||
finalText = getCellContent(getInitialSelection(), 0);
|
||||
else
|
||||
{
|
||||
for(int selected : getSelection())
|
||||
for(auto selected : getSelection())
|
||||
{
|
||||
for(int i = 0; i < colCount; i++)
|
||||
for(duint i = 0; i < colCount; i++)
|
||||
{
|
||||
QString cellContent = getCellContent(selected, i);
|
||||
if(!cellContent.length()) //skip empty cells
|
||||
|
@ -761,14 +758,14 @@ void AbstractStdTable::copyLineSlot()
|
|||
|
||||
void AbstractStdTable::copyLineToLogSlot()
|
||||
{
|
||||
int colCount = getColumnCount();
|
||||
int selected = getInitialSelection();
|
||||
auto colCount = getColumnCount();
|
||||
auto selected = getInitialSelection();
|
||||
QString finalText = "";
|
||||
if(colCount == 1)
|
||||
finalText = getCellContent(selected, 0);
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < colCount; i++)
|
||||
for(duint i = 0; i < colCount; i++)
|
||||
{
|
||||
QString cellContent = getCellContent(selected, i);
|
||||
if(!cellContent.length()) //skip empty cells
|
||||
|
@ -785,12 +782,12 @@ void AbstractStdTable::copyLineToLogSlot()
|
|||
|
||||
QString AbstractStdTable::copyTable(const std::vector<int> & colWidths)
|
||||
{
|
||||
int colCount = getColumnCount();
|
||||
int rowCount = getRowCount();
|
||||
auto colCount = getColumnCount();
|
||||
auto rowCount = getRowCount();
|
||||
QString finalText = "";
|
||||
if(colCount == 1)
|
||||
{
|
||||
for(int i = 0; i < rowCount; i++)
|
||||
for(duint i = 0; i < rowCount; i++)
|
||||
{
|
||||
QString cellContent = getCellContent(i, 0);
|
||||
if(!cellContent.length()) //skip empty cells
|
||||
|
@ -803,7 +800,7 @@ QString AbstractStdTable::copyTable(const std::vector<int> & colWidths)
|
|||
//std::vector<int> colWidths;
|
||||
//for(int i = 0; i < colCount; i++)
|
||||
// colWidths.push_back(getMaxColumnLength(i));
|
||||
for(int i = 0; i < colCount; i++)
|
||||
for(duint i = 0; i < colCount; i++)
|
||||
{
|
||||
if(i)
|
||||
finalText += " ";
|
||||
|
@ -855,11 +852,11 @@ void AbstractStdTable::copyTableToLogSlot()
|
|||
void AbstractStdTable::copyTableResizeSlot()
|
||||
{
|
||||
std::vector<int> colWidths;
|
||||
int rowCount = getRowCount();
|
||||
int colCount = getColumnCount();
|
||||
for(int i = 0; i < colCount; i++)
|
||||
auto rowCount = getRowCount();
|
||||
auto colCount = getColumnCount();
|
||||
for(duint i = 0; i < colCount; i++)
|
||||
{
|
||||
int max = getCellContent(0, i).length();
|
||||
auto max = getCellContent(0, i).length();
|
||||
for(int j = 1; j < rowCount; j++)
|
||||
max = std::max(getCellContent(j, i).length(), max);
|
||||
colWidths.push_back(max);
|
||||
|
@ -874,7 +871,7 @@ void AbstractStdTable::copyTableResizeToLogSlot()
|
|||
int colCount = getColumnCount();
|
||||
for(int i = 0; i < colCount; i++)
|
||||
{
|
||||
int max = getCellContent(0, i).length();
|
||||
auto max = getCellContent(0, i).length();
|
||||
for(int j = 1; j < rowCount; j++)
|
||||
max = std::max(getCellContent(j, i).length(), max);
|
||||
colWidths.push_back(max);
|
||||
|
@ -934,7 +931,7 @@ void AbstractStdTable::setupCopyMenu(QMenu* copyMenu)
|
|||
|
||||
void AbstractStdTable::setupCopyColumnMenu(QMenu* copyMenu)
|
||||
{
|
||||
for(int i = 0; i < getColumnCount(); i++)
|
||||
for(duint i = 0; i < getColumnCount(); i++)
|
||||
{
|
||||
if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells
|
||||
continue;
|
||||
|
@ -1022,7 +1019,7 @@ void AbstractStdTable::contextMenuRequestedSlot(const QPoint & pos)
|
|||
}
|
||||
}
|
||||
|
||||
void AbstractStdTable::headerButtonPressedSlot(int col)
|
||||
void AbstractStdTable::headerButtonPressedSlot(duint col)
|
||||
{
|
||||
if(!mIsColumnSortingAllowed)
|
||||
return;
|
||||
|
@ -1046,22 +1043,16 @@ void AbstractStdTable::reloadData()
|
|||
AbstractTableView::reloadData();
|
||||
}
|
||||
|
||||
duint AbstractStdTable::getDisassemblyPopupAddress(int mousex, int mousey)
|
||||
duint AbstractStdTable::getAddressForPosition(int x, int y)
|
||||
{
|
||||
if(!bDisassemblyPopupEnabled) //No disassembly popup is meaningful for this table
|
||||
return 0;
|
||||
int c = getColumnIndexFromX(mousex);
|
||||
int r = getTableOffset() + getIndexOffsetFromY(transY(mousey));
|
||||
auto c = getColumnIndexFromX(x);
|
||||
auto r = getTableOffset() + getIndexOffsetFromY(transY(y));
|
||||
if(r < getRowCount())
|
||||
{
|
||||
QString cell = getCellContent(r, c);
|
||||
duint addr;
|
||||
bool ok = false;
|
||||
#ifdef _WIN64
|
||||
addr = cell.toULongLong(&ok, 16);
|
||||
#else //x86
|
||||
addr = cell.toULong(&ok, 16);
|
||||
#endif //_WIN64
|
||||
if(!ok)
|
||||
return 0;
|
||||
else
|
||||
|
|
|
@ -7,7 +7,7 @@ class AbstractStdTable : public AbstractTableView
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractStdTable(QWidget* parent = 0);
|
||||
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
|
||||
QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
|
||||
void updateColors() override;
|
||||
void reloadData() override;
|
||||
|
||||
|
@ -21,30 +21,29 @@ public:
|
|||
void enableColumnSorting(bool enabled);
|
||||
|
||||
// Selection Management
|
||||
void expandSelectionUpTo(int to);
|
||||
void expandSelectionUpTo(duint to);
|
||||
void expandUp();
|
||||
void expandDown();
|
||||
void expandTop();
|
||||
void expandBottom();
|
||||
void setSingleSelection(int index);
|
||||
int getInitialSelection() const;
|
||||
QList<int> getSelection() const;
|
||||
void setSingleSelection(duint index);
|
||||
duint getInitialSelection() const;
|
||||
QList<duint> getSelection() const;
|
||||
void selectStart();
|
||||
void selectEnd();
|
||||
void selectNext();
|
||||
void selectPrevious();
|
||||
void selectAll();
|
||||
bool isSelected(int base, int offset) const;
|
||||
bool scrollSelect(int offset);
|
||||
bool isSelected(duint row) const;
|
||||
bool scrollSelect(duint row);
|
||||
|
||||
// Data Management
|
||||
void addColumnAt(int width, QString title, bool isClickable, QString copyTitle = "");
|
||||
void deleteAllColumns() override;
|
||||
|
||||
virtual QString getCellContent(int r, int c) = 0;
|
||||
virtual bool isValidIndex(int r, int c) = 0;
|
||||
virtual void sortRows(int column, bool ascending) = 0;
|
||||
duint getDisassemblyPopupAddress(int mousex, int mousey) override;
|
||||
virtual QString getCellContent(duint row, duint column) = 0;
|
||||
virtual bool isValidIndex(duint row, duint column) = 0;
|
||||
virtual void sortRows(duint column, bool ascending) = 0;
|
||||
|
||||
//context menu helpers
|
||||
void setupCopyMenu(QMenu* copyMenu);
|
||||
|
@ -54,13 +53,13 @@ public:
|
|||
void setCopyMenuOnly(bool bSet, bool bDebugOnly = true);
|
||||
|
||||
//draw helpers
|
||||
void setHighlightText(QString highlightText, int minCol = 0)
|
||||
void setHighlightText(QString highlightText, duint minCol = 0)
|
||||
{
|
||||
mHighlightText = highlightText;
|
||||
mMinimumHighlightColumn = minCol;
|
||||
}
|
||||
|
||||
void setAddressColumn(int col, bool cipBase = false)
|
||||
void setAddressColumn(duint col, bool cipBase = false)
|
||||
{
|
||||
mAddressColumn = col;
|
||||
bCipBase = cipBase;
|
||||
|
@ -71,13 +70,8 @@ public:
|
|||
bAddressLabel = addressLabel;
|
||||
}
|
||||
|
||||
bool setDisassemblyPopupEnabled(bool enabled)
|
||||
{
|
||||
return bDisassemblyPopupEnabled = enabled;
|
||||
}
|
||||
|
||||
signals:
|
||||
void selectionChangedSignal(int index);
|
||||
void selectionChanged(duint index);
|
||||
void keyPressedSignal(QKeyEvent* event);
|
||||
void doubleClickedSignal();
|
||||
void contextMenuSignal(const QPoint & pos);
|
||||
|
@ -92,21 +86,22 @@ public slots:
|
|||
void copyEntrySlot();
|
||||
void exportTableSlot();
|
||||
void contextMenuRequestedSlot(const QPoint & pos);
|
||||
void headerButtonPressedSlot(int col);
|
||||
void headerButtonPressedSlot(duint col);
|
||||
|
||||
protected:
|
||||
QString copyTable(const std::vector<int> & colWidths);
|
||||
duint getAddressForPosition(int x, int y) override;
|
||||
|
||||
struct SelectionData
|
||||
{
|
||||
int firstSelectedIndex = 0;
|
||||
int fromIndex = 0;
|
||||
int toIndex = 0;
|
||||
duint firstSelectedIndex = 0;
|
||||
duint fromIndex = 0;
|
||||
duint toIndex = 0;
|
||||
};
|
||||
|
||||
SelectionData mSelection;
|
||||
|
||||
enum
|
||||
enum GuiState
|
||||
{
|
||||
NoState,
|
||||
MultiRowsSelectionState
|
||||
|
@ -121,7 +116,7 @@ protected:
|
|||
|
||||
struct SortData
|
||||
{
|
||||
int column = -1;
|
||||
duint column = -1;
|
||||
bool ascending = true;
|
||||
} mSort;
|
||||
|
||||
|
@ -146,7 +141,6 @@ protected:
|
|||
int mMinimumHighlightColumn = 0;
|
||||
int mAddressColumn = -1;
|
||||
bool bAddressLabel = true;
|
||||
bool bDisassemblyPopupEnabled = true;
|
||||
|
||||
QAction* mCopyLine;
|
||||
QAction* mCopyTable;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,7 +14,7 @@
|
|||
#include "ActionHelpers.h"
|
||||
|
||||
class CachedFontMetrics;
|
||||
class DisassemblyPopup;
|
||||
class ColumnReorderDialog;
|
||||
|
||||
//Hacky class that fixes a really annoying cursor problem
|
||||
class AbstractTableScrollBar : public QScrollBar
|
||||
|
@ -22,8 +22,7 @@ class AbstractTableScrollBar : public QScrollBar
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractTableScrollBar(QScrollBar* scrollbar);
|
||||
void enterEvent(QEvent* event) override;
|
||||
void leaveEvent(QEvent* event) override;
|
||||
bool event(QEvent* event) override;
|
||||
};
|
||||
|
||||
class AbstractTableView;
|
||||
|
@ -32,16 +31,6 @@ class AbstractTableView : public QAbstractScrollArea, public ActionHelper<Abstra
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum GuiState
|
||||
{
|
||||
NoState,
|
||||
ReadyToResize,
|
||||
ResizeColumnState,
|
||||
HeaderButtonPressed,
|
||||
HeaderButtonReordering
|
||||
};
|
||||
|
||||
// Constructor
|
||||
explicit AbstractTableView(QWidget* parent = 0);
|
||||
virtual ~AbstractTableView() = default;
|
||||
|
||||
|
@ -51,8 +40,8 @@ public:
|
|||
virtual void updateFonts();
|
||||
|
||||
// Pure Virtual Methods
|
||||
virtual QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) = 0;
|
||||
virtual QColor getCellColor(int r, int c);
|
||||
virtual QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) = 0;
|
||||
virtual QColor getCellColor(duint row, duint col);
|
||||
|
||||
// Painting Stuff
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
|
@ -65,53 +54,62 @@ public:
|
|||
void wheelEvent(QWheelEvent* event) override;
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void leaveEvent(QEvent* event) override;
|
||||
void hideEvent(QHideEvent* event) override;
|
||||
|
||||
// ScrollBar Management
|
||||
virtual dsint sliderMovedHook(int type, dsint value, dsint delta); // can be made protected
|
||||
int scaleFromUint64ToScrollBarRange(dsint value); // can be made private
|
||||
dsint scaleFromScrollBarRangeToUint64(int value); // can be made private
|
||||
virtual duint sliderMovedHook(QScrollBar::SliderAction action, duint prevTableOffset, dsint delta); // can be made protected
|
||||
int scaleFromUint64ToScrollBarRange(duint value); // can be made private
|
||||
duint scaleFromScrollBarRangeToUint64(int value); // can be made private
|
||||
|
||||
void updateScrollBarRange(dsint range); // setRowCount+resizeEvent needs this, can be made private
|
||||
void updateScrollBarRange(duint range); // setRowCount+resizeEvent needs this, can be made private
|
||||
|
||||
// Coordinates Utils
|
||||
int getIndexOffsetFromY(int y) const; // can be made protected
|
||||
int getColumnIndexFromX(int x) const; // can be made protected
|
||||
int getColumnPosition(int index) const; // can be made protected
|
||||
dsint getIndexOffsetFromY(int y) const; // can be made protected
|
||||
duint getColumnIndexFromX(int x) const; // can be made protected
|
||||
int getColumnPosition(duint column) const; // can be made protected
|
||||
int transY(int y) const; // can be made protected
|
||||
int getViewableRowsCount() const; // can be made protected
|
||||
virtual int getLineToPrintcount() const;
|
||||
|
||||
// TODO: this should probably be uint32_t?
|
||||
duint getViewableRowsCount() const; // can be made protected
|
||||
duint getMaxTableOffset() const;
|
||||
|
||||
// New Columns/New Size
|
||||
virtual void addColumnAt(int width, const QString & title, bool isClickable);
|
||||
virtual void setRowCount(dsint count);
|
||||
virtual void setRowCount(duint count);
|
||||
virtual void deleteAllColumns(); // can be made protected, although it makes sense as a public API
|
||||
void setColTitle(int index, const QString & title); // can be deleted, although it makes sense as a public API
|
||||
QString getColTitle(int index) const; // can be deleted, although it makes sense as a public API
|
||||
void setColTitle(duint col, const QString & title); // can be deleted, although it makes sense as a public API
|
||||
QString getColTitle(duint col) const; // can be deleted, although it makes sense as a public API
|
||||
|
||||
enum GuiState
|
||||
{
|
||||
NoState,
|
||||
ReadyToResize,
|
||||
ResizeColumnState,
|
||||
HeaderButtonPressed,
|
||||
HeaderButtonReordering
|
||||
};
|
||||
|
||||
// Getter & Setter
|
||||
dsint getRowCount() const;
|
||||
int getColumnCount() const;
|
||||
duint getRowCount() const;
|
||||
duint getColumnCount() const;
|
||||
int getRowHeight() const;
|
||||
int getColumnWidth(int index) const;
|
||||
void setColumnWidth(int index, int width);
|
||||
void setColumnOrder(int pos, int index);
|
||||
int getColumnOrder(int index) const;
|
||||
int getColumnWidth(duint col) const;
|
||||
void setColumnWidth(duint col, int width);
|
||||
void setColumnOrder(duint col, duint colNew);
|
||||
duint getColumnOrder(duint col) const;
|
||||
int getHeaderHeight() const; // can be made protected
|
||||
int getTableHeight() const; // can be made protected
|
||||
int getGuiState() const; // can be made protected
|
||||
int getNbrOfLineToPrint() const;
|
||||
void setNbrOfLineToPrint(int parNbrOfLineToPrint);
|
||||
GuiState getGuiState() const; // can be made protected
|
||||
duint getNbrOfLineToPrint() const; // TODO: should this be signed?
|
||||
void setNbrOfLineToPrint(duint parNbrOfLineToPrint);
|
||||
void setShowHeader(bool show);
|
||||
int getCharWidth() const;
|
||||
bool getColumnHidden(int col) const;
|
||||
void setColumnHidden(int col, bool hidden);
|
||||
int calculateColumnWidth(int characterCount) const;
|
||||
bool getColumnHidden(duint col) const;
|
||||
void setColumnHidden(duint col, bool hidden);
|
||||
bool getDrawDebugOnly() const;
|
||||
void setDrawDebugOnly(bool value);
|
||||
bool getAllowPainting() const;
|
||||
void setAllowPainting(bool allow);
|
||||
void setDisassemblyPopupEnabled(bool enable);
|
||||
|
||||
// UI customization
|
||||
void loadColumnFromConfig(const QString & viewName);
|
||||
|
@ -119,20 +117,20 @@ public:
|
|||
static void setupColumnConfigDefaultValue(QMap<QString, duint> & map, const QString & viewName, int columnCount);
|
||||
|
||||
// Table offset management
|
||||
dsint getTableOffset() const;
|
||||
void setTableOffset(dsint val);
|
||||
duint getTableOffset() const; // TODO: duint
|
||||
void setTableOffset(duint val); // TODO: duint
|
||||
|
||||
// Update/Reload/Refresh/Repaint
|
||||
virtual void prepareData();
|
||||
|
||||
virtual duint getDisassemblyPopupAddress(int mousex, int mousey);
|
||||
virtual duint getAddressForPosition(int x, int y);
|
||||
|
||||
signals:
|
||||
void enterPressedSignal();
|
||||
void headerButtonPressed(int col);
|
||||
void headerButtonReleased(int col);
|
||||
void tableOffsetChanged(dsint i);
|
||||
void viewableRowsChanged(int rows);
|
||||
void headerButtonPressed(duint col);
|
||||
void headerButtonReleased(duint col);
|
||||
void tableOffsetChanged(duint i);
|
||||
void viewableRowsChanged(duint rowCount);
|
||||
void repainted();
|
||||
|
||||
public slots:
|
||||
|
@ -145,96 +143,96 @@ public slots:
|
|||
|
||||
void editColumnDialog();
|
||||
|
||||
protected slots:
|
||||
void ShowDisassemblyPopup(duint addr, int x, int y); // this should probably be a slot, but doesn't need emit fixes (it's already used correctly)
|
||||
void timerEvent(QTimerEvent* event);
|
||||
|
||||
private slots:
|
||||
// Configuration
|
||||
void updateColorsSlot();
|
||||
void updateFontsSlot();
|
||||
void updateShortcutsSlot();
|
||||
void shutdownSlot();
|
||||
void closeSlot();
|
||||
|
||||
private:
|
||||
struct ColumnResizingData
|
||||
GuiState mGuiState = NoState;
|
||||
|
||||
struct ColumnResizeState
|
||||
{
|
||||
bool splitHandle;
|
||||
int index;
|
||||
int lastPosX;
|
||||
};
|
||||
bool splitHandle = false;
|
||||
int index = -1;
|
||||
int lastPosX = -1;
|
||||
} mColResizeData;
|
||||
|
||||
struct HeaderButton
|
||||
{
|
||||
bool isClickable;
|
||||
bool isPressed;
|
||||
bool isMouseOver;
|
||||
bool isClickable = false;
|
||||
bool isPressed = false;
|
||||
bool isMouseOver = false;
|
||||
};
|
||||
|
||||
struct Column
|
||||
{
|
||||
int width;
|
||||
bool hidden;
|
||||
int width = 0;
|
||||
int paintedWidth = -1;
|
||||
bool hidden = false;
|
||||
HeaderButton header;
|
||||
QString title;
|
||||
};
|
||||
|
||||
struct Header
|
||||
struct HeaderConfig
|
||||
{
|
||||
bool isVisible;
|
||||
int height;
|
||||
int activeButtonIndex;
|
||||
};
|
||||
|
||||
struct ScrollBar64
|
||||
{
|
||||
bool is64;
|
||||
int rightShiftCount;
|
||||
};
|
||||
|
||||
GuiState mGuiState;
|
||||
|
||||
Header mHeader;
|
||||
QPushButton mHeaderButtonSytle;
|
||||
bool isVisible = true;
|
||||
int height = 20;
|
||||
int activeButtonIndex = -1;
|
||||
} mHeader;
|
||||
|
||||
int mMinColumnWidth = 5;
|
||||
QList<Column> mColumnList;
|
||||
ColumnResizingData mColResizeData;
|
||||
QList<duint> mColumnOrder;
|
||||
int mReorderStartX = -1;
|
||||
int mHoveredColumnDisplayIndex = -1;
|
||||
|
||||
QList<int> mColumnOrder;
|
||||
int mReorderStartX;
|
||||
int mHoveredColumnDisplayIndex;
|
||||
duint mRowCount = 0;
|
||||
duint mTableOffset = 0;
|
||||
duint mPrevTableOffset = -1;
|
||||
duint mNbrOfLineToPrint = 0;
|
||||
|
||||
dsint mRowCount;
|
||||
dsint mTableOffset;
|
||||
dsint mPrevTableOffset;
|
||||
int mNbrOfLineToPrint;
|
||||
bool mShouldReload = true;
|
||||
bool mDrawDebugOnly = false;
|
||||
|
||||
bool mShouldReload;
|
||||
bool mDrawDebugOnly;
|
||||
bool mPopupEnabled;
|
||||
int mPopupTimer;
|
||||
// State for accumulating scroll events
|
||||
enum ScrollDirection
|
||||
{
|
||||
ScrollUnknown,
|
||||
ScrollVertical,
|
||||
ScrollHorizontal,
|
||||
} mPixelScrollDirection = ScrollUnknown;
|
||||
QPoint mPixelScrollDelta;
|
||||
QPoint mAngleScrollDelta;
|
||||
|
||||
static int mMouseWheelScrollDelta;
|
||||
ScrollBar64 mScrollBarAttributes;
|
||||
struct ScrollBarAttributes
|
||||
{
|
||||
bool is64 = false;
|
||||
int rightShiftCount = 0;
|
||||
} mScrollBarAttributes;
|
||||
|
||||
int getColumnDisplayIndexFromX(int x);
|
||||
friend class ColumnReorderDialog;
|
||||
|
||||
protected:
|
||||
// Configuration
|
||||
QColor mBackgroundColor;
|
||||
QColor mTextColor;
|
||||
QColor mSeparatorColor;
|
||||
QColor mHeaderTextColor;
|
||||
QColor mSelectionColor;
|
||||
QString mViewName;
|
||||
void updateLastColumnWidth();
|
||||
|
||||
bool mAllowPainting;
|
||||
protected:
|
||||
bool mAllowPainting = true;
|
||||
|
||||
// Configuration
|
||||
QColor mTextColor;
|
||||
QColor mBackgroundColor;
|
||||
QColor mHeaderTextColor;
|
||||
QColor mHeaderBackgroundColor;
|
||||
QColor mSeparatorColor;
|
||||
QColor mSelectionColor;
|
||||
QString mViewName; // TODO: this is needed during construction
|
||||
|
||||
// Font metrics
|
||||
CachedFontMetrics* mFontMetrics;
|
||||
CachedFontMetrics* mFontMetrics = nullptr;
|
||||
void invalidateCachedFont();
|
||||
|
||||
// Disassembly Popup
|
||||
DisassemblyPopup* mDisassemblyPopup;
|
||||
ColumnReorderDialog* mReorderDialog = nullptr;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "AbstractTableView.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
#include <QTextLayout>
|
||||
#include "Architecture.h"
|
||||
|
||||
class CodeFoldingHelper;
|
||||
class MemoryPage;
|
||||
class DisassemblyPopup;
|
||||
|
||||
class Disassembly : public AbstractTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Disassembly(QWidget* parent, bool isMain);
|
||||
Disassembly(QWidget* parent, bool isMain, Architecture* architecture);
|
||||
~Disassembly() override;
|
||||
|
||||
// Configuration
|
||||
|
@ -19,7 +21,7 @@ public:
|
|||
void updateFonts() override;
|
||||
|
||||
// Reimplemented Functions
|
||||
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
|
||||
QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
|
||||
|
||||
// Mouse Management
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
|
@ -31,25 +33,25 @@ public:
|
|||
void keyPressEvent(QKeyEvent* event) override;
|
||||
|
||||
// ScrollBar Management
|
||||
dsint sliderMovedHook(int type, dsint value, dsint delta) override;
|
||||
duint sliderMovedHook(QScrollBar::SliderAction action, duint value, dsint delta) override;
|
||||
|
||||
// Instructions Management
|
||||
dsint getPreviousInstructionRVA(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);
|
||||
duint getPreviousInstructionRVA(duint rva, duint count);
|
||||
duint getNextInstructionRVA(duint rva, duint count, bool isGlobal = false);
|
||||
duint getInstructionRVA(duint index, dsint count);
|
||||
Instruction_t DisassembleAt(duint rva);
|
||||
Instruction_t DisassembleAt(duint rva, dsint count);
|
||||
|
||||
// Selection Management
|
||||
void expandSelectionUpTo(dsint to);
|
||||
void setSingleSelection(dsint index);
|
||||
dsint getInitialSelection() const;
|
||||
dsint getSelectionSize() const;
|
||||
dsint getSelectionStart() const;
|
||||
dsint getSelectionEnd() const;
|
||||
void expandSelectionUpTo(duint to);
|
||||
void setSingleSelection(duint index);
|
||||
duint getInitialSelection() const;
|
||||
duint getSelectionSize() const;
|
||||
duint getSelectionStart() const;
|
||||
duint getSelectionEnd() const;
|
||||
void selectNext(bool expand);
|
||||
void selectPrevious(bool expand);
|
||||
bool isSelected(dsint base, dsint offset);
|
||||
bool isSelected(duint base, dsint offset);
|
||||
bool isSelected(QList<Instruction_t>* buffer, int index) const;
|
||||
duint getSelectedVa() const;
|
||||
|
||||
|
@ -60,7 +62,7 @@ public:
|
|||
void paintEvent(QPaintEvent* event) override;
|
||||
|
||||
// Public Methods
|
||||
duint rvaToVa(dsint rva) const;
|
||||
duint rvaToVa(duint rva) const;
|
||||
void disassembleClear();
|
||||
const duint getBase() const;
|
||||
duint getSize() const;
|
||||
|
@ -75,32 +77,31 @@ public:
|
|||
|
||||
//disassemble
|
||||
void gotoAddress(duint addr);
|
||||
void disassembleAt(dsint parVA, bool history, dsint newTableOffset);
|
||||
void disassembleAt(duint va, bool history, duint newTableOffset);
|
||||
|
||||
QList<Instruction_t>* instructionsBuffer(); // ugly
|
||||
const dsint baseAddress() const;
|
||||
const duint baseAddress() const;
|
||||
|
||||
QString getAddrText(dsint cur_addr, char label[MAX_LABEL_SIZE], bool getLabel = true);
|
||||
void prepareDataCount(const QList<dsint> & wRVAs, QList<Instruction_t>* instBuffer);
|
||||
void prepareDataRange(dsint startRva, dsint endRva, const std::function<bool(int, const Instruction_t &)> & disassembled);
|
||||
QString getAddrText(duint cur_addr, QString & label, bool getLabel = true);
|
||||
void prepareDataCount(const QList<duint> & rvas, QList<Instruction_t>* instBuffer);
|
||||
void prepareDataRange(duint startRva, duint endRva, const std::function<bool(int, const Instruction_t &)> & disassembled);
|
||||
RichTextPainter::List getRichBytes(const Instruction_t & instr, bool isSelected) const;
|
||||
|
||||
//misc
|
||||
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
|
||||
duint getDisassemblyPopupAddress(int mousex, int mousey) override;
|
||||
void unfold(dsint rva);
|
||||
void unfold(duint rva);
|
||||
bool hightlightToken(const ZydisTokenizer::SingleToken & token);
|
||||
bool isHighlightMode() const;
|
||||
|
||||
signals:
|
||||
void selectionChanged(dsint parVA);
|
||||
void selectionChanged(duint va);
|
||||
void selectionExpanded();
|
||||
void updateWindowTitle(QString title);
|
||||
|
||||
public slots:
|
||||
void disassembleAtSlot(dsint parVA, dsint parCIP);
|
||||
void disassembleAtSlot(duint va, duint cip);
|
||||
void debugStateChangedSlot(DBGSTATE state);
|
||||
void selectionChangedSlot(dsint parVA);
|
||||
void selectionChangedSlot(duint va);
|
||||
void tokenizerConfigUpdatedSlot();
|
||||
void updateConfigSlot();
|
||||
|
||||
|
@ -127,30 +128,31 @@ private:
|
|||
{
|
||||
GJD_Nothing,
|
||||
GJD_Up,
|
||||
GJD_Down
|
||||
GJD_Down,
|
||||
GJD_Out,
|
||||
};
|
||||
|
||||
struct SelectionData
|
||||
{
|
||||
dsint firstSelectedIndex;
|
||||
dsint fromIndex;
|
||||
dsint toIndex;
|
||||
};
|
||||
|
||||
SelectionData mSelection;
|
||||
duint firstSelectedIndex = 0;
|
||||
duint fromIndex = 0;
|
||||
duint toIndex = 0;
|
||||
} mSelection;
|
||||
|
||||
Architecture* mArchitecture = nullptr;
|
||||
bool mIsLastInstDisplayed;
|
||||
|
||||
GuiState mGuiState;
|
||||
|
||||
duint mCipVa = 0;
|
||||
|
||||
Instruction_t mSelectedInstruction;
|
||||
QList<Instruction_t> mInstBuffer;
|
||||
|
||||
struct HistoryData
|
||||
{
|
||||
dsint va;
|
||||
dsint tableOffset;
|
||||
duint va = 0;
|
||||
duint tableOffset = 0;
|
||||
};
|
||||
|
||||
QList<HistoryData> mVaHistory;
|
||||
|
@ -165,9 +167,11 @@ private:
|
|||
ColMnemonicBrief,
|
||||
};
|
||||
|
||||
DisassemblyPopup* mDisassemblyPopup = nullptr;
|
||||
|
||||
protected:
|
||||
// Jumps Graphic
|
||||
int paintJumpsGraphic(QPainter* painter, int x, int y, dsint addr, bool isjmp);
|
||||
int paintJumpsGraphic(QPainter* painter, int x, int y, const Instruction_t & instruction);
|
||||
|
||||
// Function Graphic
|
||||
|
||||
|
@ -182,6 +186,9 @@ protected:
|
|||
};
|
||||
|
||||
int paintFunctionGraphic(QPainter* painter, int x, int y, Function_t funcType, bool loop);
|
||||
|
||||
duint getAddressForPosition(int mousex, int mousey) override;
|
||||
|
||||
// Configuration
|
||||
QColor mInstructionHighlightColor;
|
||||
QColor mDisassemblyRelocationUnderlineColor;
|
||||
|
@ -243,7 +250,7 @@ protected:
|
|||
dsint mRvaDisplayPageBase;
|
||||
bool mHighlightingMode;
|
||||
MemoryPage* mMemPage;
|
||||
QBeaEngine* mDisasm;
|
||||
QZydis* mDisasm;
|
||||
bool mShowMnemonicBrief;
|
||||
XREF_INFO mXrefInfo;
|
||||
CodeFoldingHelper* mCodeFoldingManager;
|
||||
|
|
|
@ -85,12 +85,6 @@ void StdSearchListView::setSearchStartCol(int col)
|
|||
mSearchStartCol = col;
|
||||
}
|
||||
|
||||
bool StdSearchListView::setDisassemblyPopupEnabled(bool enabled)
|
||||
{
|
||||
stdList()->setDisassemblyPopupEnabled(enabled);
|
||||
return stdSearchList()->setDisassemblyPopupEnabled(enabled);
|
||||
}
|
||||
|
||||
StdTable* StdSearchListView::stdList()
|
||||
{
|
||||
return mSearchListData->mList;
|
||||
|
|
|
@ -18,7 +18,6 @@ public:
|
|||
void enableMultiSelection(bool enabled);
|
||||
void setAddressColumn(int col, bool cipBase = false);
|
||||
void loadColumnFromConfig(const QString & viewName);
|
||||
bool setDisassemblyPopupEnabled(bool enabled);
|
||||
|
||||
public slots:
|
||||
virtual void setRowCount(dsint count);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "Bridge.h"
|
||||
#include <QClipboard>
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
#include "main.h"
|
||||
#include "Exports.h"
|
||||
|
||||
|
@ -12,6 +12,19 @@
|
|||
************************************************************************************/
|
||||
static Bridge* mBridge;
|
||||
|
||||
class BridgeArchitecture : public Architecture
|
||||
{
|
||||
bool disasm64() const override
|
||||
{
|
||||
return ArchValue(false, true);
|
||||
}
|
||||
|
||||
bool addr64() const override
|
||||
{
|
||||
return ArchValue(false, true);
|
||||
}
|
||||
} mArch;
|
||||
|
||||
/************************************************************************************
|
||||
Class Members
|
||||
************************************************************************************/
|
||||
|
@ -72,6 +85,11 @@ void Bridge::initBridge()
|
|||
mBridge = new Bridge();
|
||||
}
|
||||
|
||||
Architecture* Bridge::getArch()
|
||||
{
|
||||
return &mArch;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
Helper Functions
|
||||
************************************************************************************/
|
||||
|
@ -100,7 +118,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||
{
|
||||
case GUI_DISASSEMBLE_AT:
|
||||
mLastCip = (duint)param2;
|
||||
emit disassembleAt((dsint)param1, (dsint)param2);
|
||||
emit disassembleAt((duint)param1, (duint)param2);
|
||||
break;
|
||||
|
||||
case GUI_SET_DEBUG_STATE:
|
||||
|
@ -361,7 +379,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||
byte_t buffer[16];
|
||||
if(!DbgMemRead(parVA, buffer, 16))
|
||||
return 0;
|
||||
QBeaEngine disasm(int(ConfigUint("Disassembler", "MaxModuleSize")), Bridge::getArch());
|
||||
QZydis disasm(int(ConfigUint("Disassembler", "MaxModuleSize")), Bridge::getArch());
|
||||
Instruction_t instr = disasm.DisassembleAt(buffer, 16, 0, parVA);
|
||||
QString finalInstruction;
|
||||
for(const auto & curToken : instr.tokens.tokens)
|
||||
|
|
|
@ -7,6 +7,15 @@
|
|||
#include <QMenu>
|
||||
#include "Imports.h"
|
||||
#include "BridgeResult.h"
|
||||
#include "Architecture.h"
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
namespace Qt
|
||||
{
|
||||
static QString::SplitBehavior KeepEmptyParts = QString::KeepEmptyParts;
|
||||
static QString::SplitBehavior SkipEmptyParts = QString::SkipEmptyParts;
|
||||
}
|
||||
#endif // QT_VERSION
|
||||
|
||||
class ReferenceManager;
|
||||
class SymbolView;
|
||||
|
@ -23,6 +32,7 @@ public:
|
|||
|
||||
static Bridge* getBridge();
|
||||
static void initBridge();
|
||||
static Architecture* getArch();
|
||||
|
||||
// Message processing function
|
||||
void* processMessage(GUIMSG type, void* param1, void* param2);
|
||||
|
@ -47,7 +57,7 @@ public:
|
|||
bool loggingEnabled = true;
|
||||
|
||||
signals:
|
||||
void disassembleAt(dsint va, dsint eip);
|
||||
void disassembleAt(duint va, duint eip);
|
||||
void updateDisassembly();
|
||||
void dbgStateChanged(DBGSTATE state);
|
||||
void addMsgToLog(QByteArray msg);
|
||||
|
@ -57,11 +67,11 @@ signals:
|
|||
void saveLogToFile(QString file);
|
||||
void redirectLogStop();
|
||||
void redirectLogToFile(QString filename);
|
||||
void shutdown();
|
||||
void close();
|
||||
void updateRegisters();
|
||||
void updateBreakpoints();
|
||||
void updateWindowTitle(QString filename);
|
||||
void dumpAt(dsint va);
|
||||
void dumpAt(duint va);
|
||||
void scriptAdd(int count, const char** lines);
|
||||
void scriptClear();
|
||||
void scriptSetIp(int line);
|
||||
|
@ -76,7 +86,7 @@ signals:
|
|||
void clearSymbolLog();
|
||||
void setSymbolProgress(int progress);
|
||||
void referenceAddColumnAt(int width, QString title);
|
||||
void referenceSetRowCount(dsint count);
|
||||
void referenceSetRowCount(duint count);
|
||||
void referenceSetCellContent(int r, int c, QString s);
|
||||
void referenceAddCommand(QString title, QString command);
|
||||
void referenceReloadData();
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "Architecture.h"
|
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
/*
|
||||
This should probably take some inspiration from Zydis:
|
||||
- Address space min/max (64 vs 32 bit basically)
|
||||
- Disassembly architecture (likely should return a reference to a disassembler)
|
||||
|
||||
*/
|
||||
class Architecture
|
||||
{
|
||||
public:
|
||||
virtual ~Architecture() = default;
|
||||
|
||||
// TODO: replace this with something about address space
|
||||
virtual bool disasm64() const = 0;
|
||||
virtual bool addr64() const = 0;
|
||||
};
|
|
@ -1,75 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
#include "ZydisTokenizer.h"
|
||||
|
||||
class EncodeMap;
|
||||
class CodeFoldingHelper;
|
||||
|
||||
struct Instruction_t
|
||||
{
|
||||
enum BranchType
|
||||
{
|
||||
None,
|
||||
Conditional,
|
||||
Unconditional,
|
||||
Call
|
||||
};
|
||||
|
||||
Instruction_t()
|
||||
: rva(0),
|
||||
length(0),
|
||||
branchDestination(0),
|
||||
branchType(None)
|
||||
{
|
||||
}
|
||||
|
||||
QString instStr;
|
||||
QByteArray dump;
|
||||
uint8_t prefixSize, opcodeSize, group1Size, group2Size, group3Size;
|
||||
duint rva;
|
||||
int length;
|
||||
duint branchDestination;
|
||||
BranchType branchType;
|
||||
ZydisTokenizer::InstructionToken tokens;
|
||||
std::vector<std::pair<const char*, uint8_t>> regsReferenced;
|
||||
uint8_t vectorElementType[4];
|
||||
};
|
||||
|
||||
class QBeaEngine
|
||||
{
|
||||
public:
|
||||
explicit QBeaEngine(int maxModuleSize);
|
||||
~QBeaEngine();
|
||||
ulong DisassembleBack(const byte_t* data, duint base, duint size, duint ip, int n);
|
||||
ulong DisassembleNext(const byte_t* data, duint base, duint size, duint ip, int n);
|
||||
Instruction_t DisassembleAt(const byte_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr = true);
|
||||
Instruction_t DecodeDataAt(const byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type);
|
||||
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
|
||||
void UpdateConfig();
|
||||
|
||||
EncodeMap* getEncodeMap()
|
||||
{
|
||||
return mEncodeMap;
|
||||
}
|
||||
|
||||
private:
|
||||
struct DataInstructionInfo
|
||||
{
|
||||
QString shortName;
|
||||
QString longName;
|
||||
QString cName;
|
||||
};
|
||||
|
||||
void UpdateDataInstructionMap();
|
||||
ZydisTokenizer _tokenizer;
|
||||
QHash<ENCODETYPE, DataInstructionInfo> dataInstMap;
|
||||
bool _bLongDataInst;
|
||||
EncodeMap* mEncodeMap;
|
||||
CodeFoldingHelper* mCodeFoldingManager;
|
||||
uint8_t reginfo[ZYDIS_REGISTER_MAX_VALUE + 1];
|
||||
uint8_t flaginfo[ZYDIS_CPUFLAG_MAX_VALUE + 1];
|
||||
};
|
||||
|
||||
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes);
|
|
@ -1,19 +1,24 @@
|
|||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
#include "StringUtil.h"
|
||||
#include "EncodeMap.h"
|
||||
#include "CodeFolding.h"
|
||||
#include "Bridge.h"
|
||||
|
||||
QBeaEngine::QBeaEngine(int maxModuleSize)
|
||||
: _tokenizer(maxModuleSize), mCodeFoldingManager(nullptr), _bLongDataInst(false)
|
||||
#ifndef _countof
|
||||
#define _countof(array) (sizeof(array) / sizeof(array[0]))
|
||||
#endif // _countof
|
||||
|
||||
QZydis::QZydis(int maxModuleSize, Architecture* architecture)
|
||||
: mTokenizer(maxModuleSize, architecture), mArchitecture(architecture)
|
||||
{
|
||||
ZydisTokenizer::UpdateColors();
|
||||
UpdateDataInstructionMap();
|
||||
this->mEncodeMap = new EncodeMap();
|
||||
mEncodeMap = new EncodeMap();
|
||||
}
|
||||
|
||||
QBeaEngine::~QBeaEngine()
|
||||
QZydis::~QZydis()
|
||||
{
|
||||
delete this->mEncodeMap;
|
||||
delete mEncodeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,14 +33,14 @@ QBeaEngine::~QBeaEngine()
|
|||
*
|
||||
* @return Return the RVA (Relative to the data pointer) of the nth instruction before the instruction pointed by ip
|
||||
*/
|
||||
ulong QBeaEngine::DisassembleBack(const byte_t* data, duint base, duint size, duint ip, int n)
|
||||
ulong QZydis::DisassembleBack(const uint8_t* data, duint base, duint size, duint ip, int n)
|
||||
{
|
||||
int i;
|
||||
uint abuf[128], addr, back, cmdsize;
|
||||
const unsigned char* pdata;
|
||||
|
||||
// Reset Disasm Structure
|
||||
Zydis cp;
|
||||
Zydis zydis(mArchitecture->disasm64());
|
||||
|
||||
// Check if the pointer is not null
|
||||
if(data == NULL)
|
||||
|
@ -89,10 +94,10 @@ ulong QBeaEngine::DisassembleBack(const byte_t* data, duint base, duint size, du
|
|||
}
|
||||
else
|
||||
{
|
||||
if(!cp.DisassembleSafe(addr + base, pdata, (int)size))
|
||||
if(!zydis.DisassembleSafe(addr + base, pdata, (int)size))
|
||||
cmdsize = 2; //heuristic for better output (FF FE or FE FF are usually part of an instruction)
|
||||
else
|
||||
cmdsize = cp.Size();
|
||||
cmdsize = zydis.Size();
|
||||
|
||||
cmdsize = mEncodeMap->getDataSize(base + addr, cmdsize);
|
||||
|
||||
|
@ -124,14 +129,14 @@ ulong QBeaEngine::DisassembleBack(const byte_t* data, duint base, duint size, du
|
|||
*
|
||||
* @return Return the RVA (Relative to the data pointer) of the nth instruction after the instruction pointed by ip
|
||||
*/
|
||||
ulong QBeaEngine::DisassembleNext(const byte_t* data, duint base, duint size, duint ip, int n)
|
||||
ulong QZydis::DisassembleNext(const uint8_t* data, duint base, duint size, duint ip, int n)
|
||||
{
|
||||
int i;
|
||||
uint cmdsize;
|
||||
const unsigned char* pdata;
|
||||
|
||||
// Reset Disasm Structure
|
||||
Zydis cp;
|
||||
Zydis zydis(mArchitecture->disasm64());
|
||||
|
||||
if(data == NULL)
|
||||
return 0;
|
||||
|
@ -154,10 +159,10 @@ ulong QBeaEngine::DisassembleNext(const byte_t* data, duint base, duint size, du
|
|||
}
|
||||
else
|
||||
{
|
||||
if(!cp.DisassembleSafe(ip + base, pdata, (int)size))
|
||||
if(!zydis.DisassembleSafe(ip + base, pdata, (int)size))
|
||||
cmdsize = 1;
|
||||
else
|
||||
cmdsize = cp.Size();
|
||||
cmdsize = zydis.Size();
|
||||
|
||||
cmdsize = mEncodeMap->getDataSize(base + ip, cmdsize);
|
||||
|
||||
|
@ -181,7 +186,7 @@ ulong QBeaEngine::DisassembleNext(const byte_t* data, duint base, duint size, du
|
|||
*
|
||||
* @return Return the disassembled instruction
|
||||
*/
|
||||
Instruction_t QBeaEngine::DisassembleAt(const byte_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr)
|
||||
Instruction_t QZydis::DisassembleAt(const uint8_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr)
|
||||
{
|
||||
if(datainstr)
|
||||
{
|
||||
|
@ -189,147 +194,140 @@ Instruction_t QBeaEngine::DisassembleAt(const byte_t* data, duint size, duint or
|
|||
if(!mEncodeMap->isCode(type))
|
||||
return DecodeDataAt(data, size, origBase, origInstRVA, type);
|
||||
}
|
||||
|
||||
//tokenize
|
||||
ZydisTokenizer::InstructionToken cap;
|
||||
_tokenizer.Tokenize(origBase + origInstRVA, data, size, cap);
|
||||
int len = _tokenizer.Size();
|
||||
|
||||
const auto & cp = _tokenizer.GetZydis();
|
||||
bool success = cp.Success();
|
||||
mTokenizer.Tokenize(origBase + origInstRVA, data, size, cap);
|
||||
int len = mTokenizer.Size();
|
||||
|
||||
const auto & zydis = mTokenizer.GetZydis();
|
||||
bool success = zydis.Success();
|
||||
|
||||
auto branchType = Instruction_t::None;
|
||||
Instruction_t wInst;
|
||||
if(success && cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTRet | Zydis::BTLoop | Zydis::BTXbegin))
|
||||
Instruction_t inst;
|
||||
if(success && zydis.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTRet | Zydis::BTLoop | Zydis::BTXbegin))
|
||||
{
|
||||
wInst.branchDestination = DbgGetBranchDestination(origBase + origInstRVA);
|
||||
if(cp.IsBranchType(Zydis::BTUncondJmp))
|
||||
inst.branchDestination = DbgGetBranchDestination(origBase + origInstRVA);
|
||||
if(zydis.IsBranchType(Zydis::BTUncondJmp))
|
||||
branchType = Instruction_t::Unconditional;
|
||||
else if(cp.IsBranchType(Zydis::BTCall))
|
||||
else if(zydis.IsBranchType(Zydis::BTCall))
|
||||
branchType = Instruction_t::Call;
|
||||
else if(cp.IsBranchType(Zydis::BTCondJmp) || cp.IsBranchType(Zydis::BTLoop))
|
||||
else if(zydis.IsBranchType(Zydis::BTCondJmp) || zydis.IsBranchType(Zydis::BTLoop))
|
||||
branchType = Instruction_t::Conditional;
|
||||
}
|
||||
else
|
||||
wInst.branchDestination = 0;
|
||||
inst.branchDestination = 0;
|
||||
|
||||
wInst.instStr = QString(cp.InstructionText().c_str());
|
||||
wInst.dump = QByteArray((const char*)data, len);
|
||||
wInst.rva = origInstRVA;
|
||||
inst.instStr = QString(zydis.InstructionText().c_str());
|
||||
inst.dump = QByteArray((const char*)data, len);
|
||||
inst.rva = origInstRVA;
|
||||
if(mCodeFoldingManager && mCodeFoldingManager->isFolded(origInstRVA))
|
||||
wInst.length = mCodeFoldingManager->getFoldEnd(origInstRVA + origBase) - (origInstRVA + origBase) + 1;
|
||||
inst.length = mCodeFoldingManager->getFoldEnd(origInstRVA + origBase) - (origInstRVA + origBase) + 1;
|
||||
else
|
||||
wInst.length = len;
|
||||
wInst.branchType = branchType;
|
||||
wInst.tokens = cap;
|
||||
cp.BytesGroup(&wInst.prefixSize, &wInst.opcodeSize, &wInst.group1Size, &wInst.group2Size, &wInst.group3Size);
|
||||
for(uint8_t i = 0; i < _countof(wInst.vectorElementType); ++i)
|
||||
wInst.vectorElementType[i] = cp.getVectorElementType(i);
|
||||
inst.length = len;
|
||||
inst.branchType = branchType;
|
||||
inst.tokens = cap;
|
||||
zydis.BytesGroup(&inst.prefixSize, &inst.opcodeSize, &inst.group1Size, &inst.group2Size, &inst.group3Size);
|
||||
for(uint8_t i = 0; i < _countof(inst.vectorElementType); ++i)
|
||||
inst.vectorElementType[i] = zydis.getVectorElementType(i);
|
||||
|
||||
if(!success)
|
||||
return wInst;
|
||||
return inst;
|
||||
|
||||
auto instr = cp.GetInstr();
|
||||
cp.RegInfo(reginfo);
|
||||
uint8_t regInfo[ZYDIS_REGISTER_MAX_VALUE + 1];
|
||||
uint8_t flagInfo[32];
|
||||
zydis.RegInfo(regInfo);
|
||||
zydis.FlagInfo(flagInfo);
|
||||
|
||||
for(size_t i = 0; i < _countof(instr->accessedFlags); ++i)
|
||||
regInfo[ZYDIS_REGISTER_RFLAGS] = Zydis::RAINone;
|
||||
regInfo[ZYDIS_REGISTER_EFLAGS] = Zydis::RAINone;
|
||||
regInfo[ZYDIS_REGISTER_FLAGS] = Zydis::RAINone;
|
||||
regInfo[mArchitecture->disasm64() ? ZYDIS_REGISTER_RIP : ZYDIS_REGISTER_EIP] = Zydis::RAINone;
|
||||
|
||||
inst.regsReferenced.reserve(ZYDIS_REGISTER_MAX_VALUE + 21);
|
||||
for(int i = ZYDIS_REGISTER_NONE; i <= ZYDIS_REGISTER_MAX_VALUE; ++i)
|
||||
{
|
||||
auto flagAction = instr->accessedFlags[i].action;
|
||||
if(flagAction == ZYDIS_CPUFLAG_ACTION_NONE)
|
||||
continue;
|
||||
|
||||
Zydis::RegAccessInfo rai;
|
||||
switch(flagAction)
|
||||
if(regInfo[i] != Zydis::RAINone)
|
||||
{
|
||||
case ZYDIS_CPUFLAG_ACTION_MODIFIED:
|
||||
case ZYDIS_CPUFLAG_ACTION_SET_0:
|
||||
case ZYDIS_CPUFLAG_ACTION_SET_1:
|
||||
rai = Zydis::RAIWrite;
|
||||
break;
|
||||
case ZYDIS_CPUFLAG_ACTION_TESTED:
|
||||
rai = Zydis::RAIRead;
|
||||
break;
|
||||
default:
|
||||
rai = Zydis::RAINone;
|
||||
break;
|
||||
inst.regsReferenced.emplace_back(zydis.RegName(ZydisRegister(i)), regInfo[i]);
|
||||
}
|
||||
}
|
||||
for(uint8_t i = 0; i < _countof(flagInfo); i++)
|
||||
{
|
||||
auto flag = 1u << i;
|
||||
auto name = zydis.FlagName(flag);
|
||||
auto rai = flagInfo[i];
|
||||
if(name != nullptr && rai != Zydis::RAINone)
|
||||
{
|
||||
inst.regsReferenced.emplace_back(name, rai);
|
||||
}
|
||||
|
||||
reginfo[ZYDIS_REGISTER_RFLAGS] = Zydis::RAINone;
|
||||
reginfo[ZYDIS_REGISTER_EFLAGS] = Zydis::RAINone;
|
||||
reginfo[ZYDIS_REGISTER_FLAGS] = Zydis::RAINone;
|
||||
|
||||
wInst.regsReferenced.emplace_back(cp.FlagName(ZydisCPUFlag(i)), rai);
|
||||
}
|
||||
|
||||
wInst.regsReferenced.reserve(ZYDIS_REGISTER_MAX_VALUE);
|
||||
reginfo[ArchValue(ZYDIS_REGISTER_EIP, ZYDIS_REGISTER_RIP)] = Zydis::RAINone;
|
||||
for(int i = ZYDIS_REGISTER_NONE; i <= ZYDIS_REGISTER_MAX_VALUE; ++i)
|
||||
if(reginfo[i])
|
||||
wInst.regsReferenced.emplace_back(cp.RegName(ZydisRegister(i)), reginfo[i]);
|
||||
|
||||
// Info about volatile and nonvolatile registers
|
||||
if(cp.IsBranchType(Zydis::BranchType::BTCall))
|
||||
if(zydis.IsBranchType(Zydis::BranchType::BTCall))
|
||||
{
|
||||
enum : uint8_t
|
||||
{
|
||||
Volatile = Zydis::RAIImplicit | Zydis::RAIWrite,
|
||||
Parameter = Volatile | Zydis::RAIRead,
|
||||
};
|
||||
#define info(reg, type) wInst.regsReferenced.emplace_back(#reg, type)
|
||||
#define info(reg, type) inst.regsReferenced.emplace_back(#reg, type)
|
||||
|
||||
#ifdef _WIN64
|
||||
// https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions
|
||||
info(rax, Volatile);
|
||||
info(rcx, Parameter);
|
||||
info(rdx, Parameter);
|
||||
info(r8, Parameter);
|
||||
info(r9, Parameter);
|
||||
info(r10, Volatile);
|
||||
info(r11, Volatile);
|
||||
info(xmm0, Parameter);
|
||||
info(ymm0, Parameter);
|
||||
info(xmm1, Parameter);
|
||||
info(ymm1, Parameter);
|
||||
info(xmm2, Parameter);
|
||||
info(ymm2, Parameter);
|
||||
info(xmm3, Parameter);
|
||||
info(ymm3, Parameter);
|
||||
info(xmm4, Parameter);
|
||||
info(ymm4, Parameter);
|
||||
info(xmm5, Parameter);
|
||||
info(ymm5, Parameter);
|
||||
|
||||
#else
|
||||
// https://en.wikipedia.org/wiki/X86_calling_conventions#Caller-saved_(volatile)_registers
|
||||
info(eax, Volatile);
|
||||
info(edx, Volatile);
|
||||
info(ecx, Volatile);
|
||||
#endif // _WIN64
|
||||
if(mArchitecture->disasm64())
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/cpp/build/x64-software-conventions
|
||||
info(rax, Volatile);
|
||||
info(rcx, Parameter);
|
||||
info(rdx, Parameter);
|
||||
info(r8, Parameter);
|
||||
info(r9, Parameter);
|
||||
info(r10, Volatile);
|
||||
info(r11, Volatile);
|
||||
info(xmm0, Parameter);
|
||||
info(ymm0, Parameter);
|
||||
info(xmm1, Parameter);
|
||||
info(ymm1, Parameter);
|
||||
info(xmm2, Parameter);
|
||||
info(ymm2, Parameter);
|
||||
info(xmm3, Parameter);
|
||||
info(ymm3, Parameter);
|
||||
info(xmm4, Parameter);
|
||||
info(ymm4, Parameter);
|
||||
info(xmm5, Parameter);
|
||||
info(ymm5, Parameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/X86_calling_conventions#Caller-saved_(volatile)_registers
|
||||
info(eax, Volatile);
|
||||
info(edx, Volatile);
|
||||
info(ecx, Volatile);
|
||||
}
|
||||
|
||||
#undef info
|
||||
}
|
||||
|
||||
return wInst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
Instruction_t QBeaEngine::DecodeDataAt(const byte_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type)
|
||||
Instruction_t QZydis::DecodeDataAt(const uint8_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type)
|
||||
{
|
||||
//tokenize
|
||||
ZydisTokenizer::InstructionToken cap;
|
||||
|
||||
auto infoIter = dataInstMap.find(type);
|
||||
if(infoIter == dataInstMap.end())
|
||||
infoIter = dataInstMap.find(enc_byte);
|
||||
auto infoIter = mDataInstMap.find(type);
|
||||
if(infoIter == mDataInstMap.end())
|
||||
infoIter = mDataInstMap.find(enc_byte);
|
||||
|
||||
int len = mEncodeMap->getDataSize(origBase + origInstRVA, 1);
|
||||
|
||||
QString mnemonic = _bLongDataInst ? infoIter.value().longName : infoIter.value().shortName;
|
||||
QString mnemonic = mLongDataInst ? infoIter.value().longName : infoIter.value().shortName;
|
||||
|
||||
len = std::min(len, (int)size);
|
||||
|
||||
QString datastr = GetDataTypeString(data, len, type);
|
||||
|
||||
_tokenizer.TokenizeData(mnemonic, datastr, cap);
|
||||
mTokenizer.TokenizeData(mnemonic, datastr, cap);
|
||||
|
||||
Instruction_t inst;
|
||||
inst.instStr = mnemonic + " " + datastr;
|
||||
|
@ -352,35 +350,40 @@ Instruction_t QBeaEngine::DecodeDataAt(const byte_t* data, duint size, duint ori
|
|||
return inst;
|
||||
}
|
||||
|
||||
void QBeaEngine::UpdateDataInstructionMap()
|
||||
void QZydis::UpdateDataInstructionMap()
|
||||
{
|
||||
dataInstMap.clear();
|
||||
dataInstMap.insert(enc_byte, {"db", "byte", "int8"});
|
||||
dataInstMap.insert(enc_word, {"dw", "word", "short"});
|
||||
dataInstMap.insert(enc_dword, {"dd", "dword", "int"});
|
||||
dataInstMap.insert(enc_fword, {"df", "fword", "fword"});
|
||||
dataInstMap.insert(enc_qword, {"dq", "qword", "long"});
|
||||
dataInstMap.insert(enc_tbyte, {"tbyte", "tbyte", "tbyte"});
|
||||
dataInstMap.insert(enc_oword, {"oword", "oword", "oword"});
|
||||
dataInstMap.insert(enc_mmword, {"mmword", "mmword", "long long"});
|
||||
dataInstMap.insert(enc_xmmword, {"xmmword", "xmmword", "_m128"});
|
||||
dataInstMap.insert(enc_ymmword, {"ymmword", "ymmword", "_m256"});
|
||||
dataInstMap.insert(enc_real4, {"real4", "real4", "float"});
|
||||
dataInstMap.insert(enc_real8, {"real8", "real8", "double"});
|
||||
dataInstMap.insert(enc_real10, {"real10", "real10", "long double"});
|
||||
dataInstMap.insert(enc_ascii, {"ascii", "ascii", "string"});
|
||||
dataInstMap.insert(enc_unicode, {"unicode", "unicode", "wstring"});
|
||||
mDataInstMap.clear();
|
||||
mDataInstMap.insert(enc_byte, {"db", "byte", "int8"});
|
||||
mDataInstMap.insert(enc_word, {"dw", "word", "short"});
|
||||
mDataInstMap.insert(enc_dword, {"dd", "dword", "int"});
|
||||
mDataInstMap.insert(enc_fword, {"df", "fword", "fword"});
|
||||
mDataInstMap.insert(enc_qword, {"dq", "qword", "long"});
|
||||
mDataInstMap.insert(enc_tbyte, {"tbyte", "tbyte", "tbyte"});
|
||||
mDataInstMap.insert(enc_oword, {"oword", "oword", "oword"});
|
||||
mDataInstMap.insert(enc_mmword, {"mmword", "mmword", "long long"});
|
||||
mDataInstMap.insert(enc_xmmword, {"xmmword", "xmmword", "_m128"});
|
||||
mDataInstMap.insert(enc_ymmword, {"ymmword", "ymmword", "_m256"});
|
||||
mDataInstMap.insert(enc_real4, {"real4", "real4", "float"});
|
||||
mDataInstMap.insert(enc_real8, {"real8", "real8", "double"});
|
||||
mDataInstMap.insert(enc_real10, {"real10", "real10", "long double"});
|
||||
mDataInstMap.insert(enc_ascii, {"ascii", "ascii", "string"});
|
||||
mDataInstMap.insert(enc_unicode, {"unicode", "unicode", "wstring"});
|
||||
}
|
||||
|
||||
void QBeaEngine::setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager)
|
||||
void QZydis::setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager)
|
||||
{
|
||||
mCodeFoldingManager = CodeFoldingManager;
|
||||
}
|
||||
|
||||
void QBeaEngine::UpdateConfig()
|
||||
void QZydis::UpdateConfig()
|
||||
{
|
||||
_bLongDataInst = ConfigBool("Disassembler", "LongDataInstruction");
|
||||
_tokenizer.UpdateConfig();
|
||||
mLongDataInst = ConfigBool("Disassembler", "LongDataInstruction");
|
||||
mTokenizer.UpdateConfig();
|
||||
}
|
||||
|
||||
void QZydis::UpdateArchitecture()
|
||||
{
|
||||
mTokenizer.UpdateArchitecture();
|
||||
}
|
||||
|
||||
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes)
|
|
@ -0,0 +1,78 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
#include "ZydisTokenizer.h"
|
||||
|
||||
class EncodeMap;
|
||||
class CodeFoldingHelper;
|
||||
|
||||
struct Instruction_t
|
||||
{
|
||||
enum BranchType : uint8_t
|
||||
{
|
||||
None,
|
||||
Conditional,
|
||||
Unconditional,
|
||||
Call
|
||||
};
|
||||
|
||||
duint rva = 0;
|
||||
duint branchDestination = 0;
|
||||
int length = 0;
|
||||
uint8_t vectorElementType[4];
|
||||
uint8_t prefixSize = 0;
|
||||
uint8_t opcodeSize = 0;
|
||||
uint8_t group1Size = 0;
|
||||
uint8_t group2Size = 0;
|
||||
uint8_t group3Size = 0;
|
||||
BranchType branchType = None;
|
||||
|
||||
QString instStr;
|
||||
QByteArray dump;
|
||||
std::vector<std::pair<const char*, uint8_t>> regsReferenced;
|
||||
ZydisTokenizer::InstructionToken tokens;
|
||||
|
||||
Instruction_t()
|
||||
{
|
||||
memset(vectorElementType, 0, sizeof(vectorElementType));
|
||||
}
|
||||
};
|
||||
|
||||
class QZydis
|
||||
{
|
||||
public:
|
||||
QZydis(int maxModuleSize, Architecture* architecture);
|
||||
~QZydis();
|
||||
ulong DisassembleBack(const uint8_t* data, duint base, duint size, duint ip, int n);
|
||||
ulong DisassembleNext(const uint8_t* data, duint base, duint size, duint ip, int n);
|
||||
Instruction_t DisassembleAt(const uint8_t* data, duint size, duint origBase, duint origInstRVA, bool datainstr = true);
|
||||
Instruction_t DecodeDataAt(const uint8_t* data, duint size, duint origBase, duint origInstRVA, ENCODETYPE type);
|
||||
void setCodeFoldingManager(CodeFoldingHelper* CodeFoldingManager);
|
||||
void UpdateConfig();
|
||||
void UpdateArchitecture();
|
||||
|
||||
EncodeMap* getEncodeMap()
|
||||
{
|
||||
return mEncodeMap;
|
||||
}
|
||||
|
||||
private:
|
||||
struct DataInstructionInfo
|
||||
{
|
||||
QString shortName;
|
||||
QString longName;
|
||||
QString cName;
|
||||
};
|
||||
|
||||
void UpdateDataInstructionMap();
|
||||
|
||||
Architecture* mArchitecture = nullptr;
|
||||
ZydisTokenizer mTokenizer;
|
||||
QHash<ENCODETYPE, DataInstructionInfo> mDataInstMap;
|
||||
bool mLongDataInst = false;
|
||||
EncodeMap* mEncodeMap = nullptr;
|
||||
CodeFoldingHelper* mCodeFoldingManager = nullptr;
|
||||
};
|
||||
|
||||
void formatOpcodeString(const Instruction_t & inst, RichTextPainter::List & list, std::vector<std::pair<size_t, bool>> & realBytes);
|
|
@ -2,19 +2,18 @@
|
|||
#include "Configuration.h"
|
||||
#include "StringUtil.h"
|
||||
#include "CachedFontMetrics.h"
|
||||
#include "Bridge.h"
|
||||
|
||||
ZydisTokenizer::ZydisTokenizer(int maxModuleLength)
|
||||
: _maxModuleLength(maxModuleLength),
|
||||
_success(false),
|
||||
isNop(false),
|
||||
_mnemonicType(TokenType::Uncategorized)
|
||||
ZydisTokenizer::ZydisTokenizer(int maxModuleLength, Architecture* architecture)
|
||||
: mMaxModuleLength(maxModuleLength),
|
||||
mZydis(architecture->disasm64()),
|
||||
mArchitecture(architecture)
|
||||
{
|
||||
SetConfig(false, false, false, false, false, false, false, false, false);
|
||||
}
|
||||
|
||||
static ZydisTokenizer::TokenColor colorNamesMap[size_t(ZydisTokenizer::TokenType::Last)];
|
||||
QHash<QString, int> ZydisTokenizer::stringPoolMap;
|
||||
int ZydisTokenizer::poolId = 0;
|
||||
QHash<QString, int> ZydisTokenizer::gStringPool;
|
||||
int ZydisTokenizer::gPoolId = 0;
|
||||
|
||||
void ZydisTokenizer::addColorName(TokenType type, QString color, QString backgroundColor)
|
||||
{
|
||||
|
@ -28,10 +27,10 @@ ZydisTokenizer::TokenColor ZydisTokenizer::getTokenColor(TokenType type)
|
|||
|
||||
void ZydisTokenizer::addStringsToPool(const QString & strings)
|
||||
{
|
||||
QStringList stringList = strings.split(' ', QString::SkipEmptyParts);
|
||||
QStringList stringList = strings.split(' ', Qt::SkipEmptyParts);
|
||||
for(const QString & string : stringList)
|
||||
stringPoolMap.insert(string, poolId);
|
||||
poolId++;
|
||||
gStringPool.insert(string, gPoolId);
|
||||
gPoolId++;
|
||||
}
|
||||
|
||||
void ZydisTokenizer::UpdateColors()
|
||||
|
@ -77,8 +76,8 @@ void ZydisTokenizer::UpdateColors()
|
|||
|
||||
void ZydisTokenizer::UpdateStringPool()
|
||||
{
|
||||
poolId = 0;
|
||||
stringPoolMap.clear();
|
||||
gPoolId = 0;
|
||||
gStringPool.clear();
|
||||
// These registers must be in lower case.
|
||||
addStringsToPool("rax eax ax al ah");
|
||||
addStringsToPool("rbx ebx bx bl bh");
|
||||
|
@ -116,75 +115,75 @@ void ZydisTokenizer::UpdateStringPool()
|
|||
|
||||
bool ZydisTokenizer::Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction)
|
||||
{
|
||||
_inst = InstructionToken();
|
||||
mInst = InstructionToken();
|
||||
|
||||
_success = _cp.DisassembleSafe(addr, data, datasize);
|
||||
if(_success)
|
||||
mSuccess = mZydis.DisassembleSafe(addr, data, datasize);
|
||||
if(mSuccess)
|
||||
{
|
||||
if(!tokenizePrefix())
|
||||
return false;
|
||||
|
||||
isNop = _cp.IsNop();
|
||||
mIsNop = mZydis.IsNop();
|
||||
if(!tokenizeMnemonic())
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < _cp.OpCount(); i++)
|
||||
for(int i = 0; i < mZydis.OpCount(); i++)
|
||||
{
|
||||
if(i == 1 && _cp[0].size >= 128 && _cp[1].type == ZYDIS_OPERAND_TYPE_REGISTER
|
||||
&& ZydisRegisterGetClass(_cp[1].reg.value) == ZYDIS_REGCLASS_MASK)
|
||||
if(i == 1 && mZydis[0].size >= 128 && mZydis[1].type == ZYDIS_OPERAND_TYPE_REGISTER
|
||||
&& ZydisRegisterGetClass(mZydis[1].reg.value) == ZYDIS_REGCLASS_MASK)
|
||||
{
|
||||
if(_bArgumentSpaces)
|
||||
if(mArgumentSpaces)
|
||||
addToken(TokenType::ArgumentSpace, " ");
|
||||
addToken(TokenType::Comma, "{");
|
||||
if(!tokenizeOperand(_cp[i]))
|
||||
if(!tokenizeOperand(mZydis[i]))
|
||||
return false;
|
||||
addToken(TokenType::Comma, "}");
|
||||
}
|
||||
else if(i)
|
||||
{
|
||||
addToken(TokenType::Comma, ",");
|
||||
if(_bArgumentSpaces)
|
||||
if(mArgumentSpaces)
|
||||
addToken(TokenType::ArgumentSpace, " ");
|
||||
if(!tokenizeOperand(_cp[i]))
|
||||
if(!tokenizeOperand(mZydis[i]))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!tokenizeOperand(_cp[i]))
|
||||
if(!tokenizeOperand(mZydis[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isNop = false;
|
||||
mIsNop = false;
|
||||
addToken(TokenType::MnemonicUnusual, "???");
|
||||
}
|
||||
|
||||
if(_bNoHighlightOperands)
|
||||
if(mNoHighlightOperands)
|
||||
{
|
||||
while(_inst.tokens.size() && _inst.tokens[_inst.tokens.size() - 1].type == TokenType::Space)
|
||||
_inst.tokens.pop_back();
|
||||
for(SingleToken & token : _inst.tokens)
|
||||
token.type = _mnemonicType;
|
||||
while(mInst.tokens.size() && mInst.tokens[mInst.tokens.size() - 1].type == TokenType::Space)
|
||||
mInst.tokens.pop_back();
|
||||
for(SingleToken & token : mInst.tokens)
|
||||
token.type = mMnemonicType;
|
||||
}
|
||||
|
||||
instruction = _inst;
|
||||
instruction = mInst;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisTokenizer::TokenizeData(const QString & datatype, const QString & data, InstructionToken & instruction)
|
||||
{
|
||||
_inst = InstructionToken();
|
||||
isNop = false;
|
||||
mInst = InstructionToken();
|
||||
mIsNop = false;
|
||||
|
||||
if(!tokenizeMnemonic(TokenType::MnemonicNormal, datatype))
|
||||
return false;
|
||||
|
||||
addToken(TokenType::Value, data);
|
||||
|
||||
instruction = _inst;
|
||||
instruction = mInst;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -218,40 +217,45 @@ void ZydisTokenizer::TokenizeTraceMemory(duint address, duint oldValue, duint ne
|
|||
|
||||
void ZydisTokenizer::UpdateConfig()
|
||||
{
|
||||
SetConfig(ConfigBool("Disassembler", "Uppercase"),
|
||||
ConfigBool("Disassembler", "TabbedMnemonic"),
|
||||
ConfigBool("Disassembler", "ArgumentSpaces"),
|
||||
ConfigBool("Disassembler", "HidePointerSizes"),
|
||||
ConfigBool("Disassembler", "HideNormalSegments"),
|
||||
ConfigBool("Disassembler", "MemorySpaces"),
|
||||
ConfigBool("Disassembler", "NoHighlightOperands"),
|
||||
ConfigBool("Disassembler", "NoCurrentModuleText"),
|
||||
ConfigBool("Disassembler", "0xPrefixValues"));
|
||||
_maxModuleLength = (int)ConfigUint("Disassembler", "MaxModuleSize");
|
||||
mUppercase = ConfigBool("Disassembler", "Uppercase");
|
||||
mTabbedMnemonic = ConfigBool("Disassembler", "TabbedMnemonic");
|
||||
mArgumentSpaces = ConfigBool("Disassembler", "ArgumentSpaces");
|
||||
mHidePointerSizes = ConfigBool("Disassembler", "HidePointerSizes");
|
||||
mHideNormalSegments = ConfigBool("Disassembler", "HideNormalSegments");
|
||||
mMemorySpaces = ConfigBool("Disassembler", "MemorySpaces");
|
||||
mNoHighlightOperands = ConfigBool("Disassembler", "NoHighlightOperands");
|
||||
mNoCurrentModuleText = ConfigBool("Disassembler", "NoCurrentModuleText");
|
||||
m0xPrefixValues = ConfigBool("Disassembler", "0xPrefixValues");
|
||||
mMaxModuleLength = (int)ConfigUint("Disassembler", "MaxModuleSize");
|
||||
UpdateStringPool();
|
||||
}
|
||||
|
||||
void ZydisTokenizer::UpdateArchitecture()
|
||||
{
|
||||
mZydis.Reset(mArchitecture->disasm64());
|
||||
}
|
||||
|
||||
void ZydisTokenizer::SetConfig(bool bUppercase, bool bTabbedMnemonic, bool bArgumentSpaces, bool bHidePointerSizes, bool bHideNormalSegments, bool bMemorySpaces, bool bNoHighlightOperands, bool bNoCurrentModuleText, bool b0xPrefixValues)
|
||||
{
|
||||
_bUppercase = bUppercase;
|
||||
_bTabbedMnemonic = bTabbedMnemonic;
|
||||
_bArgumentSpaces = bArgumentSpaces;
|
||||
_bHidePointerSizes = bHidePointerSizes;
|
||||
_bHideNormalSegments = bHideNormalSegments;
|
||||
_bMemorySpaces = bMemorySpaces;
|
||||
_bNoHighlightOperands = bNoHighlightOperands;
|
||||
_bNoCurrentModuleText = bNoCurrentModuleText;
|
||||
_b0xPrefixValues = b0xPrefixValues;
|
||||
mUppercase = bUppercase;
|
||||
mTabbedMnemonic = bTabbedMnemonic;
|
||||
mArgumentSpaces = bArgumentSpaces;
|
||||
mHidePointerSizes = bHidePointerSizes;
|
||||
mHideNormalSegments = bHideNormalSegments;
|
||||
mMemorySpaces = bMemorySpaces;
|
||||
mNoHighlightOperands = bNoHighlightOperands;
|
||||
mNoCurrentModuleText = bNoCurrentModuleText;
|
||||
m0xPrefixValues = b0xPrefixValues;
|
||||
}
|
||||
|
||||
int ZydisTokenizer::Size() const
|
||||
{
|
||||
return _success ? _cp.Size() : 1;
|
||||
return mSuccess ? mZydis.Size() : 1;
|
||||
}
|
||||
|
||||
const Zydis & ZydisTokenizer::GetZydis() const
|
||||
{
|
||||
return _cp;
|
||||
return mZydis;
|
||||
}
|
||||
|
||||
void ZydisTokenizer::TokenToRichText(const InstructionToken & instr, RichTextPainter::List & richTextList, const SingleToken* highlightToken)
|
||||
|
@ -317,17 +321,18 @@ bool ZydisTokenizer::IsHighlightableToken(const SingleToken & token)
|
|||
case TokenType::MemoryOperator:
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisTokenizer::tokenTextPoolEquals(const QString & a, const QString & b)
|
||||
{
|
||||
if(a.compare(b, Qt::CaseInsensitive) == 0)
|
||||
return true;
|
||||
auto found1 = stringPoolMap.find(a.toLower());
|
||||
auto found2 = stringPoolMap.find(b.toLower());
|
||||
if(found1 == stringPoolMap.end() || found2 == stringPoolMap.end())
|
||||
auto found1 = gStringPool.find(a.toLower());
|
||||
auto found2 = gStringPool.find(b.toLower());
|
||||
if(found1 == gStringPool.end() || found2 == gStringPool.end())
|
||||
return false;
|
||||
return found1.value() == found2.value();
|
||||
}
|
||||
|
@ -358,9 +363,9 @@ void ZydisTokenizer::addToken(TokenType type, QString text, const TokenValue & v
|
|||
text = text.trimmed();
|
||||
break;
|
||||
}
|
||||
if(_bUppercase && !value.size)
|
||||
if(mUppercase && !value.size)
|
||||
text = text.toUpper();
|
||||
_inst.tokens.push_back(SingleToken(isNop ? TokenType::MnemonicNop : type, text, value));
|
||||
mInst.tokens.push_back(SingleToken(mIsNop ? TokenType::MnemonicNop : type, text, value));
|
||||
}
|
||||
|
||||
void ZydisTokenizer::addToken(TokenType type, const QString & text)
|
||||
|
@ -370,39 +375,39 @@ void ZydisTokenizer::addToken(TokenType type, const QString & text)
|
|||
|
||||
void ZydisTokenizer::addMemoryOperator(char operatorText)
|
||||
{
|
||||
if(_bMemorySpaces)
|
||||
if(mMemorySpaces)
|
||||
addToken(TokenType::MemoryOperatorSpace, " ");
|
||||
QString text;
|
||||
text += operatorText;
|
||||
addToken(TokenType::MemoryOperator, text);
|
||||
if(_bMemorySpaces)
|
||||
if(mMemorySpaces)
|
||||
addToken(TokenType::MemoryOperatorSpace, " ");
|
||||
}
|
||||
|
||||
QString ZydisTokenizer::printValue(const TokenValue & value, bool expandModule, int maxModuleLength) const
|
||||
QString ZydisTokenizer::printValue(const TokenValue & value, bool expandModule) const
|
||||
{
|
||||
QString labelText;
|
||||
char label_[MAX_LABEL_SIZE] = "";
|
||||
char module_[MAX_MODULE_SIZE] = "";
|
||||
char label[MAX_LABEL_SIZE] = "";
|
||||
char module[MAX_MODULE_SIZE] = "";
|
||||
QString moduleText;
|
||||
duint addr = value.value;
|
||||
bool bHasLabel = DbgGetLabelAt(addr, SEG_DEFAULT, label_);
|
||||
labelText = QString(label_);
|
||||
bool bHasLabel = DbgGetLabelAt(addr, SEG_DEFAULT, label);
|
||||
labelText = QString(label);
|
||||
bool bHasModule;
|
||||
if(_bNoCurrentModuleText)
|
||||
if(mNoCurrentModuleText)
|
||||
{
|
||||
duint size, base;
|
||||
base = DbgMemFindBaseAddr(this->GetZydis().Address(), &size);
|
||||
if(addr >= base && addr < base + size)
|
||||
bHasModule = false;
|
||||
else
|
||||
bHasModule = (expandModule && DbgGetModuleAt(addr, module_) && !QString(labelText).startsWith("JMP.&"));
|
||||
bHasModule = (expandModule && DbgGetModuleAt(addr, module) && !QString(labelText).startsWith("JMP.&"));
|
||||
}
|
||||
else
|
||||
bHasModule = (expandModule && DbgGetModuleAt(addr, module_) && !QString(labelText).startsWith("JMP.&"));
|
||||
moduleText = QString(module_);
|
||||
if(maxModuleLength != -1)
|
||||
moduleText.truncate(maxModuleLength);
|
||||
bHasModule = (expandModule && DbgGetModuleAt(addr, module) && !QString(labelText).startsWith("JMP.&"));
|
||||
moduleText = QString(module);
|
||||
if(mMaxModuleLength != -1)
|
||||
moduleText.truncate(mMaxModuleLength);
|
||||
if(moduleText.length())
|
||||
moduleText += ".";
|
||||
QString addrText = ToHexString(addr);
|
||||
|
@ -413,7 +418,7 @@ QString ZydisTokenizer::printValue(const TokenValue & value, bool expandModule,
|
|||
finalText = QString("%1%2").arg(moduleText).arg(addrText);
|
||||
else if(bHasLabel) //<label>
|
||||
finalText = QString("<%1>").arg(labelText);
|
||||
else if(_b0xPrefixValues)
|
||||
else if(m0xPrefixValues)
|
||||
finalText = QString("0x") + addrText;
|
||||
else
|
||||
finalText = addrText;
|
||||
|
@ -422,70 +427,69 @@ QString ZydisTokenizer::printValue(const TokenValue & value, bool expandModule,
|
|||
|
||||
bool ZydisTokenizer::tokenizePrefix()
|
||||
{
|
||||
//TODO: what happens with multiple prefixes?
|
||||
bool hasPrefix = true;
|
||||
QStringList prefixText;
|
||||
|
||||
auto attr = _cp.GetInstr()->attributes;
|
||||
|
||||
if(attr & ZYDIS_ATTRIB_HAS_LOCK)
|
||||
prefixText += "lock";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_REP)
|
||||
prefixText += "rep";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_REPE)
|
||||
prefixText += "repe";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_REPNE)
|
||||
prefixText += "repne";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_BOUND)
|
||||
prefixText += "bnd";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_XACQUIRE)
|
||||
prefixText += "xacquire";
|
||||
else if(attr & ZYDIS_ATTRIB_HAS_XRELEASE)
|
||||
prefixText += "xrelease";
|
||||
else
|
||||
hasPrefix = false;
|
||||
|
||||
if(hasPrefix)
|
||||
auto addPrefix = [this](const QString & prefix)
|
||||
{
|
||||
addToken(TokenType::Prefix, prefixText.join(' '));
|
||||
addToken(TokenType::Prefix, prefix);
|
||||
addToken(TokenType::Space, " ");
|
||||
}
|
||||
};
|
||||
|
||||
auto attr = mZydis.GetInstr()->info.attributes;
|
||||
if(attr & ZYDIS_ATTRIB_HAS_LOCK)
|
||||
addPrefix("lock");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_REP)
|
||||
addPrefix("rep");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_REPE)
|
||||
addPrefix("repe");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_REPNE)
|
||||
addPrefix("repne");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_BND)
|
||||
addPrefix("bnd");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_XACQUIRE)
|
||||
addPrefix("xacquire");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_XRELEASE)
|
||||
addPrefix("xrelease");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_BRANCH_NOT_TAKEN)
|
||||
addPrefix("unlikely");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_BRANCH_TAKEN)
|
||||
addPrefix("likely");
|
||||
if(attr & ZYDIS_ATTRIB_HAS_NOTRACK)
|
||||
addPrefix("notrack");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZydisTokenizer::tokenizeMnemonic()
|
||||
{
|
||||
QString mnemonic = QString(_cp.Mnemonic().c_str());
|
||||
_mnemonicType = TokenType::MnemonicNormal;
|
||||
QString mnemonic = QString(mZydis.Mnemonic().c_str());
|
||||
mMnemonicType = TokenType::MnemonicNormal;
|
||||
|
||||
if(_cp.IsBranchType(Zydis::BTFar))
|
||||
if(mZydis.IsBranchType(Zydis::BTFar))
|
||||
mnemonic += " far";
|
||||
|
||||
if(isNop)
|
||||
_mnemonicType = TokenType::MnemonicNop;
|
||||
else if(_cp.IsInt3())
|
||||
_mnemonicType = TokenType::MnemonicInt3;
|
||||
else if(_cp.IsUnusual())
|
||||
_mnemonicType = TokenType::MnemonicUnusual;
|
||||
else if(_cp.IsBranchType(Zydis::BTCallSem))
|
||||
_mnemonicType = TokenType::MnemonicCall;
|
||||
else if(_cp.IsBranchType(Zydis::BTCondJmpSem))
|
||||
_mnemonicType = TokenType::MnemonicCondJump;
|
||||
else if(_cp.IsBranchType(Zydis::BTUncondJmpSem))
|
||||
_mnemonicType = TokenType::MnemonicUncondJump;
|
||||
else if(_cp.IsBranchType(Zydis::BTRetSem))
|
||||
_mnemonicType = TokenType::MnemonicRet;
|
||||
else if(_cp.IsPushPop())
|
||||
_mnemonicType = TokenType::MnemonicPushPop;
|
||||
if(mIsNop)
|
||||
mMnemonicType = TokenType::MnemonicNop;
|
||||
else if(mZydis.IsInt3())
|
||||
mMnemonicType = TokenType::MnemonicInt3;
|
||||
else if(mZydis.IsUnusual())
|
||||
mMnemonicType = TokenType::MnemonicUnusual;
|
||||
else if(mZydis.IsBranchType(Zydis::BTCallSem))
|
||||
mMnemonicType = TokenType::MnemonicCall;
|
||||
else if(mZydis.IsBranchType(Zydis::BTCondJmpSem))
|
||||
mMnemonicType = TokenType::MnemonicCondJump;
|
||||
else if(mZydis.IsBranchType(Zydis::BTUncondJmpSem))
|
||||
mMnemonicType = TokenType::MnemonicUncondJump;
|
||||
else if(mZydis.IsBranchType(Zydis::BTRetSem))
|
||||
mMnemonicType = TokenType::MnemonicRet;
|
||||
else if(mZydis.IsPushPop())
|
||||
mMnemonicType = TokenType::MnemonicPushPop;
|
||||
|
||||
return tokenizeMnemonic(_mnemonicType, mnemonic);
|
||||
return tokenizeMnemonic(mMnemonicType, mnemonic);
|
||||
}
|
||||
|
||||
bool ZydisTokenizer::tokenizeMnemonic(TokenType type, const QString & mnemonic)
|
||||
{
|
||||
addToken(type, mnemonic);
|
||||
if(_bTabbedMnemonic)
|
||||
if(mTabbedMnemonic)
|
||||
{
|
||||
int spaceCount = 7 - mnemonic.length();
|
||||
if(spaceCount > 0)
|
||||
|
@ -539,12 +543,14 @@ bool ZydisTokenizer::tokenizeRegOperand(const ZydisDecodedOperand & op)
|
|||
case ZYDIS_REGCLASS_MASK:
|
||||
registerType = TokenType::ZmmRegister;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(reg.value == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS))
|
||||
if(reg.value == (mArchitecture->disasm64() ? ZYDIS_REGISTER_GS : ZYDIS_REGISTER_FS))
|
||||
registerType = TokenType::MnemonicUnusual;
|
||||
|
||||
addToken(registerType, _cp.RegName(reg.value));
|
||||
addToken(registerType, mZydis.RegName(reg.value));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -552,20 +558,20 @@ bool ZydisTokenizer::tokenizeImmOperand(const ZydisDecodedOperand & op)
|
|||
{
|
||||
duint value;
|
||||
TokenType valueType;
|
||||
if(_cp.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin))
|
||||
if(mZydis.IsBranchType(Zydis::BTJmp | Zydis::BTCall | Zydis::BTLoop | Zydis::BTXbegin))
|
||||
{
|
||||
valueType = TokenType::Address;
|
||||
value = op.imm.value.u;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto opsize = _cp.GetInstr()->operandWidth;
|
||||
auto opsize = mZydis.GetInstr()->info.operand_width;
|
||||
valueType = TokenType::Value;
|
||||
value = duint(op.imm.value.u) & (duint(-1) >> (sizeof(duint) * 8 - opsize));
|
||||
|
||||
}
|
||||
auto tokenValue = TokenValue(op.size / 8, value);
|
||||
addToken(valueType, printValue(tokenValue, true, _maxModuleLength), tokenValue);
|
||||
addToken(valueType, printValue(tokenValue, true), tokenValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -574,9 +580,9 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
|
|||
auto opsize = op.size / 8;
|
||||
|
||||
//memory size
|
||||
if(!_bHidePointerSizes)
|
||||
if(!mHidePointerSizes)
|
||||
{
|
||||
const char* sizeText = _cp.MemSizeName(opsize);
|
||||
const char* sizeText = mZydis.MemSizeName(opsize);
|
||||
if(sizeText)
|
||||
{
|
||||
addToken(TokenType::MemorySize, QString(sizeText) + " ptr");
|
||||
|
@ -588,11 +594,11 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
|
|||
|
||||
//memory segment
|
||||
bool bUnusualSegment = (mem.segment == ZYDIS_REGISTER_FS || mem.segment == ZYDIS_REGISTER_GS);
|
||||
if(!_bHideNormalSegments || bUnusualSegment)
|
||||
if(!mHideNormalSegments || bUnusualSegment)
|
||||
{
|
||||
auto segmentType = mem.segment == ArchValue(ZYDIS_REGISTER_FS, ZYDIS_REGISTER_GS)
|
||||
auto segmentType = mem.segment == (mArchitecture->disasm64() ? ZYDIS_REGISTER_GS : ZYDIS_REGISTER_FS)
|
||||
? TokenType::MnemonicUnusual : TokenType::MemorySegment;
|
||||
addToken(segmentType, _cp.RegName(mem.segment));
|
||||
addToken(segmentType, mZydis.RegName(mem.segment));
|
||||
addToken(TokenType::Uncategorized, ":");
|
||||
}
|
||||
|
||||
|
@ -613,28 +619,28 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
|
|||
//stuff inside the brackets
|
||||
if(mem.base == ZYDIS_REGISTER_RIP) //rip-relative (#replacement)
|
||||
{
|
||||
duint addr = _cp.Address() + duint(mem.disp.value) + _cp.Size();
|
||||
duint addr = mZydis.Address() + duint(mem.disp.value) + mZydis.Size();
|
||||
TokenValue value = TokenValue(opsize, addr);
|
||||
auto displacementType = DbgMemIsValidReadPtr(addr) ? TokenType::Address : TokenType::Value;
|
||||
addToken(displacementType, printValue(value, false, _maxModuleLength), value);
|
||||
addToken(displacementType, printValue(value, false), value);
|
||||
}
|
||||
else //#base + #index * #scale + #displacement
|
||||
{
|
||||
bool prependPlus = false;
|
||||
if(mem.base != ZYDIS_REGISTER_NONE) //base register
|
||||
{
|
||||
addToken(TokenType::MemoryBaseRegister, _cp.RegName(mem.base));
|
||||
addToken(TokenType::MemoryBaseRegister, mZydis.RegName(mem.base));
|
||||
prependPlus = true;
|
||||
}
|
||||
if(mem.index != ZYDIS_REGISTER_NONE) //index register
|
||||
{
|
||||
if(prependPlus)
|
||||
addMemoryOperator('+');
|
||||
addToken(TokenType::MemoryIndexRegister, _cp.RegName(mem.index));
|
||||
addToken(TokenType::MemoryIndexRegister, mZydis.RegName(mem.index));
|
||||
if(mem.scale > 1)
|
||||
{
|
||||
addMemoryOperator('*');
|
||||
addToken(TokenType::MemoryScale, QString().sprintf("%d", mem.scale));
|
||||
addToken(TokenType::MemoryScale, QString("%1").arg(mem.scale));
|
||||
}
|
||||
prependPlus = true;
|
||||
}
|
||||
|
@ -647,10 +653,10 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
|
|||
if(mem.disp.value < 0 && prependPlus)
|
||||
{
|
||||
operatorText = '-';
|
||||
valueText = printValue(TokenValue(opsize, duint(mem.disp.value * -1)), false, _maxModuleLength);
|
||||
valueText = printValue(TokenValue(opsize, duint(mem.disp.value * -1)), false);
|
||||
}
|
||||
else
|
||||
valueText = printValue(value, false, _maxModuleLength);
|
||||
valueText = printValue(value, false);
|
||||
if(prependPlus)
|
||||
addMemoryOperator(operatorText);
|
||||
addToken(displacementType, valueText, value);
|
||||
|
@ -667,12 +673,12 @@ bool ZydisTokenizer::tokenizeMemOperand(const ZydisDecodedOperand & op)
|
|||
bool ZydisTokenizer::tokenizePtrOperand(const ZydisDecodedOperand & op)
|
||||
{
|
||||
auto segValue = TokenValue(2, op.ptr.segment);
|
||||
addToken(TokenType::MemorySegment, printValue(segValue, true, _maxModuleLength), segValue);
|
||||
addToken(TokenType::MemorySegment, printValue(segValue, true), segValue);
|
||||
|
||||
addToken(TokenType::Uncategorized, ":");
|
||||
|
||||
auto offsetValue = TokenValue(_cp.GetInstr()->operandWidth / 8, op.ptr.offset);
|
||||
addToken(TokenType::Address, printValue(offsetValue, true, _maxModuleLength), offsetValue);
|
||||
auto offsetValue = TokenValue(mZydis.GetInstr()->info.operand_width / 8, op.ptr.offset);
|
||||
addToken(TokenType::Address, printValue(offsetValue, true), offsetValue);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <map>
|
||||
#include <QHash>
|
||||
#include <QtCore>
|
||||
#include "Architecture.h"
|
||||
|
||||
class ZydisTokenizer
|
||||
{
|
||||
|
@ -109,13 +110,7 @@ public:
|
|||
struct InstructionToken
|
||||
{
|
||||
std::vector<SingleToken> tokens; //list of tokens that form the instruction
|
||||
int x; //x of the first character
|
||||
|
||||
InstructionToken()
|
||||
{
|
||||
tokens.clear();
|
||||
x = 0;
|
||||
}
|
||||
int x = 0; //x of the first character
|
||||
};
|
||||
|
||||
struct TokenColor
|
||||
|
@ -152,10 +147,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
ZydisTokenizer(int maxModuleLength);
|
||||
ZydisTokenizer(int maxModuleLength, Architecture* architecture);
|
||||
bool Tokenize(duint addr, const unsigned char* data, int datasize, InstructionToken & instruction);
|
||||
bool TokenizeData(const QString & datatype, const QString & data, InstructionToken & instruction);
|
||||
void UpdateConfig();
|
||||
void UpdateArchitecture();
|
||||
void SetConfig(bool bUppercase, bool bTabbedMnemonic, bool bArgumentSpaces, bool bHidePointerSizes, bool bHideNormalSegments, bool bMemorySpaces, bool bNoHighlightOperands, bool bNoCurrentModuleText, bool b0xPrefixValues);
|
||||
int Size() const;
|
||||
const Zydis & GetZydis() const;
|
||||
|
@ -176,29 +172,30 @@ public:
|
|||
|
||||
|
||||
private:
|
||||
Zydis _cp;
|
||||
bool isNop;
|
||||
InstructionToken _inst;
|
||||
bool _success;
|
||||
int _maxModuleLength;
|
||||
bool _bUppercase;
|
||||
bool _bTabbedMnemonic;
|
||||
bool _bArgumentSpaces;
|
||||
bool _bHidePointerSizes;
|
||||
bool _bHideNormalSegments;
|
||||
bool _bMemorySpaces;
|
||||
bool _bNoHighlightOperands;
|
||||
bool _bNoCurrentModuleText;
|
||||
bool _b0xPrefixValues;
|
||||
TokenType _mnemonicType;
|
||||
Architecture* mArchitecture;
|
||||
Zydis mZydis;
|
||||
bool mSuccess = false;
|
||||
bool mIsNop = false;
|
||||
InstructionToken mInst;
|
||||
TokenType mMnemonicType = TokenType::Uncategorized;
|
||||
int mMaxModuleLength = -1;
|
||||
bool mUppercase = false;
|
||||
bool mTabbedMnemonic = false;
|
||||
bool mArgumentSpaces = false;
|
||||
bool mHidePointerSizes = false;
|
||||
bool mHideNormalSegments = false;
|
||||
bool mMemorySpaces = false;
|
||||
bool mNoHighlightOperands = false;
|
||||
bool mNoCurrentModuleText = false;
|
||||
bool m0xPrefixValues = false;
|
||||
|
||||
void addToken(TokenType type, QString text, const TokenValue & value);
|
||||
void addToken(TokenType type, const QString & text);
|
||||
void addMemoryOperator(char operatorText);
|
||||
QString printValue(const TokenValue & value, bool expandModule, int maxModuleLength) const;
|
||||
QString printValue(const TokenValue & value, bool expandModule) const;
|
||||
|
||||
static QHash<QString, int> stringPoolMap;
|
||||
static int poolId;
|
||||
static QHash<QString, int> gStringPool;
|
||||
static int gPoolId;
|
||||
|
||||
bool tokenizePrefix();
|
||||
bool tokenizeMnemonic();
|
||||
|
|
|
@ -22,14 +22,14 @@ BreakpointsView::BreakpointsView(QWidget* parent)
|
|||
addColumnAt(0, tr("Summary"), true);
|
||||
loadColumnFromConfig("BreakpointsView");
|
||||
|
||||
mDisasm = new QBeaEngine(ConfigUint("Disassembler", "MaxModuleSize"));
|
||||
mDisasm = new QZydis(ConfigUint("Disassembler", "MaxModuleSize"), Bridge::getArch());
|
||||
mDisasm->UpdateConfig();
|
||||
enableMultiSelection(true);
|
||||
|
||||
setupContextMenu();
|
||||
|
||||
connect(Bridge::getBridge(), SIGNAL(updateBreakpoints()), this, SLOT(updateBreakpointsSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
|
||||
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerConfigUpdatedSlot()));
|
||||
|
||||
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
|
||||
|
@ -139,7 +139,7 @@ void BreakpointsView::updateColors()
|
|||
updateBreakpointsSlot();
|
||||
}
|
||||
|
||||
void BreakpointsView::sortRows(int column, bool ascending)
|
||||
void BreakpointsView::sortRows(duint column, bool ascending)
|
||||
{
|
||||
std::stable_sort(mData.begin(), mData.end(), [this, column, ascending](const std::vector<CellData> & a, const std::vector<CellData> & b)
|
||||
{
|
||||
|
@ -161,15 +161,15 @@ void BreakpointsView::sortRows(int column, bool ascending)
|
|||
});
|
||||
}
|
||||
|
||||
QString BreakpointsView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
||||
QString BreakpointsView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||
{
|
||||
if(isSelected(rowBase, rowOffset))
|
||||
if(isSelected(row))
|
||||
painter->fillRect(QRect(x, y, w, h), QBrush(col == ColDisasm ? mDisasmSelectionColor : mSelectionColor));
|
||||
else if(col == ColDisasm)
|
||||
painter->fillRect(QRect(x, y, w, h), QBrush(mDisasmBackgroundColor));
|
||||
auto index = bpIndex(rowBase + rowOffset);
|
||||
auto index = bpIndex(row);
|
||||
auto & bp = mBps.at(index);
|
||||
auto cellContent = getCellContent(rowBase + rowOffset, col);
|
||||
auto cellContent = getCellContent(row, col);
|
||||
if(col > ColType && !bp.addr && !bp.active)
|
||||
{
|
||||
auto mid = h / 2.0;
|
||||
|
@ -556,7 +556,7 @@ void BreakpointsView::updateBreakpointsSlot()
|
|||
reloadData();
|
||||
}
|
||||
|
||||
void BreakpointsView::disassembleAtSlot(dsint addr, dsint cip)
|
||||
void BreakpointsView::disassembleAtSlot(duint addr, duint cip)
|
||||
{
|
||||
Q_UNUSED(addr);
|
||||
mCip = cip;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <QWidget>
|
||||
#include "Bridge.h"
|
||||
#include "StdTable.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
|
||||
class MenuBuilder;
|
||||
|
||||
|
@ -16,12 +16,12 @@ public:
|
|||
protected:
|
||||
void setupContextMenu();
|
||||
void updateColors() override;
|
||||
void sortRows(int column, bool ascending) override;
|
||||
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
|
||||
void sortRows(duint column, bool ascending) override;
|
||||
QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
|
||||
|
||||
private slots:
|
||||
void updateBreakpointsSlot();
|
||||
void disassembleAtSlot(dsint addr, dsint cip);
|
||||
void disassembleAtSlot(duint addr, duint cip);
|
||||
void tokenizerConfigUpdatedSlot();
|
||||
void contextMenuSlot(const QPoint & pos);
|
||||
void followBreakpointSlot();
|
||||
|
@ -64,7 +64,7 @@ private:
|
|||
duint mCip = 0;
|
||||
MenuBuilder* mMenuBuilder;
|
||||
QAction* mEnableDisableAction;
|
||||
QBeaEngine* mDisasm;
|
||||
QZydis* mDisasm;
|
||||
|
||||
const int bpIndex(int i) const
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "WordEditDialog.h"
|
||||
#include "XrefBrowseDialog.h"
|
||||
#include "Bridge.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
|
||||
CPUInfoBox::CPUInfoBox(QWidget* parent) : StdTable(parent)
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ CPUInfoBox::CPUInfoBox(QWidget* parent) : StdTable(parent)
|
|||
setSingleSelection(-1);
|
||||
|
||||
int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize");
|
||||
mDisasm = new QBeaEngine(maxModuleSize);
|
||||
mDisasm = new QZydis(maxModuleSize, Bridge::getArch());
|
||||
|
||||
setupContextMenu();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
class WordEditDialog;
|
||||
class XrefBrowseDialog;
|
||||
class QBeaEngine;
|
||||
class QZydis;
|
||||
|
||||
class CPUInfoBox : public StdTable
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ private:
|
|||
void setupContextMenu();
|
||||
void setupShortcuts();
|
||||
XrefBrowseDialog* mXrefDlg = nullptr;
|
||||
QBeaEngine* mDisasm;
|
||||
QZydis* mDisasm;
|
||||
|
||||
QAction* mCopyAddressAction;
|
||||
QAction* mCopyRvaAction;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "DisassemblerGraphView.h"
|
||||
#include "MenuBuilder.h"
|
||||
#include "CachedFontMetrics.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
#include "GotoDialog.h"
|
||||
#include "XrefBrowseDialog.h"
|
||||
#include <vector>
|
||||
|
@ -21,7 +21,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget* parent)
|
|||
: QAbstractScrollArea(parent),
|
||||
mFontMetrics(nullptr),
|
||||
currentGraph(duint(0)),
|
||||
disasm(ConfigUint("Disassembler", "MaxModuleSize")),
|
||||
disasm(ConfigUint("Disassembler", "MaxModuleSize"), Bridge::getArch()),
|
||||
mCip(0),
|
||||
mGoto(nullptr),
|
||||
syncOrigin(false),
|
||||
|
@ -72,7 +72,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget* parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(graphAt(duint)), this, SLOT(graphAtSlot(duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(updateGraph()), this, SLOT(updateGraphSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionGraphGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(getCurrentGraph(BridgeCFGraphList*)), this, SLOT(getCurrentGraphSlot(BridgeCFGraphList*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChangedSlot(DBGSTATE)));
|
||||
|
||||
|
@ -2522,7 +2522,7 @@ void DisassemblerGraphView::selectionGetSlot(SELECTIONDATA* selection)
|
|||
Bridge::getBridge()->setResult(BridgeResult::SelectionGet, 1);
|
||||
}
|
||||
|
||||
void DisassemblerGraphView::disassembleAtSlot(dsint va, dsint cip)
|
||||
void DisassemblerGraphView::disassembleAtSlot(duint va, duint cip)
|
||||
{
|
||||
Q_UNUSED(va);
|
||||
auto cipChanged = mCip != cip;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <QMutex>
|
||||
#include "Bridge.h"
|
||||
#include "RichTextPainter.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
#include "ActionHelpers.h"
|
||||
#include "VaHistory.h"
|
||||
|
||||
|
@ -273,7 +273,7 @@ public slots:
|
|||
void selectionGetSlot(SELECTIONDATA* selection);
|
||||
void tokenizerConfigUpdatedSlot();
|
||||
void loadCurrentGraph();
|
||||
void disassembleAtSlot(dsint va, dsint cip);
|
||||
void disassembleAtSlot(duint va, duint cip);
|
||||
void gotoExpressionSlot();
|
||||
void gotoOriginSlot();
|
||||
void gotoPreviousSlot();
|
||||
|
@ -386,7 +386,7 @@ private:
|
|||
|
||||
BridgeCFGraph currentGraph;
|
||||
std::unordered_map<duint, duint> currentBlockMap;
|
||||
QBeaEngine disasm;
|
||||
QZydis disasm;
|
||||
GotoDialog* mGoto;
|
||||
XrefBrowseDialog* mXrefDlg;
|
||||
|
||||
|
|
|
@ -5,14 +5,19 @@
|
|||
#include "MiscUtil.h"
|
||||
#include <QPainter>
|
||||
#include <QStyleOptionFrame>
|
||||
#include "Bridge.h"
|
||||
|
||||
DisassemblyPopup::DisassemblyPopup(QWidget* parent) :
|
||||
DisassemblyPopup::DisassemblyPopup(AbstractTableView* parent, Architecture* architecture) :
|
||||
QFrame(parent, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus),
|
||||
mFontMetrics(nullptr),
|
||||
mDisasm(ConfigUint("Disassembler", "MaxModuleSize"))
|
||||
mDisasm(ConfigUint("Disassembler", "MaxModuleSize"), architecture),
|
||||
mParent(parent)
|
||||
{
|
||||
addr = 0;
|
||||
addrText = nullptr;
|
||||
parent->installEventFilter(this);
|
||||
parent->setMouseTracking(true);
|
||||
connect(parent->verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(hide()));
|
||||
connect(parent->horizontalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(hide()));
|
||||
|
||||
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateFont()));
|
||||
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateColors()));
|
||||
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerConfigUpdated()));
|
||||
|
@ -20,22 +25,22 @@ DisassemblyPopup::DisassemblyPopup(QWidget* parent) :
|
|||
updateColors();
|
||||
setFrameStyle(QFrame::Panel);
|
||||
setLineWidth(2);
|
||||
mMaxInstructions = 20;
|
||||
}
|
||||
|
||||
void DisassemblyPopup::updateColors()
|
||||
{
|
||||
disassemblyBackgroundColor = ConfigColor("DisassemblyBackgroundColor");
|
||||
disassemblyTracedColor = ConfigColor("DisassemblyTracedBackgroundColor");
|
||||
labelColor = ConfigColor("DisassemblyLabelColor");
|
||||
labelBackgroundColor = ConfigColor("DisassemblyLabelBackgroundColor");
|
||||
commentColor = ConfigColor("DisassemblyCommentColor");
|
||||
commentBackgroundColor = ConfigColor("DisassemblyCommentBackgroundColor");
|
||||
commentAutoColor = ConfigColor("DisassemblyAutoCommentColor");
|
||||
commentAutoBackgroundColor = ConfigColor("DisassemblyAutoCommentBackgroundColor");
|
||||
QPalette palette;
|
||||
palette.setColor(QPalette::Foreground, ConfigColor("AbstractTableViewSeparatorColor"));
|
||||
setPalette(palette);
|
||||
mDisassemblyBackgroundColor = ConfigColor("DisassemblyBackgroundColor");
|
||||
mDisassemblyTracedColor = ConfigColor("DisassemblyTracedBackgroundColor");
|
||||
mLabelColor = ConfigColor("DisassemblyLabelColor");
|
||||
mLabelBackgroundColor = ConfigColor("DisassemblyLabelBackgroundColor");
|
||||
mCommentColor = ConfigColor("DisassemblyCommentColor");
|
||||
mCommentBackgroundColor = ConfigColor("DisassemblyCommentBackgroundColor");
|
||||
mCommentAutoColor = ConfigColor("DisassemblyAutoCommentColor");
|
||||
mCommentAutoBackgroundColor = ConfigColor("DisassemblyAutoCommentBackgroundColor");
|
||||
// TODO: fix this
|
||||
//QPalette palette;
|
||||
//palette.setColor(QPalette::Foreground, ConfigColor("AbstractTableViewSeparatorColor"));
|
||||
//setPalette(palette);
|
||||
}
|
||||
|
||||
void DisassemblyPopup::tokenizerConfigUpdated()
|
||||
|
@ -50,8 +55,8 @@ void DisassemblyPopup::updateFont()
|
|||
QFontMetricsF metrics(font());
|
||||
mFontMetrics = new CachedFontMetrics(this, font());
|
||||
// Update font size, used in layout calculations.
|
||||
charWidth = mFontMetrics->width('W');
|
||||
charHeight = metrics.height();
|
||||
mCharWidth = mFontMetrics->width('W');
|
||||
mCharHeight = metrics.height();
|
||||
}
|
||||
|
||||
void DisassemblyPopup::paintEvent(QPaintEvent* event)
|
||||
|
@ -61,29 +66,29 @@ void DisassemblyPopup::paintEvent(QPaintEvent* event)
|
|||
p.setFont(font());
|
||||
|
||||
// Render background
|
||||
p.fillRect(viewportRect, disassemblyBackgroundColor);
|
||||
p.fillRect(viewportRect, mDisassemblyBackgroundColor);
|
||||
// Draw Address
|
||||
p.setPen(QPen(labelColor));
|
||||
int addrWidth = mFontMetrics->width(addrText);
|
||||
p.fillRect(3, 2 + lineWidth(), addrWidth, charHeight, QBrush(labelBackgroundColor));
|
||||
p.drawText(3, 2, addrWidth, charHeight, 0, addrText);
|
||||
p.setPen(QPen(mLabelColor));
|
||||
int addrWidth = mFontMetrics->width(mAddrText);
|
||||
p.fillRect(3, 2 + lineWidth(), addrWidth, mCharHeight, QBrush(mLabelBackgroundColor));
|
||||
p.drawText(3, 2, addrWidth, mCharHeight, 0, mAddrText);
|
||||
// Draw Comments
|
||||
if(!addrComment.isEmpty())
|
||||
if(!mAddrComment.isEmpty())
|
||||
{
|
||||
int commentWidth = mFontMetrics->width(addrComment);
|
||||
QBrush background = QBrush(addrCommentAuto ? commentAutoBackgroundColor : commentBackgroundColor);
|
||||
p.setPen(addrCommentAuto ? commentAutoColor : commentColor);
|
||||
p.fillRect(3 + addrWidth, 2, commentWidth, charHeight, background);
|
||||
p.drawText(3 + addrWidth, 2, commentWidth, charHeight, 0, addrComment);
|
||||
int commentWidth = mFontMetrics->width(mAddrComment);
|
||||
QBrush background = QBrush(mAddrCommentAuto ? mCommentAutoBackgroundColor : mCommentBackgroundColor);
|
||||
p.setPen(mAddrCommentAuto ? mCommentAutoColor : mCommentColor);
|
||||
p.fillRect(3 + addrWidth, 2, commentWidth, mCharHeight, background);
|
||||
p.drawText(3 + addrWidth, 2, commentWidth, mCharHeight, 0, mAddrComment);
|
||||
}
|
||||
// Draw Instructions
|
||||
int y = charHeight + 1;
|
||||
int y = mCharHeight + 1;
|
||||
for(auto & instruction : mDisassemblyToken)
|
||||
{
|
||||
if(instruction.second)
|
||||
p.fillRect(QRect(3, y, mWidth - 3, charHeight), disassemblyTracedColor);
|
||||
RichTextPainter::paintRichText(&p, 3, y, mWidth - 3, charHeight, 0, instruction.first, mFontMetrics);
|
||||
y += charHeight;
|
||||
p.fillRect(QRect(3, y, mWidth - 3, mCharHeight), mDisassemblyTracedColor);
|
||||
RichTextPainter::paintRichText(&p, 3, y, mWidth - 3, mCharHeight, 0, instruction.first, mFontMetrics);
|
||||
y += mCharHeight;
|
||||
}
|
||||
|
||||
// The code above will destroy the stylesheet adjustments, making it impossible to change the border color.
|
||||
|
@ -95,12 +100,88 @@ void DisassemblyPopup::paintEvent(QPaintEvent* event)
|
|||
QFrame::paintEvent(event);
|
||||
}
|
||||
|
||||
bool DisassemblyPopup::eventFilter(QObject* object, QEvent* event)
|
||||
{
|
||||
if(object == parent())
|
||||
{
|
||||
switch(event->type())
|
||||
{
|
||||
case QEvent::Leave:
|
||||
case QEvent::Hide:
|
||||
case QEvent::KeyPress:
|
||||
{
|
||||
hide();
|
||||
}
|
||||
break;
|
||||
|
||||
case QEvent::MouseMove:
|
||||
{
|
||||
hide();
|
||||
|
||||
auto mouseEvent = (QMouseEvent*)event;
|
||||
auto x = mouseEvent->x();
|
||||
auto y = mouseEvent->y();
|
||||
|
||||
// TODO: make sure the cursor isn't on the column separators
|
||||
if(y > mParent->getHeaderHeight())
|
||||
{
|
||||
mLastX = x;
|
||||
mLastY = y;
|
||||
if(mPopupTimer != 0)
|
||||
killTimer(mPopupTimer);
|
||||
mPopupTimer = startTimer(QApplication::startDragTime());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QFrame::eventFilter(object, event);
|
||||
}
|
||||
|
||||
void DisassemblyPopup::timerEvent(QTimerEvent* event)
|
||||
{
|
||||
if(event->timerId() == mPopupTimer)
|
||||
{
|
||||
// Kill the timer
|
||||
killTimer(mPopupTimer);
|
||||
mPopupTimer = 0;
|
||||
|
||||
// Show the popup if relevant for the current position
|
||||
auto addr = mParent->getAddressForPosition(mLastX, mLastY);
|
||||
if(getAddress() != addr)
|
||||
{
|
||||
if(DbgFunctions()->MemIsCodePage(addr, false))
|
||||
{
|
||||
move(mParent->mapToGlobal(QPoint(mLastX + 20, mLastY + fontMetrics().height() * 2)));
|
||||
setAddress(addr);
|
||||
show();
|
||||
}
|
||||
else
|
||||
{
|
||||
hide();
|
||||
if(mPopupTimer != 0)
|
||||
{
|
||||
mPopupTimer = 0;
|
||||
killTimer(mPopupTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QFrame::timerEvent(event);
|
||||
}
|
||||
|
||||
void DisassemblyPopup::setAddress(duint Address)
|
||||
{
|
||||
addr = Address;
|
||||
mAddr = Address;
|
||||
QList<Instruction_t> instBuffer;
|
||||
mDisassemblyToken.clear();
|
||||
if(addr != 0)
|
||||
mDisasm.UpdateArchitecture();
|
||||
if(mAddr != 0)
|
||||
{
|
||||
mWidth = 1;
|
||||
// Get RVA
|
||||
|
@ -113,7 +194,7 @@ void DisassemblyPopup::setAddress(duint Address)
|
|||
auto nextAddr = addr;
|
||||
bool hadBranch = false;
|
||||
duint bestBranch = 0;
|
||||
byte data[64];
|
||||
uint8_t data[64];
|
||||
do
|
||||
{
|
||||
if(nextAddr >= base + size)
|
||||
|
@ -160,27 +241,27 @@ void DisassemblyPopup::setAddress(duint Address)
|
|||
mDisassemblyToken.push_back(std::make_pair(std::move(richText), DbgFunctions()->GetTraceRecordHitCount(instruction.rva) != 0));
|
||||
}
|
||||
// Address
|
||||
addrText = getSymbolicName(addr);
|
||||
mAddrText = getSymbolicName(addr);
|
||||
// Comments
|
||||
GetCommentFormat(addr, addrComment, &addrCommentAuto);
|
||||
if(addrComment.length())
|
||||
addrText.append(' ');
|
||||
GetCommentFormat(addr, mAddrComment, &mAddrCommentAuto);
|
||||
if(mAddrComment.length())
|
||||
mAddrText.append(' ');
|
||||
// Calculate width of address
|
||||
mWidth = std::max(mWidth, mFontMetrics->width(addrText) + mFontMetrics->width(addrComment));
|
||||
mWidth += charWidth * 6;
|
||||
mWidth = std::max(mWidth, mFontMetrics->width(mAddrText) + mFontMetrics->width(mAddrComment));
|
||||
mWidth += mCharWidth * 6;
|
||||
// Resize popup
|
||||
resize(mWidth + 2, charHeight * int(mDisassemblyToken.size() + 1) + 2);
|
||||
resize(mWidth + 2, mCharHeight * int(mDisassemblyToken.size() + 1) + 2);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
duint DisassemblyPopup::getAddress()
|
||||
duint DisassemblyPopup::getAddress() const
|
||||
{
|
||||
return addr;
|
||||
return mAddr;
|
||||
}
|
||||
|
||||
void DisassemblyPopup::hide()
|
||||
{
|
||||
addr = 0;
|
||||
mAddr = 0;
|
||||
QFrame::hide();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
#include <QFrame>
|
||||
#include "Imports.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
#include "AbstractTableView.h"
|
||||
|
||||
class CachedFontMetrics;
|
||||
|
||||
|
@ -10,10 +11,9 @@ class DisassemblyPopup : public QFrame
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DisassemblyPopup(QWidget* parent);
|
||||
void paintEvent(QPaintEvent* event);
|
||||
DisassemblyPopup(AbstractTableView* parent, Architecture* architecture);
|
||||
void setAddress(duint Address);
|
||||
duint getAddress();
|
||||
duint getAddress() const;
|
||||
|
||||
public slots:
|
||||
void hide();
|
||||
|
@ -22,25 +22,33 @@ public slots:
|
|||
void tokenizerConfigUpdated();
|
||||
|
||||
protected:
|
||||
CachedFontMetrics* mFontMetrics;
|
||||
duint addr;
|
||||
QString addrText;
|
||||
QString addrComment;
|
||||
bool addrCommentAuto;
|
||||
int charWidth;
|
||||
int charHeight;
|
||||
int mWidth;
|
||||
unsigned int mMaxInstructions;
|
||||
void paintEvent(QPaintEvent* event) override;
|
||||
bool eventFilter(QObject* object, QEvent* event) override;
|
||||
void timerEvent(QTimerEvent* event) override;
|
||||
|
||||
QColor disassemblyBackgroundColor;
|
||||
QColor disassemblyTracedColor;
|
||||
QColor labelColor;
|
||||
QColor labelBackgroundColor;
|
||||
QColor commentColor;
|
||||
QColor commentBackgroundColor;
|
||||
QColor commentAutoColor;
|
||||
QColor commentAutoBackgroundColor;
|
||||
QBeaEngine mDisasm;
|
||||
CachedFontMetrics* mFontMetrics = nullptr;
|
||||
duint mAddr = 0;
|
||||
QString mAddrText;
|
||||
QString mAddrComment;
|
||||
bool mAddrCommentAuto = false;
|
||||
int mCharWidth = 0;
|
||||
int mCharHeight = 0;
|
||||
int mWidth = 0;
|
||||
int mPopupTimer = 0;
|
||||
int mLastX = 0;
|
||||
int mLastY = 0;
|
||||
unsigned int mMaxInstructions = 20;
|
||||
|
||||
QColor mDisassemblyBackgroundColor;
|
||||
QColor mDisassemblyTracedColor;
|
||||
QColor mLabelColor;
|
||||
QColor mLabelBackgroundColor;
|
||||
QColor mCommentColor;
|
||||
QColor mCommentBackgroundColor;
|
||||
QColor mCommentAutoColor;
|
||||
QColor mCommentAutoBackgroundColor;
|
||||
QZydis mDisasm;
|
||||
AbstractTableView* mParent = nullptr;
|
||||
|
||||
std::vector<std::pair<RichTextPainter::List, bool>> mDisassemblyToken;
|
||||
};
|
||||
|
|
|
@ -19,7 +19,6 @@ MemoryMapView::MemoryMapView(StdTable* parent)
|
|||
{
|
||||
setDrawDebugOnly(true);
|
||||
enableMultiSelection(true);
|
||||
setDisassemblyPopupEnabled(false);
|
||||
|
||||
int charwidth = getCharWidth();
|
||||
|
||||
|
@ -38,7 +37,7 @@ MemoryMapView::MemoryMapView(StdTable* parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(stateChangedSlot(DBGSTATE)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectInMemoryMap(duint)), this, SLOT(selectAddress(duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionMemmapGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
|
||||
connect(Bridge::getBridge(), SIGNAL(focusMemmap()), this, SLOT(setFocus()));
|
||||
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
|
||||
|
||||
|
@ -283,11 +282,10 @@ static QString getProtectionString(DWORD Protect)
|
|||
return QString(rights);
|
||||
}
|
||||
|
||||
QString MemoryMapView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
||||
QString MemoryMapView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||
{
|
||||
if(col == 0) //address
|
||||
{
|
||||
int row = rowBase + rowOffset;
|
||||
auto addr = getCellUserdata(row, ColAddress);
|
||||
QColor color = mTextColor;
|
||||
QColor backgroundColor = Qt::transparent;
|
||||
|
@ -308,25 +306,25 @@ QString MemoryMapView::paintContent(QPainter* painter, dsint rowBase, int rowOff
|
|||
color = ConfigColor("MemoryMapCipColor");
|
||||
backgroundColor = ConfigColor("MemoryMapCipBackgroundColor");
|
||||
}
|
||||
else if(isSelected(rowBase, rowOffset) == true)
|
||||
else if(isSelected(row) == true)
|
||||
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
|
||||
|
||||
if(backgroundColor.alpha())
|
||||
painter->fillRect(QRect(x, y, w - 1, h), QBrush(backgroundColor));
|
||||
painter->setPen(color);
|
||||
QString wStr = getCellContent(rowBase + rowOffset, col);
|
||||
painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr);
|
||||
QString str = getCellContent(row, col);
|
||||
painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, str);
|
||||
return QString();
|
||||
}
|
||||
else if(col == ColPageInfo) //info
|
||||
{
|
||||
QString wStr = StdIconTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
|
||||
auto addr = getCellUserdata(rowBase + rowOffset, ColAddress);
|
||||
if(wStr.contains(" \""))
|
||||
QString str = StdIconTable::paintContent(painter, row, col, x, y, w, h);
|
||||
auto addr = getCellUserdata(row, ColAddress);
|
||||
if(str.contains(" \""))
|
||||
{
|
||||
auto idx = wStr.indexOf(" \"");
|
||||
auto pre = wStr.mid(0, idx);
|
||||
auto post = wStr.mid(idx);
|
||||
auto idx = str.indexOf(" \"");
|
||||
auto pre = str.mid(0, idx);
|
||||
auto post = str.mid(idx);
|
||||
RichTextPainter::List richText;
|
||||
RichTextPainter::CustomRichText_t entry;
|
||||
entry.flags = RichTextPainter::FlagColor;
|
||||
|
@ -346,21 +344,21 @@ QString MemoryMapView::paintContent(QPainter* painter, dsint rowBase, int rowOff
|
|||
{
|
||||
auto party = DbgFunctions()->ModGetParty(addr);
|
||||
painter->setPen(ConfigColor(party == mod_user ? "SymbolUserTextColor" : "SymbolSystemTextColor"));
|
||||
painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr);
|
||||
painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, str);
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
else if(col == ColCurProtect) //CPROT
|
||||
{
|
||||
QString wStr = StdIconTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);;
|
||||
QString str = StdIconTable::paintContent(painter, row, col, x, y, w, h);;
|
||||
if(!ConfigBool("Engine", "ListAllPages"))
|
||||
{
|
||||
painter->setPen(ConfigColor("MemoryMapSectionTextColor"));
|
||||
painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr);
|
||||
painter->drawText(QRect(x + 4, y, getColumnWidth(col) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, str);
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
return StdIconTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
|
||||
return StdIconTable::paintContent(painter, row, col, x, y, w, h);
|
||||
}
|
||||
|
||||
void MemoryMapView::setSwitchViewName()
|
||||
|
@ -679,13 +677,15 @@ void MemoryMapView::selectAddress(duint va)
|
|||
if(base)
|
||||
{
|
||||
auto rows = getRowCount();
|
||||
for(dsint row = 0; row < rows; row++)
|
||||
for(duint row = 0; row < rows; row++)
|
||||
{
|
||||
if(getCellUserdata(row, ColAddress) == base)
|
||||
{
|
||||
scrollSelect(row);
|
||||
reloadData();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
SimpleErrorBox(this, tr("Error"), tr("Address %0 not found in memory map...").arg(ToPtrString(va)));
|
||||
}
|
||||
|
@ -737,7 +737,7 @@ void MemoryMapView::selectionGetSlot(SELECTIONDATA* selection)
|
|||
Bridge::getBridge()->setResult(BridgeResult::SelectionGet, 1);
|
||||
}
|
||||
|
||||
void MemoryMapView::disassembleAtSlot(dsint va, dsint cip)
|
||||
void MemoryMapView::disassembleAtSlot(duint va, duint cip)
|
||||
{
|
||||
Q_UNUSED(va)
|
||||
mCipBase = DbgMemFindBaseAddr(cip, nullptr);;
|
||||
|
@ -745,11 +745,11 @@ void MemoryMapView::disassembleAtSlot(dsint va, dsint cip)
|
|||
|
||||
void MemoryMapView::commentSlot()
|
||||
{
|
||||
duint wVA = getSelectionAddr();
|
||||
duint va = getSelectionAddr();
|
||||
LineEditDialog mLineEdit(this);
|
||||
QString addr_text = ToPtrString(wVA);
|
||||
QString addr_text = ToPtrString(va);
|
||||
char comment_text[MAX_COMMENT_SIZE] = "";
|
||||
if(DbgGetCommentAt((duint)wVA, comment_text))
|
||||
if(DbgGetCommentAt((duint)va, comment_text))
|
||||
{
|
||||
if(comment_text[0] == '\1') //automatic comment
|
||||
mLineEdit.setText(QString(comment_text + 1));
|
||||
|
@ -759,7 +759,7 @@ void MemoryMapView::commentSlot()
|
|||
mLineEdit.setWindowTitle(tr("Add comment at ") + addr_text);
|
||||
if(mLineEdit.exec() != QDialog::Accepted)
|
||||
return;
|
||||
if(!DbgSetCommentAt(wVA, mLineEdit.editText.replace('\r', "").replace('\n', "").toUtf8().constData()))
|
||||
if(!DbgSetCommentAt(va, mLineEdit.editText.replace('\r', "").replace('\n', "").toUtf8().constData()))
|
||||
SimpleErrorBox(this, tr("Error!"), tr("DbgSetCommentAt failed!"));
|
||||
|
||||
GuiUpdateMemoryView();
|
||||
|
|
|
@ -16,7 +16,6 @@ ScriptView::ScriptView(StdTable* parent) : StdTable(parent)
|
|||
enableMultiSelection(false);
|
||||
enableColumnSorting(false);
|
||||
setDrawDebugOnly(false);
|
||||
setDisassemblyPopupEnabled(false);
|
||||
|
||||
int charwidth = getCharWidth();
|
||||
|
||||
|
@ -54,7 +53,7 @@ ScriptView::ScriptView(StdTable* parent) : StdTable(parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(scriptMessage(QString)), this, SLOT(message(QString)));
|
||||
connect(Bridge::getBridge(), SIGNAL(scriptQuestion(QString)), this, SLOT(question(QString)));
|
||||
connect(Bridge::getBridge(), SIGNAL(scriptEnableHighlighting(bool)), this, SLOT(enableHighlighting(bool)));
|
||||
connect(Bridge::getBridge(), SIGNAL(shutdown()), this, SLOT(shutdownSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(close()), this, SLOT(shutdownSlot()));
|
||||
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
|
||||
|
||||
Initialize();
|
||||
|
@ -68,14 +67,14 @@ void ScriptView::updateColors()
|
|||
mBackgroundColor = ConfigColor("DisassemblyBackgroundColor");
|
||||
}
|
||||
|
||||
QString ScriptView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
||||
QString ScriptView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||
{
|
||||
bool wIsSelected = isSelected(rowBase, rowOffset);
|
||||
bool rowSelected = isSelected(row);
|
||||
// Highlight if selected
|
||||
if(wIsSelected)
|
||||
if(rowSelected)
|
||||
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor)); //ScriptViewSelectionColor
|
||||
QString returnString;
|
||||
int line = rowBase + rowOffset + 1;
|
||||
int line = row + 1;
|
||||
SCRIPTLINETYPE linetype = DbgScriptGetLineType(line);
|
||||
switch(col)
|
||||
{
|
||||
|
@ -131,7 +130,7 @@ QString ScriptView::paintContent(QPainter* painter, dsint rowBase, int rowOffset
|
|||
RichTextPainter::List richText;
|
||||
RichTextPainter::CustomRichText_t newRichText;
|
||||
newRichText.underline = false;
|
||||
QString command = getCellContent(rowBase + rowOffset, col);
|
||||
QString command = getCellContent(row, col);
|
||||
|
||||
//handle comments
|
||||
int comment_idx = command.indexOf("\1"); //find the index of the comment
|
||||
|
@ -312,13 +311,13 @@ QString ScriptView::paintContent(QPainter* painter, dsint rowBase, int rowOffset
|
|||
returnString = "";
|
||||
}
|
||||
else //no syntax highlighting
|
||||
returnString = getCellContent(rowBase + rowOffset, col);
|
||||
returnString = getCellContent(row, col);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: //info
|
||||
{
|
||||
returnString = getCellContent(rowBase + rowOffset, col);
|
||||
returnString = getCellContent(row, col);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
mSymbolSystemTextColor = ConfigColor("SymbolSystemTextColor");
|
||||
}
|
||||
|
||||
QColor getCellColor(int r, int c) override
|
||||
QColor getCellColor(duint r, duint c) override
|
||||
{
|
||||
if(c == ColParty || c == ColPath)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
QString getCellContent(int r, int c) override
|
||||
QString getCellContent(duint r, duint c) override
|
||||
{
|
||||
if(c != ColStatus)
|
||||
return StdTable::getCellContent(r, c);
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
MODULESYMBOLSTATUS getStatus(int r)
|
||||
MODULESYMBOLSTATUS getStatus(duint r)
|
||||
{
|
||||
return DbgFunctions()->ModSymbolStatus(getCellUserdata(r, 0));
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ public:
|
|||
return mSearchList;
|
||||
}
|
||||
|
||||
void filter(const QString & filter, FilterType type, int startColumn) override
|
||||
void filter(const QString & filter, FilterType type, duint startColumn) override
|
||||
{
|
||||
mSearchList->setRowCount(0);
|
||||
int newRowCount = 0;
|
||||
|
@ -179,7 +179,6 @@ SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView
|
|||
mModuleList->setSearchStartCol(ColBase);
|
||||
mModuleList->enableMultiSelection(true);
|
||||
mModuleList->setAddressColumn(ColBase, true);
|
||||
mModuleList->setDisassemblyPopupEnabled(false);
|
||||
int charwidth = mModuleList->getCharWidth();
|
||||
mModuleList->addColumnAt(8 + charwidth * 2 * sizeof(dsint), tr("Base"), true);
|
||||
mModuleList->addColumnAt(300, tr("Module"), true);
|
||||
|
@ -220,8 +219,8 @@ SymbolView::SymbolView(QWidget* parent) : QWidget(parent), ui(new Ui::SymbolView
|
|||
connect(Bridge::getBridge(), SIGNAL(clearLog()), this, SLOT(clearSymbolLogSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(clearSymbolLog()), this, SLOT(clearSymbolLogSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionSymmodGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||
connect(mModuleList->stdList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(moduleSelectionChanged(int)));
|
||||
connect(mModuleList->stdSearchList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(moduleSelectionChanged(int)));
|
||||
connect(mModuleList->stdList(), SIGNAL(selectionChanged(duint)), this, SLOT(moduleSelectionChanged(duint)));
|
||||
connect(mModuleList->stdSearchList(), SIGNAL(selectionChanged(duint)), this, SLOT(moduleSelectionChanged(duint)));
|
||||
connect(mModuleList, SIGNAL(emptySearchResult()), this, SLOT(emptySearchResultSlot()));
|
||||
connect(mModuleList, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(moduleContextMenu(QMenu*)));
|
||||
connect(mModuleList, SIGNAL(enterPressedSignal()), this, SLOT(moduleFollow()));
|
||||
|
@ -425,7 +424,7 @@ void SymbolView::clearSymbolLogSlot()
|
|||
ui->symbolLogEdit->clear();
|
||||
}
|
||||
|
||||
void SymbolView::moduleSelectionChanged(int index)
|
||||
void SymbolView::moduleSelectionChanged(duint index)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
setUpdatesEnabled(false);
|
||||
|
@ -559,7 +558,7 @@ void SymbolView::symbolFollowImport()
|
|||
|
||||
void SymbolView::symbolSelectModule(duint base)
|
||||
{
|
||||
for(dsint i = 0; i < mModuleList->stdList()->getRowCount(); i++)
|
||||
for(duint i = 0; i < mModuleList->stdList()->getRowCount(); i++)
|
||||
{
|
||||
if(mModuleList->stdList()->getCellUserdata(i, ColBase) == base)
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "RichTextPainter.h"
|
||||
#include "main.h"
|
||||
#include "BrowseDialog.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
#include "GotoDialog.h"
|
||||
#include "CommonActions.h"
|
||||
#include "LineEditDialog.h"
|
||||
|
@ -55,7 +55,7 @@ TraceBrowser::TraceBrowser(QWidget* parent) : AbstractTableView(parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(gotoTraceIndex(duint)), this, SLOT(gotoIndexSlot(duint)));
|
||||
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerConfigUpdatedSlot()));
|
||||
connect(this, SIGNAL(selectionChanged(unsigned long long)), this, SLOT(selectionChangedSlot(unsigned long long)));
|
||||
connect(Bridge::getBridge(), SIGNAL(shutdown()), this, SLOT(closeFileSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(close()), this, SLOT(closeFileSlot()));
|
||||
}
|
||||
|
||||
TraceBrowser::~TraceBrowser()
|
||||
|
@ -286,7 +286,7 @@ int TraceBrowser::paintFunctionGraphic(QPainter* painter, int x, int y, Function
|
|||
return x_add + line_width + end_add;
|
||||
}
|
||||
|
||||
QString TraceBrowser::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
||||
QString TraceBrowser::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||
{
|
||||
if(!isFileOpened())
|
||||
{
|
||||
|
@ -311,7 +311,7 @@ QString TraceBrowser::paintContent(QPainter* painter, dsint rowBase, int rowOffs
|
|||
painter->drawRect(rect);
|
||||
}
|
||||
|
||||
duint index = rowBase + rowOffset;
|
||||
duint index = row;
|
||||
duint cur_addr;
|
||||
REGDUMP reg;
|
||||
reg = mTraceFile->Registers(index);
|
||||
|
@ -403,7 +403,7 @@ QString TraceBrowser::paintContent(QPainter* painter, dsint rowBase, int rowOffs
|
|||
{
|
||||
NotDebuggingLabel:
|
||||
QColor background;
|
||||
if(wIsSelected)
|
||||
if(rowSelected)
|
||||
{
|
||||
background = mSelectedAddressBackgroundColor;
|
||||
painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor)
|
||||
|
@ -431,7 +431,7 @@ NotDebuggingLabel:
|
|||
else //other cases (memory breakpoint in disassembly) -> do as normal
|
||||
{
|
||||
QColor background;
|
||||
if(wIsSelected)
|
||||
if(rowSelected)
|
||||
{
|
||||
background = mSelectedAddressBackgroundColor;
|
||||
painter->setPen(mSelectedAddressColor); //black address (DisassemblySelectedAddressColor)
|
||||
|
@ -569,25 +569,25 @@ NotDebuggingLabel:
|
|||
next_addr = mTraceFile->Registers(index + 1).regcontext.cip;
|
||||
if(next_addr < cur_addr)
|
||||
{
|
||||
QPoint wPoints[] =
|
||||
QPoint points[] =
|
||||
{
|
||||
QPoint(x + funcsize, y + halfRow + 1),
|
||||
QPoint(x + funcsize + 2, y + halfRow - 1),
|
||||
QPoint(x + funcsize + 4, y + halfRow + 1),
|
||||
};
|
||||
jumpsize = 8;
|
||||
painter->drawPolyline(wPoints, 3);
|
||||
painter->drawPolyline(points, 3);
|
||||
}
|
||||
else if(next_addr > cur_addr)
|
||||
{
|
||||
QPoint wPoints[] =
|
||||
QPoint points[] =
|
||||
{
|
||||
QPoint(x + funcsize, y + halfRow - 1),
|
||||
QPoint(x + funcsize + 2, y + halfRow + 1),
|
||||
QPoint(x + funcsize + 4, y + halfRow - 1),
|
||||
};
|
||||
jumpsize = 8;
|
||||
painter->drawPolyline(wPoints, 3);
|
||||
painter->drawPolyline(points, 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1102,7 +1102,7 @@ void TraceBrowser::mouseDoubleClickEvent(QMouseEvent* event)
|
|||
|
||||
void TraceBrowser::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
dsint index = getIndexOffsetFromY(transY(event->y())) + getTableOffset();
|
||||
duint index = getIndexOffsetFromY(transY(event->y())) + getTableOffset();
|
||||
if((event->buttons() & Qt::LeftButton) != 0 && getGuiState() == AbstractTableView::NoState && mTraceFile != nullptr && mTraceFile->Progress() == 100)
|
||||
{
|
||||
if(index < getRowCount())
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "AbstractTableView.h"
|
||||
#include "VaHistory.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
|
||||
class TraceFileReader;
|
||||
class BreakpointMenu;
|
||||
|
@ -16,7 +16,7 @@ public:
|
|||
explicit TraceBrowser(QWidget* parent = 0);
|
||||
~TraceBrowser() override;
|
||||
|
||||
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
|
||||
QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
|
||||
|
||||
void prepareData() override;
|
||||
void updateColors() override;
|
||||
|
|
|
@ -18,7 +18,7 @@ TraceFileReader::TraceFileReader(QObject* parent) : QObject(parent)
|
|||
EXEPath.clear();
|
||||
|
||||
int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize");
|
||||
mDisasm = new QBeaEngine(maxModuleSize);
|
||||
mDisasm = new QZydis(maxModuleSize, Bridge::getArch());
|
||||
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerUpdatedSlot()));
|
||||
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(tokenizerUpdatedSlot()));
|
||||
}
|
||||
|
@ -705,7 +705,7 @@ void TraceFilePage::OpCode(unsigned long long index, unsigned char* buffer, int*
|
|||
memcpy(buffer, opcodes.constData() + opcodeOffset.at(index), *opcodeSize);
|
||||
}
|
||||
|
||||
const Instruction_t & TraceFilePage::Instruction(unsigned long long index, QBeaEngine & mDisasm)
|
||||
const Instruction_t & TraceFilePage::Instruction(unsigned long long index, QZydis & mDisasm)
|
||||
{
|
||||
if(instructions.size() == 0)
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
class TraceFileParser;
|
||||
class TraceFilePage;
|
||||
class QBeaEngine;
|
||||
class QZydis;
|
||||
struct Instruction_t;
|
||||
|
||||
#define MAX_MEMORY_OPERANDS 32
|
||||
|
@ -73,5 +73,5 @@ private:
|
|||
std::map<Range, TraceFilePage, RangeCompare> pages;
|
||||
TraceFilePage* getPage(unsigned long long index, unsigned long long* base);
|
||||
|
||||
QBeaEngine* mDisasm;
|
||||
QZydis* mDisasm;
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <QThread>
|
||||
#include "TraceFileReader.h"
|
||||
#include "QBeaEngine.h"
|
||||
#include "QZydis.h"
|
||||
|
||||
class TraceFileParser : public QThread
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ public:
|
|||
unsigned long long Length() const;
|
||||
const REGDUMP & Registers(unsigned long long index) const;
|
||||
void OpCode(unsigned long long index, unsigned char* buffer, int* opcodeSize) const;
|
||||
const Instruction_t & Instruction(unsigned long long index, QBeaEngine & mDisasm);
|
||||
const Instruction_t & Instruction(unsigned long long index, QZydis & mDisasm);
|
||||
DWORD ThreadId(unsigned long long index) const;
|
||||
int MemoryAccessCount(unsigned long long index) const;
|
||||
void MemoryAccessInfo(unsigned long long index, duint* address, duint* oldMemory, duint* newMemory, bool* isValid) const;
|
||||
|
|
|
@ -170,9 +170,6 @@ int main(int argc, char* argv[])
|
|||
|
||||
TLS_TranslatedStringMap = new std::map<DWORD, TranslatedStringStorage>();
|
||||
|
||||
// initialize Zydis
|
||||
Zydis::GlobalInitialize();
|
||||
|
||||
// load config file + set config font
|
||||
mConfiguration = new Configuration;
|
||||
application.setFont(ConfigFont("Application"));
|
||||
|
|
|
@ -49,7 +49,7 @@ QMAKE_CXXFLAGS_RELEASE += -Zi # Compiler
|
|||
QMAKE_LFLAGS_RELEASE += /DEBUG # Linker
|
||||
|
||||
# Build as a library
|
||||
DEFINES += BUILD_LIB NOMINMAX
|
||||
DEFINES += BUILD_LIB NOMINMAX X64DBG
|
||||
TEMPLATE = lib
|
||||
|
||||
##
|
||||
|
@ -66,8 +66,7 @@ INCLUDEPATH += \
|
|||
Src/Global \
|
||||
Src/Utils \
|
||||
Src/ThirdPartyLibs/ldconvert \
|
||||
../zydis_wrapper \
|
||||
../zydis_wrapper/zydis/include
|
||||
../zydis_wrapper
|
||||
|
||||
# Resources, sources, headers, and forms
|
||||
RESOURCES += \
|
||||
|
@ -76,6 +75,7 @@ RESOURCES += \
|
|||
SOURCES += \
|
||||
Src/BasicView/StdIconSearchListView.cpp \
|
||||
Src/BasicView/StdIconTable.cpp \
|
||||
Src/Disassembler/QZydis.cpp \
|
||||
Src/Gui/CPURegistersView.cpp \
|
||||
Src/Gui/RichTextItemDelegate.cpp \
|
||||
Src/Gui/SystemBreakpointScriptDialog.cpp \
|
||||
|
@ -91,7 +91,6 @@ SOURCES += \
|
|||
Src/BasicView/Disassembly.cpp \
|
||||
Src/BasicView/HexDump.cpp \
|
||||
Src/BasicView/AbstractTableView.cpp \
|
||||
Src/Disassembler/QBeaEngine.cpp \
|
||||
Src/Disassembler/ZydisTokenizer.cpp \
|
||||
Src/Memory/MemoryPage.cpp \
|
||||
Src/Bridge/Bridge.cpp \
|
||||
|
@ -195,10 +194,10 @@ SOURCES += \
|
|||
Src/BasicView/StdTableSearchList.cpp \
|
||||
Src/Utils/BackgroundFlickerThread.cpp
|
||||
|
||||
|
||||
HEADERS += \
|
||||
Src/BasicView/StdIconSearchListView.h \
|
||||
Src/BasicView/StdIconTable.h \
|
||||
Src/Disassembler/QZydis.h \
|
||||
Src/Gui/CPURegistersView.h \
|
||||
Src/Gui/RichTextItemDelegate.h \
|
||||
Src/Gui/SystemBreakpointScriptDialog.h \
|
||||
|
@ -213,7 +212,6 @@ HEADERS += \
|
|||
Src/BasicView/Disassembly.h \
|
||||
Src/BasicView/HexDump.h \
|
||||
Src/BasicView/AbstractTableView.h \
|
||||
Src/Disassembler/QBeaEngine.h \
|
||||
Src/Disassembler/ZydisTokenizer.h \
|
||||
Src/Memory/MemoryPage.h \
|
||||
Src/Bridge/Bridge.h \
|
||||
|
@ -325,7 +323,6 @@ HEADERS += \
|
|||
Src/BasicView/StdTableSearchList.h \
|
||||
Src/Utils/MethodInvoker.h \
|
||||
Src/Utils/BackgroundFlickerThread.h
|
||||
|
||||
|
||||
FORMS += \
|
||||
Src/Gui/SystemBreakpointScriptDialog.ui \
|
||||
|
|
|
@ -858,6 +858,36 @@ void Zydis::RegInfo(uint8_t regs[ZYDIS_REGISTER_MAX_VALUE + 1]) const
|
|||
}
|
||||
}
|
||||
|
||||
void Zydis::FlagInfo(uint8_t info[32]) const
|
||||
{
|
||||
auto instr = GetInstr();
|
||||
if(instr == nullptr)
|
||||
{
|
||||
memset(info, 0, 32);
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint8_t i = 0; i < 32; i++)
|
||||
{
|
||||
auto flag = 1u << i;
|
||||
uint8_t rai = Zydis::RAINone;
|
||||
if(FlagName(flag) != nullptr)
|
||||
{
|
||||
const auto & flags = *instr->info.cpu_flags;
|
||||
if((flags.tested & flag) == flag)
|
||||
{
|
||||
rai |= Zydis::RAIRead;
|
||||
}
|
||||
auto writeMask = flags.modified | flags.set_0 | flags.set_1 | flags.undefined;
|
||||
if((writeMask & flag) == flag)
|
||||
{
|
||||
rai |= Zydis::RAIWrite;
|
||||
}
|
||||
}
|
||||
info[i] = rai;
|
||||
}
|
||||
}
|
||||
|
||||
const char* Zydis::FlagName(uint32_t flag) const
|
||||
{
|
||||
switch(flag)
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
};
|
||||
|
||||
void RegInfo(uint8_t info[ZYDIS_REGISTER_MAX_VALUE + 1]) const;
|
||||
void FlagInfo(uint8_t info[32]) const;
|
||||
const char* FlagName(uint32_t flag) const;
|
||||
|
||||
enum BranchType : uint32_t
|
||||
|
|
Loading…
Reference in New Issue