1
0
Fork 0

GUI: implemented code page views in HexDump #629

This commit is contained in:
mrexodia 2016-06-04 15:42:47 +02:00
parent 022fc72579
commit 505aea109e
No known key found for this signature in database
GPG Key ID: D72F9A4FAA0073B4
10 changed files with 331 additions and 98 deletions

View File

@ -569,11 +569,12 @@ void HexDump::getColumnRichText(int col, dsint rva, RichTextPainter::List & rich
}
else if(mDescriptor.at(col - 1).isData == true)
{
const ColumnDescriptor_t & desc = mDescriptor.at(col - 1);
int wI;
QString wStr = "";
int wByteCount = getSizeOf(mDescriptor.at(col - 1).data.itemSize);
int wBufferByteCount = mDescriptor.at(col - 1).itemCount * wByteCount;
int wByteCount = getSizeOf(desc.data.itemSize);
int wBufferByteCount = desc.itemCount * wByteCount;
wBufferByteCount = wBufferByteCount > (dsint)(mMemPage->getSize() - rva) ? mMemPage->getSize() - rva : wBufferByteCount;
@ -582,27 +583,41 @@ void HexDump::getColumnRichText(int col, dsint rva, RichTextPainter::List & rich
mMemPage->read(wData, rva, wBufferByteCount);
QColor highlightColor = ConfigColor("HexDumpModifiedBytesColor");
for(wI = 0; wI < mDescriptor.at(col - 1).itemCount && (rva + wI) < (dsint)mMemPage->getSize(); wI++)
if(desc.textCodec) //convert the row bytes to unicode
{
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;
//This might produce invalid characters in variables-width encodings. This is currently ignored.
curData.text = desc.textCodec->toUnicode(QByteArray((const char*)wData, wBufferByteCount));
curData.text.replace('\t', "\\t");
curData.text.replace('\f', "\\f");
curData.text.replace('\v', "\\v");
curData.text.replace('\n', "\\n");
curData.text.replace('\r', "\\r");
richText.push_back(curData);
}
else
{
QColor highlightColor = ConfigColor("HexDumpModifiedBytesColor");
for(wI = 0; wI < desc.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(desc.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;
}

View File

@ -4,6 +4,7 @@
#include "AbstractTableView.h"
#include "RichTextPainter.h"
#include "MemoryPage.h"
#include <QTextCodec>
class HexDump : public AbstractTableView
{
@ -68,13 +69,19 @@ public:
};
} DataDescriptor_t;
typedef struct _ColumnDescriptor_t
struct ColumnDescriptor_t
{
bool isData;
int itemCount;
int separator;
QTextCodec* textCodec; //name of the text codec (leave empty if you want to keep your sanity)
DataDescriptor_t data;
} ColumnDescriptor_t;
explicit ColumnDescriptor_t()
: textCodec(nullptr)
{
}
};
explicit HexDump(QWidget* parent = 0);
virtual ~HexDump();

View File

@ -11,6 +11,7 @@
#include "EntropyDialog.h"
#include "CPUMultiDump.h"
#include "WordEditDialog.h"
#include "CodepageSelectionDialog.h"
#include <QToolTip>
CPUDump::CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent) : HexDump(parent)
@ -18,69 +19,7 @@ CPUDump::CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent
mDisas = disas;
mMultiDump = multiDump;
switch((ViewEnum_t)ConfigUint("HexDump", "DefaultView"))
{
case ViewHexAscii:
hexAsciiSlot();
break;
case ViewHexUnicode:
hexUnicodeSlot();
break;
case ViewTextAscii:
textAsciiSlot();
break;
case ViewTextUnicode:
textUnicodeSlot();
break;
case ViewIntegerSignedShort:
integerSignedShortSlot();
break;
case ViewIntegerSignedLong:
integerSignedLongSlot();
break;
#ifdef _WIN64
case ViewIntegerSignedLongLong:
integerSignedLongLongSlot();
break;
#endif //_WIN64
case ViewIntegerUnsignedShort:
integerUnsignedShortSlot();
break;
case ViewIntegerUnsignedLong:
integerUnsignedLongSlot();
break;
#ifdef _WIN64
case ViewIntegerUnsignedLongLong:
integerUnsignedLongLongSlot();
break;
#endif //_WIN64
case ViewIntegerHexShort:
integerHexShortSlot();
break;
case ViewIntegerHexLong:
integerHexLongSlot();
break;
#ifdef _WIN64
case ViewIntegerHexLongLong:
integerHexLongLongSlot();
break;
#endif //_WIN64
case ViewFloatFloat:
floatFloatSlot();
break;
case ViewFloatDouble:
floatDoubleSlot();
break;
case ViewFloatLongDouble:
floatLongDoubleSlot();
break;
case ViewAddress:
addressSlot();
break;
default:
hexAsciiSlot();
break;
}
setView((ViewEnum_t)ConfigUint("HexDump", "DefaultView"));
connect(this, SIGNAL(selectionUpdated()), this, SLOT(selectionUpdatedSlot()));
@ -362,25 +301,33 @@ void CPUDump::setupContextMenu()
mHexMenu = new QMenu(tr("&Hex"), this);
mHexMenu->setIcon(QIcon(":/icons/images/hex.png"));
//Hex->Ascii
mHexAsciiAction = new QAction("&Ascii", this);
mHexAsciiAction = new QAction("&ASCII", this);
connect(mHexAsciiAction, SIGNAL(triggered()), this, SLOT(hexAsciiSlot()));
mHexMenu->addAction(mHexAsciiAction);
//Hex->Unicode
mHexUnicodeAction = new QAction(tr("&Unicode"), this);
mHexUnicodeAction = new QAction(tr("&UTF-16"), this);
connect(mHexUnicodeAction, SIGNAL(triggered()), this, SLOT(hexUnicodeSlot()));
mHexMenu->addAction(mHexUnicodeAction);
//Hex->Codepage
mHexCodepageAction = new QAction(tr("&Codepage..."), this);
connect(mHexCodepageAction, SIGNAL(triggered()), this, SLOT(hexCodepageSlot()));
mHexMenu->addAction(mHexCodepageAction);
//Text menu
mTextMenu = new QMenu(tr("&Text"), this);
mTextMenu->setIcon(QIcon(":/icons/images/strings.png"));
//Text->Ascii
mTextAsciiAction = new QAction(tr("&Ascii"), this);
mTextAsciiAction = new QAction(tr("&ASCII"), this);
connect(mTextAsciiAction, SIGNAL(triggered()), this, SLOT(textAsciiSlot()));
mTextMenu->addAction(mTextAsciiAction);
//Text->Unicode
mTextUnicodeAction = new QAction(tr("&Unicode"), this);
mTextUnicodeAction = new QAction(tr("&UTF-16"), this);
connect(mTextUnicodeAction, SIGNAL(triggered()), this, SLOT(textUnicodeSlot()));
mTextMenu->addAction(mTextUnicodeAction);
//Hex->Codepage
mTextCodepageAction = new QAction(tr("&Codepage..."), this);
connect(mTextCodepageAction, SIGNAL(triggered()), this, SLOT(textCodepageSlot()));
mTextMenu->addAction(mTextCodepageAction);
//Integer menu
mIntegerMenu = new QMenu(tr("&Integer"), this);
@ -393,12 +340,10 @@ void CPUDump::setupContextMenu()
mIntegerSignedLongAction = new QAction("Signed long (32-bit)", this);
connect(mIntegerSignedLongAction, SIGNAL(triggered()), this, SLOT(integerSignedLongSlot()));
mIntegerMenu->addAction(mIntegerSignedLongAction);
#ifdef _WIN64
//Integer->Signed long long
mIntegerSignedLongLongAction = new QAction("Signed long long (64-bit)", this);
connect(mIntegerSignedLongLongAction, SIGNAL(triggered()), this, SLOT(integerSignedLongLongSlot()));
mIntegerMenu->addAction(mIntegerSignedLongLongAction);
#endif //_WIN64
//Integer->Unsigned short
mIntegerUnsignedShortAction = new QAction("Unsigned short (16-bit)", this);
connect(mIntegerUnsignedShortAction, SIGNAL(triggered()), this, SLOT(integerUnsignedShortSlot()));
@ -407,12 +352,10 @@ void CPUDump::setupContextMenu()
mIntegerUnsignedLongAction = new QAction("Unsigned long (32-bit)", this);
connect(mIntegerUnsignedLongAction, SIGNAL(triggered()), this, SLOT(integerUnsignedLongSlot()));
mIntegerMenu->addAction(mIntegerUnsignedLongAction);
#ifdef _WIN64
//Integer->Unsigned long long
mIntegerUnsignedLongLongAction = new QAction("Unsigned long long (64-bit)", this);
connect(mIntegerUnsignedLongLongAction, SIGNAL(triggered()), this, SLOT(integerUnsignedLongLongSlot()));
mIntegerMenu->addAction(mIntegerUnsignedLongLongAction);
#endif //_WIN64
//Integer->Hex short
mIntegerHexShortAction = new QAction("Hex short (16-bit)", this);
connect(mIntegerHexShortAction, SIGNAL(triggered()), this, SLOT(integerHexShortSlot()));
@ -421,12 +364,10 @@ void CPUDump::setupContextMenu()
mIntegerHexLongAction = new QAction("Hex long (32-bit)", this);
connect(mIntegerHexLongAction, SIGNAL(triggered()), this, SLOT(integerHexLongSlot()));
mIntegerMenu->addAction(mIntegerHexLongAction);
#ifdef _WIN64
//Integer->Hex long long
mIntegerHexLongLongAction = new QAction("Hex long long (64-bit)", this);
connect(mIntegerHexLongLongAction, SIGNAL(triggered()), this, SLOT(integerHexLongLongSlot()));
mIntegerMenu->addAction(mIntegerHexLongLongAction);
#endif //_WIN64
//Float menu
mFloatMenu = new QMenu(tr("&Float"), this);
@ -892,6 +833,36 @@ void CPUDump::hexUnicodeSlot()
reloadData();
}
void CPUDump::hexCodepageSlot()
{
CodepageSelectionDialog dialog(this);
if(dialog.exec() != QDialog::Accepted)
return;
int charwidth = getCharWidth();
ColumnDescriptor_t wColDesc;
DataDescriptor_t dDesc;
wColDesc.isData = true; //hex byte
wColDesc.itemCount = 16;
wColDesc.separator = 4;
dDesc.itemSize = Byte;
dDesc.byteMode = HexByte;
wColDesc.data = dDesc;
appendResetDescriptor(8 + charwidth * 47, tr("Hex"), false, wColDesc);
wColDesc.isData = true; //text (in code page)
wColDesc.itemCount = 16;
wColDesc.separator = 0;
wColDesc.textCodec = QTextCodec::codecForName(dialog.getSelectedCodepage());
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
appendDescriptor(0, dialog.getSelectedCodepage(), false, wColDesc);
reloadData();
}
void CPUDump::textAsciiSlot()
{
Config()->setUint("HexDump", "DefaultView", (duint)ViewTextAscii);
@ -944,6 +915,27 @@ void CPUDump::textUnicodeSlot()
reloadData();
}
void CPUDump::textCodepageSlot()
{
CodepageSelectionDialog dialog(this);
if(dialog.exec() != QDialog::Accepted)
return;
ColumnDescriptor_t wColDesc;
DataDescriptor_t dDesc;
wColDesc.isData = true; //text (in code page)
wColDesc.itemCount = 64;
wColDesc.separator = 0;
wColDesc.textCodec = QTextCodec::codecForName(dialog.getSelectedCodepage());
dDesc.itemSize = Byte;
dDesc.byteMode = AsciiByte;
wColDesc.data = dDesc;
appendResetDescriptor(0, dialog.getSelectedCodepage(), false, wColDesc);
reloadData();
}
void CPUDump::integerSignedShortSlot()
{
Config()->setUint("HexDump", "DefaultView", (duint)ViewIntegerSignedShort);
@ -1656,3 +1648,63 @@ void CPUDump::gotoPrevSlot()
historyPrev();
}
void CPUDump::setView(ViewEnum_t view)
{
switch(view)
{
case ViewHexAscii:
hexAsciiSlot();
break;
case ViewHexUnicode:
hexUnicodeSlot();
break;
case ViewTextAscii:
textAsciiSlot();
break;
case ViewTextUnicode:
textUnicodeSlot();
break;
case ViewIntegerSignedShort:
integerSignedShortSlot();
break;
case ViewIntegerSignedLong:
integerSignedLongSlot();
break;
case ViewIntegerSignedLongLong:
integerSignedLongLongSlot();
break;
case ViewIntegerUnsignedShort:
integerUnsignedShortSlot();
break;
case ViewIntegerUnsignedLong:
integerUnsignedLongSlot();
break;
case ViewIntegerUnsignedLongLong:
integerUnsignedLongLongSlot();
break;
case ViewIntegerHexShort:
integerHexShortSlot();
break;
case ViewIntegerHexLong:
integerHexLongSlot();
break;
case ViewIntegerHexLongLong:
integerHexLongLongSlot();
break;
case ViewFloatFloat:
floatFloatSlot();
break;
case ViewFloatDouble:
floatDoubleSlot();
break;
case ViewFloatLongDouble:
floatLongDoubleSlot();
break;
case ViewAddress:
addressSlot();
break;
default:
hexAsciiSlot();
break;
}
}

View File

@ -52,9 +52,11 @@ public slots:
void hexAsciiSlot();
void hexUnicodeSlot();
void hexCodepageSlot();
void textAsciiSlot();
void textUnicodeSlot();
void textCodepageSlot();
void integerSignedShortSlot();
void integerSignedLongSlot();
@ -145,10 +147,12 @@ private:
QMenu* mHexMenu;
QAction* mHexAsciiAction;
QAction* mHexUnicodeAction;
QAction* mHexCodepageAction;
QMenu* mTextMenu;
QAction* mTextAsciiAction;
QAction* mTextUnicodeAction;
QAction* mTextCodepageAction;
QMenu* mIntegerMenu;
QAction* mIntegerSignedShortAction;
@ -224,6 +228,8 @@ private:
ViewFloatLongDouble,
ViewAddress
};
void setView(ViewEnum_t view);
};
#endif // CPUDUMP_H

View File

@ -0,0 +1,33 @@
#include "CodepageSelectionDialog.h"
#include "ui_CodepageSelectionDialog.h"
#include <QTextCodec>
CodepageSelectionDialog::CodepageSelectionDialog(QWidget* parent) :
QDialog(parent),
ui(new Ui::CodepageSelectionDialog)
{
ui->setupUi(this);
setModal(true);
setFixedSize(this->size()); //fixed size
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
setWindowIcon(QIcon(":/icons/images/codepage.png"));
for(auto & name : QTextCodec::availableCodecs())
{
auto codec = QTextCodec::codecForName(name);
if(!codec)
continue;
ui->listCodepages->addItem(name);
mCodepages.append(codec->name());
}
ui->listCodepages->setCurrentRow(0);
}
CodepageSelectionDialog::~CodepageSelectionDialog()
{
delete ui;
}
QByteArray CodepageSelectionDialog::getSelectedCodepage()
{
return mCodepages[ui->listCodepages->currentRow()];
}

View File

@ -0,0 +1,25 @@
#ifndef CODEPAGESELECTIONDIALOG_H
#define CODEPAGESELECTIONDIALOG_H
#include <QDialog>
namespace Ui
{
class CodepageSelectionDialog;
}
class CodepageSelectionDialog : public QDialog
{
Q_OBJECT
public:
explicit CodepageSelectionDialog(QWidget* parent = 0);
~CodepageSelectionDialog();
QByteArray getSelectedCodepage();
private:
Ui::CodepageSelectionDialog* ui;
QList<QByteArray> mCodepages;
};
#endif // CODEPAGESELECTIONDIALOG_H

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CodepageSelectionDialog</class>
<widget class="QDialog" name="CodepageSelectionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>396</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Select Codepage...</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="listCodepages"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonOk">
<property name="text">
<string>&amp;OK</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonCancel">
<property name="text">
<string>&amp;Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonOk</sender>
<signal>clicked()</signal>
<receiver>CodepageSelectionDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>280</y>
</hint>
<hint type="destinationlabel">
<x>204</x>
<y>273</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonCancel</sender>
<signal>clicked()</signal>
<receiver>CodepageSelectionDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>340</x>
<y>283</y>
</hint>
<hint type="destinationlabel">
<x>93</x>
<y>279</y>
</hint>
</hints>
</connection>
</connections>
</ui>

BIN
src/gui/images/codepage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

View File

@ -98,5 +98,6 @@
<file>images/dump.png</file>
<file>images/analyzesinglefunction.png</file>
<file>images/xrefs.png</file>
<file>images/codepage.png</file>
</qresource>
</RCC>

View File

@ -152,7 +152,8 @@ SOURCES += \
Src/Utils/HexValidator.cpp \
Src/Utils/LongLongValidator.cpp \
Src/Utils/MiscUtil.cpp \
Src/Gui/XrefBrowseDialog.cpp
Src/Gui/XrefBrowseDialog.cpp \
Src/Gui/CodepageSelectionDialog.cpp
HEADERS += \
@ -245,7 +246,8 @@ HEADERS += \
Src/Utils/HexValidator.h \
Src/Utils/LongLongValidator.h \
Src/Utils/MiscUtil.h \
Src/Gui/XrefBrowseDialog.h
Src/Gui/XrefBrowseDialog.h \
Src/Gui/CodepageSelectionDialog.h
FORMS += \
Src/Gui/MainWindow.ui \
@ -275,7 +277,8 @@ FORMS += \
Src/Gui/EditBreakpointDialog.ui \
Src/Gui/CPUArgumentWidget.ui \
Src/Gui/EditFloatRegister.ui \
Src/Gui/XrefBrowseDialog.ui
Src/Gui/XrefBrowseDialog.ui \
Src/Gui/CodepageSelectionDialog.ui
TRANSLATIONS = \
Translations/x64dbg_zh_CN.ts