1
0
Fork 0

GUI: First draft of hexa dump implementation

This commit is contained in:
SigmaPic 2014-01-03 12:34:53 +01:00
parent 07efe9eb57
commit bd4d220af2
3 changed files with 828 additions and 102 deletions

View File

@ -1,19 +1,17 @@
#include "HexDump.h"
HexDump::HexDump(QWidget *parent) :AbstractTableView(parent)
{
SelectionData_t data;
memset(&data, 0, sizeof(SelectionData_t));
mSelection = data;
mBase = 0;
mSize = 0;
mGuiState = HexDump::NoState;
mByteWidth = QFontMetrics(this->font()).width(QChar('L')) + 4;
mDumpByteWidth = 16;
setRowCount(0);
mMemPage = new MemoryPage(0, 0);
@ -21,6 +19,39 @@ HexDump::HexDump(QWidget *parent) :AbstractTableView(parent)
addColumnAt(100, "", false);
addColumnAt(100, "", false);
addColumnAt(100, "", false);
addColumnAt(100, "", false);
addColumnAt(100, "", false);
addColumnAt(100, "", false);
mDescriptor.clear();
ColumnDescriptor_t wColDesc;
wColDesc.isData = true;
wColDesc.itemCount = 8;
wColDesc.data = (DataDescriptor_t){Byte, HexByte};
mDescriptor << wColDesc;
wColDesc.isData = true;
wColDesc.itemCount = 8;
wColDesc.data = (DataDescriptor_t){Byte, AsciiByte};
mDescriptor << wColDesc;
wColDesc.isData = true;
wColDesc.itemCount = 2;
wColDesc.data.itemSize = Dword;
wColDesc.data.dwordMode = SignedDecDword;
mDescriptor << wColDesc;
wColDesc.isData = true;
wColDesc.itemCount = 1;
wColDesc.data.itemSize = Qword;
wColDesc.data.qwordMode = FloatQword;
mDescriptor << wColDesc;
wColDesc.isData = false;
wColDesc.itemCount = 0;
wColDesc.data = (DataDescriptor_t){Byte, AsciiByte};
mDescriptor << wColDesc;
connect(Bridge::getBridge(), SIGNAL(disassembleAt(int_t, int_t)), this, SLOT(printDumpAt(int_t)));
}
@ -31,34 +62,46 @@ void HexDump::printDumpAt(int_t parVA)
int_t wBase = DbgMemFindBaseAddr(parVA, 0);
int_t wSize = DbgMemGetPageSize(wBase);
int_t wRVA = parVA - wBase;
int wBytePerRowCount = getBytePerRowCount();
setRowCount(wSize/mDumpByteWidth);
setRowCount(wSize / wBytePerRowCount);
mMemPage->setAttributes(wBase, wSize); // Set base and size (Useful when memory page changed)
setTableOffset(wRVA/mDumpByteWidth);
mBase = wBase;
mSize = wSize;
setTableOffset(wRVA / wBytePerRowCount);
}
void HexDump::mouseMoveEvent(QMouseEvent* event)
{
//qDebug() << "HexDump::mouseMoveEvent";
bool wAccept = true;
if(mGuiState == HexDump::MultiRowsSelectionState)
{
//qDebug() << "State = MultiRowsSelectionState";
if((transY(event->y()) >= 0) && (transY(event->y()) <= this->getTableHeigth()))
if((transY(event->y()) >= 0) && event->y() <= this->height())
{
int wRowIndex = getTableOffset() +getIndexOffsetFromY(transY(event->y()));
if(wRowIndex < getRowCount())
for(int wI = 1; wI < getColumnCount(); wI++) // Skip first column (Addresses)
{
expandSelectionUpTo(wRowIndex);
int wColIndex = getColumnIndexFromX(event->x());
this->viewport()->repaint();
if(wColIndex > 0) // No selection for first column (addresses)
{
int_t wStartingAddress = getItemStartingAddress(event->x(), event->y());
int_t wEndingAddress = wStartingAddress + getSizeOf(mDescriptor.at(wColIndex - 1).data.itemSize) - 1;
wAccept = false;
if(wStartingAddress < getInitialSelection())
expandSelectionUpTo(wStartingAddress);
else
expandSelectionUpTo(wEndingAddress);
mGuiState = HexDump::MultiRowsSelectionState;
repaint();
}
}
wAccept = true;
}
}
@ -78,33 +121,27 @@ void HexDump::mousePressEvent(QMouseEvent* event)
{
if(getGuiState() == AbstractTableView::NoState)
{
if(event->y() > getHeaderHeight())
if(event->y() > getHeaderHeight() && event->y() <= this->height())
{
int wRowIndex = getTableOffset()+ getIndexOffsetFromY(transY(event->y()));
int wColIndex = getColumnIndexFromX(event->x());
int wByteIndex;
if(wRowIndex < getRowCount())
for(int wI = 1; wI < getColumnCount(); wI++) // Skip first column (Addresses)
{
if(wColIndex == 1)
int wColIndex = getColumnIndexFromX(event->x());
if(wColIndex > 0 && mDescriptor.at(wColIndex - 1).isData == true) // No selection for first column (addresses) and no data columns
{
int wX = event->x() - getColumnPosition(wColIndex);
int_t wStartingAddress = getItemStartingAddress(event->x(), event->y());
int_t wEndingAddress = wStartingAddress + getSizeOf(mDescriptor.at(wColIndex - 1).data.itemSize) - 1;
setSingleSelection(wStartingAddress);
expandSelectionUpTo(wEndingAddress);
mGuiState = HexDump::MultiRowsSelectionState;
repaint();
}
else if(wColIndex == 2)
{
int wColBegin = getColumnPosition(wColIndex);
}
setSingleSelection(wRowIndex);
mGuiState = HexDump::MultiRowsSelectionState;
viewport()->repaint();
wAccept = true;
}
wAccept = true;
}
}
}
@ -144,73 +181,77 @@ QString HexDump::paintContent(QPainter* painter, int_t rowBase, int rowOffset, i
//return QString("HexDump: Col:") + QString::number(col) + "Row:" + QString::number(rowBase + rowOffset);
QString wStr = "";
int_t wRva = (rowBase + rowOffset) * mDumpByteWidth;
int wBytePerRowCount = getBytePerRowCount();
int_t wRva = (rowBase + rowOffset) * wBytePerRowCount;
//if(isSelected(rowBase, rowOffset) == true)
// painter->fillRect(QRect(x, y, w, h), QBrush(QColor(192,192,192)));
switch(col)
if(col == 0) // Addresses
{
case 0:
{
//uint_t wAddr = (uint_t)instruction.rva + (uint_t)mMemoryView->getBase();
//wStr = QString("%1").arg(wAddr, 8, 16, QChar('0')).toUpper();
wStr += QString::number(wRva);
break;
}
case 1:
{
QByteArray wBuffer;
wBuffer.resize(mDumpByteWidth);
mMemPage->readOriginalMemory(reinterpret_cast<byte_t*>(wBuffer.data()), wRva, mDumpByteWidth);
for(int i = 0; i < mDumpByteWidth; i++)
wStr += QString("%1").arg((unsigned char)wBuffer.at(i), 2, 16, QChar('0')).toUpper() + " ";
break;
}
case 2:
{
wStr = "ToDo";
break;
}
default:
break;
//wStr += QString::number(wRva);
wStr += QString("%1").arg(mBase + wRva, sizeof(int_t) * 2, 16, QChar('0')).toUpper();
}
else if(mDescriptor.at(col - 1).isData == true)
{
printSelected(painter, rowBase, rowOffset, col, x, y, w, h);
wStr += getString(col - 1, wRva);
}
else
{
wStr += "comments";
}
return wStr;
}
void HexDump::printSelected(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h)
{
if((col > 0) && ((col - 1) < mDescriptor.size()))
{
int wI = 0;
int wBytePerRowCount = getBytePerRowCount();
int_t wRva = (rowBase + rowOffset) * wBytePerRowCount;
int wItemPixWidth = getItemPixelWidth(mDescriptor.at(col - 1));
int wSelectionX;
int wSelectionWidth;
for(wI = 0; wI < mDescriptor.at(col - 1).itemCount; wI++)
{
if(isSelected(wRva + wI * getSizeOf(mDescriptor.at(col - 1).data.itemSize)) == true)
{
wSelectionX = x + wI * wItemPixWidth;
wSelectionWidth = wItemPixWidth > w - (wSelectionX - x) ? w - (wSelectionX - x) : wItemPixWidth;
wSelectionWidth = wSelectionWidth < 0 ? 0 : wSelectionWidth;
painter->fillRect(QRect(wSelectionX, y, wSelectionWidth, h), QBrush(QColor(192,192,192)));
}
}
}
}
/************************************************************************************
Selection Management
************************************************************************************/
void HexDump::expandSelectionUpTo(int to)
void HexDump::expandSelectionUpTo(int_t rva)
{
if(to < mSelection.firstSelectedIndex)
if(rva < mSelection.firstSelectedIndex)
{
mSelection.fromIndex = to;
mSelection.fromIndex = rva;
mSelection.toIndex = mSelection.firstSelectedIndex;
}
else if(to > mSelection.firstSelectedIndex)
else if(rva > mSelection.firstSelectedIndex)
{
mSelection.fromIndex = mSelection.firstSelectedIndex;
mSelection.toIndex = to;
mSelection.toIndex = rva;
}
}
void HexDump::setSingleSelection(int index)
void HexDump::setSingleSelection(int_t rva)
{
mSelection.firstSelectedIndex = index;
mSelection.fromIndex = index;
mSelection.toIndex = index;
mSelection.firstSelectedIndex = rva;
mSelection.fromIndex = rva;
mSelection.toIndex = rva;
}
@ -220,22 +261,608 @@ int HexDump::getInitialSelection()
}
bool HexDump::isSelected(int base, int offset)
bool HexDump::isSelected(int_t rva)
{
/*
int wAddr = base;
if(offset < 0)
wAddr = getPreviousInstructionRVA(getTableOffset(), offset);
else if(offset > 0)
wAddr = getNextInstructionRVA(getTableOffset(), offset);
if(wAddr >= mSelection.fromIndex && wAddr <= mSelection.toIndex)
if(rva >= mSelection.fromIndex && rva <= mSelection.toIndex)
return true;
else
return false;
*/
return false;
}
QString HexDump::getString(int col, int_t rva)
{
int wI;
QString wStr = "";
int wByteCount = getSizeOf(mDescriptor.at(col).data.itemSize);
byte_t wData[mDescriptor.at(col).itemCount * wByteCount];
mMemPage->readOriginalMemory(wData, rva, mDescriptor.at(col).itemCount * wByteCount);
for(wI = 0; wI < mDescriptor.at(col).itemCount; wI++)
{
wStr += toString(mDescriptor.at(col).data, (void*)(wData + wI * wByteCount)).rightJustified(getStringMaxLength(mDescriptor.at(col).data), ' ') + " ";
}
return wStr;
}
QString HexDump::toString(DataDescriptor_t desc, void* data)
{
QString wStr = "";
switch(desc.itemSize)
{
case Byte:
{
wStr = byteToString(*((byte_t*)data), desc.byteMode);
}
break;
case Word:
{
wStr = wordToString(*((uint16*)data), desc.wordMode);
}
break;
case Dword:
{
wStr = dwordToString(*((uint32*)data), desc.dwordMode);
}
break;
case Qword:
{
wStr = qwordToString(*((uint64*)data), desc.qwordMode);
}
break;
case Tword:
{
wStr = twordToString(*((long double*)data), desc.twordMode);
}
break;
default:
{
}
break;
}
return wStr;
}
QString HexDump::byteToString(byte_t byte, ByteViewMode_e mode)
{
QString wStr = "";
switch(mode)
{
case HexByte:
{
wStr = QString("%1").arg((unsigned char)byte, 2, 16, QChar('0')).toUpper();
}
break;
case AsciiByte:
{
QChar wChar((char)byte);
if(wChar.isPrint() == true)
wStr = QString(wChar);
else
wStr = ".";
}
break;
case SignedDecByte:
{
wStr = QString::number((int)((char)byte));
}
break;
case UnsignedDecByte:
{
wStr = QString::number((unsigned int)byte);
}
break;
default:
{
}
break;
}
return wStr;
}
QString HexDump::wordToString(uint16 word, WordViewMode_e mode)
{
QString wStr = "";
switch(mode)
{
case HexWord:
{
wStr = QString("%1").arg((unsigned short)word, 4, 16, QChar('0')).toUpper();
}
break;
case UnicodeWord:
{
QChar wChar((unsigned short)word);
if(wChar.isPrint() == true)
wStr = QString(wChar);
else
wStr = ".";
}
break;
case SignedDecWord:
{
wStr = QString::number((int)((short)word));
}
break;
case UnsignedDecWord:
{
wStr = QString::number((unsigned int)word);
}
break;
default:
{
}
break;
}
return wStr;
}
QString HexDump::dwordToString(uint32 dword, DwordViewMode_e mode)
{
QString wStr = "";
switch(mode)
{
case HexDword:
{
wStr = QString("%1").arg((unsigned int)dword, 8, 16, QChar('0')).toUpper();
}
break;
case SignedDecDword:
{
wStr = QString::number((int)dword);
}
break;
case UnsignedDecDword:
{
wStr = QString::number((unsigned int)dword);
}
break;
case FloatDword:
{
float* wPtr = (float*)&dword;
wStr = QString::number((double)*wPtr);
}
break;
default:
{
}
break;
}
return wStr;
}
QString HexDump::qwordToString(uint64 qword, QwordViewMode_e mode)
{
QString wStr = "";
switch(mode)
{
case HexQword:
{
wStr = QString("%1").arg((unsigned long long)qword, 16, 16, QChar('0')).toUpper();
}
break;
case SignedDecQword:
{
wStr = QString::number((long long)qword);
}
break;
case UnsignedDecQword:
{
wStr = QString::number((unsigned long long)qword);
}
break;
case FloatQword:
{
double* wPtr = (double*)&qword;
wStr = QString::number((double)*wPtr);
}
break;
default:
{
}
break;
}
return wStr;
}
QString HexDump::twordToString(long double tword, TwordViewMode_e mode)
{
QString wStr = "";
switch(mode)
{
case FloatTword:
{
std::stringstream wlongDoubleStr;
wlongDoubleStr << std::scientific << (long double)tword;
wStr = QString::fromStdString(wlongDoubleStr.str());
}
break;
default:
{
}
break;
}
return wStr;
}
int HexDump::getSizeOf(DataSize_e size)
{
int wSize = 0;
switch(size)
{
case Byte: // 1 Byte
{
wSize = 1;
}
break;
case Word: // 2 Bytes
{
wSize = 2;
}
break;
case Dword: // 4 Bytes
{
wSize = 4;
}
break;
case Qword: // 8 Bytes
{
wSize = 8;
}
break;
case Tword: // 10 Bytes
{
wSize = 10;
}
break;
default:
{
wSize = 0;
}
}
return wSize;
}
int HexDump::getStringMaxLength(DataDescriptor_t desc)
{
int wLength = 0;
switch(desc.itemSize)
{
case Byte:
{
wLength = byteStringMaxLength(desc.byteMode);
}
break;
case Word:
{
wLength = wordStringMaxLength(desc.wordMode);
}
break;
case Dword:
{
wLength = dwordStringMaxLength(desc.dwordMode);
}
break;
case Qword:
{
wLength = qwordStringMaxLength(desc.qwordMode);
}
break;
case Tword:
{
wLength = twordStringMaxLength(desc.twordMode);
}
break;
default:
{
}
break;
}
return wLength;
}
int HexDump::byteStringMaxLength(ByteViewMode_e mode)
{
int wLength = 0;
switch(mode)
{
case HexByte:
{
wLength = 2;
}
break;
case AsciiByte:
{
wLength = 1;
}
break;
case SignedDecByte:
{
wLength = 4;
}
break;
case UnsignedDecByte:
{
wLength = 3;
}
break;
default:
{
}
break;
}
return wLength;
}
int HexDump::wordStringMaxLength(WordViewMode_e mode)
{
int wLength = 0;
switch(mode)
{
case HexWord:
{
wLength = 4;
}
break;
case UnicodeWord:
{
wLength = 1;
}
break;
case SignedDecWord:
{
wLength = 6;
}
break;
case UnsignedDecWord:
{
wLength = 5;
}
break;
default:
{
}
break;
}
return wLength;
}
int HexDump::dwordStringMaxLength(DwordViewMode_e mode)
{
int wLength = 0;
switch(mode)
{
case HexDword:
{
wLength = 8;
}
break;
case SignedDecDword:
{
wLength = 11;
}
break;
case UnsignedDecDword:
{
wLength = 10;
}
break;
case FloatDword:
{
wLength = 13;
}
break;
default:
{
}
break;
}
return wLength;
}
int HexDump::qwordStringMaxLength(QwordViewMode_e mode)
{
int wLength = 0;
switch(mode)
{
case HexQword:
{
wLength = 16;
}
break;
case SignedDecQword:
{
wLength = 20;
}
break;
case UnsignedDecQword:
{
wLength = 20;
}
break;
case FloatQword:
{
wLength = 23;
}
break;
default:
{
}
break;
}
return wLength;
}
int HexDump::twordStringMaxLength(TwordViewMode_e mode)
{
int wLength = 0;
switch(mode)
{
case FloatTword:
{
wLength = 29;
}
break;
default:
{
}
break;
}
return wLength;
}
int HexDump::getItemIndexFromX(int x)
{
int wColIndex = getColumnIndexFromX(x);
if(wColIndex > 0)
{
int wColStartingPos = getColumnPosition(wColIndex);
int wRelativeX = x - wColStartingPos;
int wItemPixWidth = getItemPixelWidth(mDescriptor.at(wColIndex - 1));
int wItemIndex = wRelativeX / wItemPixWidth;
wItemIndex = wItemIndex < 0 ? 0 : wItemIndex;
wItemIndex = wItemIndex > (mDescriptor.at(wColIndex - 1).itemCount - 1) ? (mDescriptor.at(wColIndex - 1).itemCount - 1) : wItemIndex;
return wItemIndex;
}
else
{
return 0;
}
}
int_t HexDump::getItemStartingAddress(int x, int y)
{
int wRowOffset = getIndexOffsetFromY(transY(y));
int wItemIndex = getItemIndexFromX(x);
int wColIndex = getColumnIndexFromX(x);
int_t wStartingAddress = 0;
if(wColIndex > 0)
{
wColIndex -= 1;
wStartingAddress = (getTableOffset() + wRowOffset) * (mDescriptor.at(wColIndex).itemCount * getSizeOf(mDescriptor.at(wColIndex).data.itemSize)) + wItemIndex * getSizeOf(mDescriptor.at(wColIndex).data.itemSize);
}
return wStartingAddress;
}
int HexDump::getBytePerRowCount()
{
return mDescriptor.at(0).itemCount * getSizeOf(mDescriptor.at(0).data.itemSize);
}
int HexDump::getItemPixelWidth(ColumnDescriptor_t desc)
{
int wCharWidth = QFontMetrics(this->font()).width(QChar('C'));
int wItemPixWidth = getStringMaxLength(desc.data) * wCharWidth + wCharWidth;
return wItemPixWidth;
}

View File

@ -8,11 +8,79 @@
#include "MemoryPage.h"
#include "QBeaEngine.h"
#include "Bridge.h"
#include <sstream>
class HexDump : public AbstractTableView
{
Q_OBJECT
public:
enum DataSize_e
{
Byte,
Word,
Dword,
Qword,
Tword
};
enum ByteViewMode_e
{
HexByte,
AsciiByte,
SignedDecByte,
UnsignedDecByte
};
enum WordViewMode_e
{
HexWord,
UnicodeWord,
SignedDecWord,
UnsignedDecWord
};
enum DwordViewMode_e
{
HexDword,
SignedDecDword,
UnsignedDecDword,
FloatDword
};
enum QwordViewMode_e
{
HexQword,
SignedDecQword,
UnsignedDecQword,
FloatQword
};
enum TwordViewMode_e
{
FloatTword
};
typedef struct _DataDescriptor_t
{
DataSize_e itemSize; // Items size
union // View mode
{
ByteViewMode_e byteMode;
WordViewMode_e wordMode;
DwordViewMode_e dwordMode;
QwordViewMode_e qwordMode;
TwordViewMode_e twordMode;
};
} DataDescriptor_t;
typedef struct _ColumnDescriptor_t
{
bool isData;
int itemCount;
DataDescriptor_t data;
} ColumnDescriptor_t;
explicit HexDump(QWidget *parent = 0);
//QString getStringToPrint(int rowBase, int rowOffset, int col);
@ -23,12 +91,38 @@ public:
QString paintContent(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h);
void paintGraphicDump(QPainter* painter, int x, int y, int addr);
// Selection Management
void expandSelectionUpTo(int to);
void setSingleSelection(int index);
int getInitialSelection();
bool isSelected(int base, int offset);
void printSelected(QPainter* painter, int_t rowBase, int rowOffset, int col, int x, int y, int w, int h);
// Selection Management
void expandSelectionUpTo(int_t rva);
void setSingleSelection(int_t rva);
int getInitialSelection();
bool isSelected(int_t rva);
QString getString(int col, int_t rva);
int getSizeOf(DataSize_e size);
QString toString(DataDescriptor_t desc, void *data);
QString byteToString(byte_t byte, ByteViewMode_e mode);
QString wordToString(uint16 word, WordViewMode_e mode);
QString dwordToString(uint32 dword, DwordViewMode_e mode);
QString qwordToString(uint64 qword, QwordViewMode_e mode);
QString twordToString(long double tword, TwordViewMode_e mode);
int getStringMaxLength(DataDescriptor_t desc);
int byteStringMaxLength(ByteViewMode_e mode);
int wordStringMaxLength(WordViewMode_e mode);
int dwordStringMaxLength(DwordViewMode_e mode);
int qwordStringMaxLength(QwordViewMode_e mode);
int twordStringMaxLength(TwordViewMode_e mode);
int getItemIndexFromX(int x);
int_t getItemStartingAddress(int x, int y);
int getBytePerRowCount();
int getItemPixelWidth(ColumnDescriptor_t desc);
signals:
@ -38,20 +132,22 @@ public slots:
private:
enum GuiState_t {NoState, MultiRowsSelectionState};
typedef struct _SelectionData_t
typedef struct _RowDescriptor_t
{
int firstSelectedIndex;
int fromIndex;
int toIndex;
int_t firstSelectedIndex;
int_t fromIndex;
int_t toIndex;
} SelectionData_t;
QList<ColumnDescriptor_t> mDescriptor;
SelectionData_t mSelection;
GuiState_t mGuiState;
int mByteWidth;
int_t mBase;
int_t mSize;
int mDumpByteWidth;
MemoryPage* mMemPage;
};

View File

@ -3,6 +3,9 @@
#include "Imports.h"
typedef short int16;
typedef unsigned short uint16;
typedef int int32;
typedef unsigned int uint32;