1
0
Fork 0

GUI: resolved issue #232 (copy in dump windows)

This commit is contained in:
mrexodia 2016-06-03 21:34:41 +02:00
parent abe53d3492
commit 597298f90f
No known key found for this signature in database
GPG Key ID: D72F9A4FAA0073B4
6 changed files with 311 additions and 270 deletions

View File

@ -2,6 +2,7 @@
#include "Configuration.h"
#include "Bridge.h"
#include "StringUtil.h"
#include <QMessageBox>
HexDump::HexDump(QWidget* parent)
: AbstractTableView(parent)
@ -31,6 +32,7 @@ HexDump::HexDump(QWidget* parent)
// Slots
connect(Bridge::getBridge(), SIGNAL(updateDump()), this, SLOT(updateDumpSlot()));
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChanged(DBGSTATE)));
setupCopyMenu();
Initialize();
}
@ -55,6 +57,13 @@ void HexDump::updateFonts()
setFont(ConfigFont("HexDump"));
}
void HexDump::updateShortcuts()
{
AbstractTableView::updateShortcuts();
mCopyAddress->setShortcut(ConfigShortcut("ActionCopyAddress"));
mCopySelection->setShortcut(ConfigShortcut("ActionCopy"));
}
void HexDump::updateDumpSlot()
{
if(mSyncAddrExpression.length() && DbgFunctions()->ValFromString)
@ -69,6 +78,11 @@ void HexDump::updateDumpSlot()
reloadData();
}
void HexDump::copySelectionSlot()
{
Bridge::CopyToClipboard(makeCopyText());
}
void HexDump::printDumpAt(dsint parVA, bool select, bool repaint, bool updateTableOffset)
{
dsint wBase = DbgMemFindBaseAddr(parVA, 0); //get memory base
@ -126,6 +140,79 @@ duint HexDump::getTableOffsetRva()
return getTableOffset() * getBytePerRowCount() - mByteOffset;
}
QString HexDump::makeAddrText(duint va)
{
char label[MAX_LABEL_SIZE] = "";
QString addrText = "";
dsint cur_addr = va;
if(mRvaDisplayEnabled) //RVA display
{
dsint rva = cur_addr - mRvaDisplayBase;
if(rva == 0)
{
#ifdef _WIN64
addrText = "$ ==> ";
#else
addrText = "$ ==> ";
#endif //_WIN64
}
else if(rva > 0)
{
#ifdef _WIN64
addrText = "$+" + QString("%1").arg(rva, -15, 16, QChar(' ')).toUpper();
#else
addrText = "$+" + QString("%1").arg(rva, -7, 16, QChar(' ')).toUpper();
#endif //_WIN64
}
else if(rva < 0)
{
#ifdef _WIN64
addrText = "$-" + QString("%1").arg(-rva, -15, 16, QChar(' ')).toUpper();
#else
addrText = "$-" + QString("%1").arg(-rva, -7, 16, QChar(' ')).toUpper();
#endif //_WIN64
}
}
addrText += ToPtrString(cur_addr);
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label
{
char module[MAX_MODULE_SIZE] = "";
if(DbgGetModuleAt(cur_addr, module) && !QString(label).startsWith("JMP.&"))
addrText += " <" + QString(module) + "." + QString(label) + ">";
else
addrText += " <" + QString(label) + ">";
}
else
*label = 0;
return addrText;
}
QString HexDump::makeCopyText()
{
dsint deltaRowBase = getSelectionStart() % getBytePerRowCount() + mByteOffset;
if(deltaRowBase >= getBytePerRowCount())
deltaRowBase -= getBytePerRowCount();
auto curRow = getSelectionStart() - deltaRowBase;
QString result;
while(curRow < getSelectionEnd())
{
for(int col = 0; col < getColumnCount(); col++)
{
if(col)
result += " ";
RichTextPainter::List richText;
getColumnRichText(col, curRow, richText);
QString colText;
for(auto & r : richText)
colText += r.text;
result += colText.leftJustified(getColumnWidth(col) / getCharWidth(), QChar(' '), true);
}
curRow += getBytePerRowCount();
result += "\n";
}
return result;
}
void HexDump::addVaToHistory(dsint parVa)
{
//truncate everything right from the current VA
@ -177,6 +264,44 @@ void HexDump::historyClear()
mVaHistory.clear();
}
void HexDump::setupCopyMenu()
{
// Copy -> Data
mCopySelection = new QAction(tr("&Selection"), this);
connect(mCopySelection, SIGNAL(triggered(bool)), this, SLOT(copySelectionSlot()));
mCopySelection->setShortcutContext(Qt::WidgetShortcut);
addAction(mCopySelection);
// Copy -> Address
mCopyAddress = new QAction(tr("&Address"), this);
connect(mCopyAddress, SIGNAL(triggered()), this, SLOT(copyAddressSlot()));
mCopyAddress->setShortcutContext(Qt::WidgetShortcut);
addAction(mCopyAddress);
// Copy -> RVA
mCopyRva = new QAction("&RVA", this);
connect(mCopyRva, SIGNAL(triggered()), this, SLOT(copyRvaSlot()));
}
void HexDump::copyAddressSlot()
{
QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper();
Bridge::CopyToClipboard(addrText);
}
void HexDump::copyRvaSlot()
{
duint addr = rvaToVa(getInitialSelection());
duint base = DbgFunctions()->ModBaseFromAddr(addr);
if(base)
{
QString addrText = QString("%1").arg(addr - base, 0, 16, QChar('0')).toUpper();
Bridge::CopyToClipboard(addrText);
}
else
QMessageBox::warning(this, "Error!", "Selection not in a module...");
}
void HexDump::mouseMoveEvent(QMouseEvent* event)
{
bool wAccept = true;
@ -332,20 +457,14 @@ QString HexDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, i
int wBytePerRowCount = getBytePerRowCount();
dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
QString wStr = "";
if(col == 0) // Addresses
{
wStr += QString("%1").arg(rvaToVa(wRva), sizeof(dsint) * 2, 16, QChar('0')).toUpper();
}
else if(mDescriptor.at(col - 1).isData == true) //paint data
{
if(col && mDescriptor.at(col - 1).isData)
printSelected(painter, rowBase, rowOffset, col, x, y, w, h);
RichTextPainter::List richText;
getString(col - 1, wRva, richText);
RichTextPainter::paintRichText(painter, x, y, w, h, 4, richText, getCharWidth());
}
return wStr;
RichTextPainter::List richText;
getColumnRichText(col, wRva, richText);
RichTextPainter::paintRichText(painter, x, y, w, h, 4, richText, getCharWidth());
return "";
}
void HexDump::printSelected(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
@ -434,45 +553,56 @@ bool HexDump::isSelected(dsint rva)
return false;
}
void HexDump::getString(int col, dsint rva, RichTextPainter::List & richText)
void HexDump::getColumnRichText(int col, dsint rva, RichTextPainter::List & richText)
{
int wI;
QString wStr = "";
int wByteCount = getSizeOf(mDescriptor.at(col).data.itemSize);
int wBufferByteCount = mDescriptor.at(col).itemCount * wByteCount;
wBufferByteCount = wBufferByteCount > (dsint)(mMemPage->getSize() - rva) ? mMemPage->getSize() - rva : wBufferByteCount;
byte_t* wData = new byte_t[wBufferByteCount];
//byte_t wData[mDescriptor.at(col).itemCount * wByteCount];
mMemPage->read(wData, rva, wBufferByteCount);
RichTextPainter::CustomRichText_t curData;
curData.highlight = false;
curData.flags = RichTextPainter::FlagColor;
QColor highlightColor = ConfigColor("HexDumpModifiedBytesColor");
for(wI = 0; wI < mDescriptor.at(col).itemCount && (rva + wI) < (dsint)mMemPage->getSize(); wI++)
curData.textColor = textColor;
if(!col) //address
{
int maxLen = getStringMaxLength(mDescriptor.at(col).data);
QString append = " ";
if(!maxLen)
append = "";
if((rva + wI + wByteCount - 1) < (dsint)mMemPage->getSize())
wStr = toString(mDescriptor.at(col).data, (void*)(wData + wI * wByteCount)).rightJustified(maxLen, ' ') + append;
else
wStr = QString("?").rightJustified(maxLen, ' ') + append;
curData.text = wStr;
dsint start = rvaToVa(rva + wI * wByteCount);
dsint end = start + wByteCount - 1;
curData.textColor = DbgFunctions()->PatchInRange(start, end) ? highlightColor : textColor;
curData.text = makeAddrText(rvaToVa(rva));
richText.push_back(curData);
}
else if(mDescriptor.at(col - 1).isData == true)
{
int wI;
QString wStr = "";
delete[] wData;
int wByteCount = getSizeOf(mDescriptor.at(col - 1).data.itemSize);
int wBufferByteCount = mDescriptor.at(col - 1).itemCount * wByteCount;
wBufferByteCount = wBufferByteCount > (dsint)(mMemPage->getSize() - rva) ? mMemPage->getSize() - rva : wBufferByteCount;
byte_t* wData = new byte_t[wBufferByteCount];
//byte_t wData[mDescriptor.at(col).itemCount * wByteCount];
mMemPage->read(wData, rva, wBufferByteCount);
QColor highlightColor = ConfigColor("HexDumpModifiedBytesColor");
for(wI = 0; wI < mDescriptor.at(col - 1).itemCount && (rva + wI) < (dsint)mMemPage->getSize(); wI++)
{
int maxLen = getStringMaxLength(mDescriptor.at(col - 1).data);
QString append = " ";
if(!maxLen)
append = "";
if((rva + wI + wByteCount - 1) < (dsint)mMemPage->getSize())
wStr = toString(mDescriptor.at(col - 1).data, (void*)(wData + wI * wByteCount)).rightJustified(maxLen, ' ') + append;
else
wStr = QString("?").rightJustified(maxLen, ' ') + append;
curData.text = wStr;
dsint start = rvaToVa(rva + wI * wByteCount);
dsint end = start + wByteCount - 1;
if(DbgFunctions()->PatchInRange(start, end))
curData.textColor = highlightColor;
else
curData.textColor = textColor;
richText.push_back(curData);
}
delete[] wData;
}
}
QString HexDump::toString(DataDescriptor_t desc, void* data) //convert data to string

View File

@ -82,6 +82,7 @@ public:
// Configuration
virtual void updateColors();
virtual void updateFonts();
virtual void updateShortcuts();
//QString getStringToPrint(int rowBase, int rowOffset, int col);
void mouseMoveEvent(QMouseEvent* event);
@ -101,7 +102,7 @@ public:
dsint getSelectionEnd();
bool isSelected(dsint rva);
void getString(int col, dsint rva, RichTextPainter::List & richText);
virtual void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText);
int getSizeOf(DataSize_e size);
QString toString(DataDescriptor_t desc, void* data);
@ -134,6 +135,8 @@ public:
void printDumpAt(dsint parVA, bool select, bool repaint = true, bool updateTableOffset = true);
duint rvaToVa(dsint rva);
duint getTableOffsetRva();
QString makeAddrText(duint va);
QString makeCopyText();
void addVaToHistory(dsint parVa);
bool historyHasPrev();
@ -142,6 +145,8 @@ public:
void historyNext();
void historyClear();
void setupCopyMenu();
signals:
void selectionUpdated();
@ -149,6 +154,9 @@ public slots:
void printDumpAt(dsint parVA);
void debugStateChanged(DBGSTATE state);
void updateDumpSlot();
void copySelectionSlot();
void copyAddressSlot();
void copyRvaSlot();
private:
enum GuiState_t {NoState, MultiRowsSelectionState};
@ -176,6 +184,9 @@ protected:
duint mRvaDisplayBase;
dsint mRvaDisplayPageBase;
QString mSyncAddrExpression;
QAction* mCopyAddress;
QAction* mCopyRva;
QAction* mCopySelection;
};
#endif // _HEXDUMP_H

View File

@ -459,22 +459,7 @@ void CPUDump::setupContextMenu()
mPluginMenu->setIcon(QIcon(":/icons/images/plugin.png"));
Bridge::getBridge()->emitMenuAddToList(this, mPluginMenu, GUI_DUMP_MENU);
//Copy
mCopyMenu = new QMenu(tr("&Copy"), this);
mCopyMenu->setIcon(QIcon(":/icons/images/copy.png"));
// Copy -> Address
mCopyAddress = new QAction(tr("&Address"), this);
connect(mCopyAddress, SIGNAL(triggered()), this, SLOT(copyAddressSlot()));
mCopyAddress->setShortcutContext(Qt::WidgetShortcut);
this->addAction(mCopyAddress);
mCopyMenu->addAction(mCopyAddress);
// Copy -> RVA
mCopyRva = new QAction("&RVA", this);
connect(mCopyRva, SIGNAL(triggered()), this, SLOT(copyRvaSlot()));
mCopyMenu->addAction(mCopyRva);
updateShortcuts();
refreshShortcutsSlot();
connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcutsSlot()));
}
@ -497,7 +482,51 @@ void CPUDump::refreshShortcutsSlot()
mGotoEnd->setShortcut(ConfigShortcut("ActionGotoEnd"));
mGotoFileOffset->setShortcut(ConfigShortcut("ActionGotoFileOffset"));
mYaraAction->setShortcut(ConfigShortcut("ActionYara"));
mCopyAddress->setShortcut(ConfigShortcut("ActionCopyAddress"));
}
void CPUDump::getColumnRichText(int col, dsint rva, RichTextPainter::List & richText)
{
if(col && !mDescriptor.at(col - 1).isData && mDescriptor.at(col - 1).itemCount) //print comments
{
RichTextPainter::CustomRichText_t curData;
curData.flags = RichTextPainter::FlagColor;
curData.textColor = textColor;
duint data = 0;
mMemPage->read((byte_t*)&data, rva, sizeof(duint));
char modname[MAX_MODULE_SIZE] = "";
if(!DbgGetModuleAt(data, modname))
modname[0] = '\0';
char label_text[MAX_LABEL_SIZE] = "";
if(DbgGetLabelAt(data, SEG_DEFAULT, label_text))
curData.text = QString(modname) + "." + QString(label_text);
char string_text[MAX_STRING_SIZE] = "";
if(DbgGetStringAt(data, string_text))
curData.text = string_text;
if(!curData.text.length()) //stack comments
{
auto va = rvaToVa(rva);
duint stackSize;
duint csp = DbgValFromString("csp");
duint stackBase = DbgMemFindBaseAddr(csp, &stackSize);
STACK_COMMENT comment;
if(va >= stackBase && va < stackBase + stackSize && DbgStackCommentGet(va, &comment))
{
if(va >= csp) //active stack
{
if(*comment.color)
curData.textColor = QColor(QString(comment.color));
}
else
curData.textColor = ConfigColor("StackInactiveTextColor");
curData.text = comment.comment;
}
}
if(curData.text.length())
richText.push_back(curData);
}
else
HexDump::getColumnRichText(col, rva, richText);
}
QString CPUDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
@ -506,111 +535,27 @@ QString CPUDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, i
if(rowBase == 0 && mByteOffset != 0)
printDumpAt(mMemPage->getBase(), false, false);
QString wStr = "";
if(!col) //address
{
char label[MAX_LABEL_SIZE] = "";
QString addrText = "";
dsint cur_addr = rvaToVa((rowBase + rowOffset) * getBytePerRowCount() - mByteOffset);
if(mRvaDisplayEnabled) //RVA display
QColor background;
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //label
{
dsint rva = cur_addr - mRvaDisplayBase;
if(rva == 0)
{
#ifdef _WIN64
addrText = "$ ==> ";
#else
addrText = "$ ==> ";
#endif //_WIN64
}
else if(rva > 0)
{
#ifdef _WIN64
addrText = "$+" + QString("%1").arg(rva, -15, 16, QChar(' ')).toUpper();
#else
addrText = "$+" + QString("%1").arg(rva, -7, 16, QChar(' ')).toUpper();
#endif //_WIN64
}
else if(rva < 0)
{
#ifdef _WIN64
addrText = "$-" + QString("%1").arg(-rva, -15, 16, QChar(' ')).toUpper();
#else
addrText = "$-" + QString("%1").arg(-rva, -7, 16, QChar(' ')).toUpper();
#endif //_WIN64
}
}
addrText += QString("%1").arg(cur_addr, sizeof(dsint) * 2, 16, QChar('0')).toUpper();
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label
{
char module[MAX_MODULE_SIZE] = "";
if(DbgGetModuleAt(cur_addr, module) && !QString(label).startsWith("JMP.&"))
addrText += " <" + QString(module) + "." + QString(label) + ">";
else
addrText += " <" + QString(label) + ">";
}
else
*label = 0;
if(*label) //label
{
QColor background = ConfigColor("HexDumpLabelBackgroundColor");
if(background.alpha())
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill bookmark color
background = ConfigColor("HexDumpLabelBackgroundColor");
painter->setPen(ConfigColor("HexDumpLabelColor")); //TODO: config
}
else
{
QColor background = ConfigColor("HexDumpAddressBackgroundColor");
if(background.alpha())
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill bookmark color
background = ConfigColor("HexDumpAddressBackgroundColor");
painter->setPen(ConfigColor("HexDumpAddressColor")); //TODO: config
}
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, addrText);
if(background.alpha())
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background color
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(cur_addr));
return "";
}
else if(mDescriptor.at(col - 1).isData) //print data
{
wStr = HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
}
else if(!mDescriptor.at(col - 1).isData && mDescriptor.at(col - 1).itemCount) //print comments
{
duint data = 0;
dsint wRva = (rowBase + rowOffset) * getBytePerRowCount() - mByteOffset;
mMemPage->read((byte_t*)&data, wRva, sizeof(duint));
char modname[MAX_MODULE_SIZE] = "";
if(!DbgGetModuleAt(data, modname))
modname[0] = '\0';
char label_text[MAX_LABEL_SIZE] = "";
if(DbgGetLabelAt(data, SEG_DEFAULT, label_text))
wStr = QString(modname) + "." + QString(label_text);
char string_text[MAX_STRING_SIZE] = "";
if(DbgGetStringAt(data, string_text))
wStr = string_text;
if(!wStr.length()) //stack comments
{
auto va = rvaToVa(wRva);
duint stackSize;
duint csp = DbgValFromString("csp");
duint stackBase = DbgMemFindBaseAddr(csp, &stackSize);
STACK_COMMENT comment;
if(va >= stackBase && va < stackBase + stackSize && DbgStackCommentGet(rvaToVa(wRva), &comment))
{
painter->save();
if(va >= csp) //active stack
{
if(*comment.color)
painter->setPen(QPen(QColor(QString(comment.color))));
else
painter->setPen(QPen(textColor));
}
else
painter->setPen(QPen(ConfigColor("StackInactiveTextColor")));
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, comment.comment);
painter->restore();
}
}
}
return wStr;
return HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
}
void CPUDump::contextMenuEvent(QContextMenuEvent* event)
@ -619,12 +564,19 @@ void CPUDump::contextMenuEvent(QContextMenuEvent* event)
return;
dsint selectedAddr = rvaToVa(getInitialSelection());
dsint start = rvaToVa(getSelectionStart());
dsint end = rvaToVa(getSelectionEnd());
QMenu wMenu(this); //create context menu
wMenu.addMenu(mBinaryMenu);
wMenu.addMenu(mCopyMenu);
dsint start = rvaToVa(getSelectionStart());
dsint end = rvaToVa(getSelectionEnd());
QMenu wCopyMenu("&Copy", this);
wCopyMenu.setIcon(QIcon(":/icons/images/copy.png"));
wCopyMenu.addAction(mCopySelection);
wCopyMenu.addAction(mCopyAddress);
if(DbgFunctions()->ModBaseFromAddr(selectedAddr))
wCopyMenu.addAction(mCopyRva);
wMenu.addMenu(&wCopyMenu);
if(DbgFunctions()->PatchInRange(start, end)) //nothing patched in selected range
wMenu.addAction(mUndoSelection);
if(DbgMemIsValidReadPtr(start) && DbgMemFindBaseAddr(start, 0) == DbgMemFindBaseAddr(DbgValFromString("csp"), 0))
@ -1681,25 +1633,6 @@ void CPUDump::syncWithExpressionSlot()
DbgCmdExec(QString("dump \"%1\"").arg(mSyncAddrExpression).toUtf8().constData());
}
void CPUDump::copyAddressSlot()
{
QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper();
Bridge::CopyToClipboard(addrText);
}
void CPUDump::copyRvaSlot()
{
duint addr = rvaToVa(getInitialSelection());
duint base = DbgFunctions()->ModBaseFromAddr(addr);
if(base)
{
QString addrText = QString("%1").arg(addr - base, 0, 16, QChar('0')).toUpper();
Bridge::CopyToClipboard(addrText);
}
else
QMessageBox::warning(this, "Error!", "Selection not in a module...");
}
void CPUDump::followInDumpNSlot()
{
for(int i = 0; i < mFollowInDumpActions.length(); i++)

View File

@ -13,6 +13,7 @@ class CPUDump : public HexDump
Q_OBJECT
public:
explicit CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent = 0);
void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText) override;
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h);
void setupContextMenu();
void contextMenuEvent(QContextMenuEvent* event);
@ -94,8 +95,6 @@ public slots:
void dataCopySlot();
void entropySlot();
void syncWithExpressionSlot();
void copyAddressSlot();
void copyRvaSlot();
void followInDumpNSlot();
void gotoNextSlot();
@ -195,13 +194,9 @@ private:
QAction* mFollowDataDump;
QAction* mSyncWithExpression;
QAction* mEntropy;
QAction* mCopyAddress;
QAction* mCopyRva;
QMenu* mSpecialMenu;
QMenu* mCustomMenu;
QMenu* mPluginMenu;
QMenu* mCopyMenu;
QMenu* mFollowInDumpMenu;
QList<QAction*> mFollowInDumpActions;

View File

@ -308,12 +308,55 @@ void CPUStack::refreshShortcutsSlot()
mGotoNext->setShortcut(ConfigShortcut("ActionGotoNext"));
}
void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & richText)
{
// Compute RVA
dsint wRva = rva;
duint wVa = rvaToVa(wRva);
bool wActiveStack = true;
if(wVa < mCsp) //inactive stack
wActiveStack = false;
STACK_COMMENT comment;
RichTextPainter::CustomRichText_t curData;
curData.highlight = false;
curData.flags = RichTextPainter::FlagColor;
curData.textColor = textColor;
if(col && mDescriptor.at(col - 1).isData == true) //paint stack data
{
HexDump::getColumnRichText(col, rva, richText);
if(!wActiveStack)
{
QColor inactiveColor = ConfigColor("StackInactiveTextColor");
for(int i = 0; i < int(richText.size()); i++)
{
richText[i].flags = RichTextPainter::FlagColor;
richText[i].textColor = inactiveColor;
}
}
}
else if(col && DbgStackCommentGet(rvaToVa(wRva), &comment)) //paint stack comments
{
if(wActiveStack)
{
if(*comment.color)
curData.textColor = QColor(QString(comment.color));
else
curData.textColor = textColor;
}
else
curData.textColor = ConfigColor("StackInactiveTextColor");
curData.text = comment.comment;
richText.push_back(curData);
}
else
HexDump::getColumnRichText(col, rva, richText);
}
QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
{
// Reset byte offset when base address is reached
if(rowBase == 0 && mByteOffset != 0)
printDumpAt(mMemPage->getBase(), false, false);
// Compute RVA
int wBytePerRowCount = getBytePerRowCount();
dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
@ -327,58 +370,10 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
if(wIsSelected) //highlight if selected
painter->fillRect(QRect(x, y, w, h), QBrush(selectionColor));
bool wActiveStack = true;
if(wVa < mCsp) //inactive stack
wActiveStack = false;
STACK_COMMENT comment;
if(col == 0) // paint stack address
{
char label[MAX_LABEL_SIZE] = "";
QString addrText = "";
dsint cur_addr = rvaToVa((rowBase + rowOffset) * getBytePerRowCount() - mByteOffset);
if(mRvaDisplayEnabled) //RVA display
{
dsint rva = cur_addr - mRvaDisplayBase;
if(rva == 0)
{
#ifdef _WIN64
addrText = "$ ==> ";
#else
addrText = "$ ==> ";
#endif //_WIN64
}
else if(rva > 0)
{
#ifdef _WIN64
addrText = "$+" + QString("%1").arg(rva, -15, 16, QChar(' ')).toUpper();
#else
addrText = "$+" + QString("%1").arg(rva, -7, 16, QChar(' ')).toUpper();
#endif //_WIN64
}
else if(rva < 0)
{
#ifdef _WIN64
addrText = "$-" + QString("%1").arg(-rva, -15, 16, QChar(' ')).toUpper();
#else
addrText = "$-" + QString("%1").arg(-rva, -7, 16, QChar(' ')).toUpper();
#endif //_WIN64
}
}
addrText += ToPtrString(cur_addr);
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //has label
{
char module[MAX_MODULE_SIZE] = "";
if(DbgGetModuleAt(cur_addr, module) && !QString(label).startsWith("JMP.&"))
addrText += " <" + QString(module) + "." + QString(label) + ">";
else
addrText += " <" + QString(label) + ">";
}
else
*label = 0;
QColor background;
if(*label) //label
if(DbgGetLabelAt(wVa, SEG_DEFAULT, nullptr)) //label
{
if(wVa == mCsp) //CSP
{
@ -411,41 +406,10 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
}
if(background.alpha())
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background when defined
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, addrText);
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(wVa));
return "";
}
else if(mDescriptor.at(col - 1).isData == true) //paint stack data
{
int wBytePerRowCount = getBytePerRowCount();
dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
printSelected(painter, rowBase, rowOffset, col, x, y, w, h);
RichTextPainter::List richText;
getString(col - 1, wRva, richText);
if(!wActiveStack)
{
QColor inactiveColor = ConfigColor("StackInactiveTextColor");
for(int i = 0; i < int(richText.size()); i++)
{
richText[i].flags = RichTextPainter::FlagColor;
richText[i].textColor = inactiveColor;
}
}
RichTextPainter::paintRichText(painter, x, y, w, h, 4, richText, getCharWidth());
}
else if(DbgStackCommentGet(rvaToVa(wRva), &comment)) //paint stack comments
{
QString wStr = QString(comment.comment);
if(wActiveStack)
{
if(*comment.color)
painter->setPen(QPen(QColor(QString(comment.color))));
else
painter->setPen(QPen(textColor));
}
else
painter->setPen(QPen(ConfigColor("StackInactiveTextColor")));
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, wStr);
}
return "";
return HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);;
}
void CPUStack::contextMenuEvent(QContextMenuEvent* event)
@ -458,6 +422,13 @@ void CPUStack::contextMenuEvent(QContextMenuEvent* event)
QMenu wMenu(this); //create context menu
wMenu.addAction(mModifyAction);
wMenu.addMenu(mBinaryMenu);
QMenu wCopyMenu("&Copy", this);
wCopyMenu.setIcon(QIcon(":/icons/images/copy.png"));
wCopyMenu.addAction(mCopySelection);
wCopyMenu.addAction(mCopyAddress);
if(DbgFunctions()->ModBaseFromAddr(selectedAddr))
wCopyMenu.addAction(mCopyRva);
wMenu.addMenu(&wCopyMenu);
wMenu.addMenu(mBreakpointMenu);
dsint start = rvaToVa(getSelectionStart());
dsint end = rvaToVa(getSelectionEnd());

View File

@ -17,7 +17,8 @@ public:
virtual void updateColors();
virtual void updateFonts();
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h);
void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText) override;
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
void contextMenuEvent(QContextMenuEvent* event);
void mouseDoubleClickEvent(QMouseEvent* event);
void setupContextMenu();