1
0
Fork 0
x64dbg/src/gui/Src/Gui/WordEditDialog.cpp

188 lines
5.8 KiB
C++

#include "WordEditDialog.h"
#include "ui_WordEditDialog.h"
#include "ValidateExpressionThread.h"
#include "StringUtil.h"
#include <Configuration.h>
WordEditDialog::WordEditDialog(QWidget* parent)
: QDialog(parent),
ui(new Ui::WordEditDialog),
mHexLineEditPos(0),
mSignedEditPos(0),
mUnsignedEditPos(0),
mAsciiLineEditPos(0)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
setModal(true);
// Set up default validators for numerical input
ui->signedLineEdit->setValidator(new QRegExpValidator(QRegExp("^-?\\d*(\\d+)?$"), this));// Optional negative, 0-9
ui->unsignedLineEdit->setValidator(new QRegExpValidator(QRegExp("^\\d*(\\d+)?$"), this));// No signs, 0-9
mValidateThread = new ValidateExpressionThread(this);
mValidateThread->setOnExpressionChangedCallback(std::bind(&WordEditDialog::validateExpression, this, std::placeholders::_1));
connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, dsint)), this, SLOT(expressionChanged(bool, bool, dsint)));
connect(ui->expressionLineEdit, SIGNAL(textChanged(QString)), mValidateThread, SLOT(textChanged(QString)));
mWord = 0;
Config()->setupWindowPos(this);
}
void WordEditDialog::validateExpression(QString expression)
{
duint value;
bool validExpression = DbgFunctions()->ValFromString(expression.toUtf8().constData(), &value);
bool validPointer = validExpression && DbgMemIsValidReadPtr(value);
this->mValidateThread->emitExpressionChanged(validExpression, validPointer, value);
}
WordEditDialog::~WordEditDialog()
{
Config()->saveWindowPos(this);
mValidateThread->stop();
mValidateThread->wait();
delete ui;
}
void WordEditDialog::showEvent(QShowEvent* event)
{
Q_UNUSED(event);
mValidateThread->start();
}
void WordEditDialog::hideEvent(QHideEvent* event)
{
Q_UNUSED(event);
mValidateThread->stop();
mValidateThread->wait();
}
void WordEditDialog::setup(QString title, duint defVal, int byteCount)
{
this->setWindowTitle(title);
ui->hexLineEdit->setInputMask(QString("hh").repeated(byteCount));
ui->expressionLineEdit->setText(QString("%1").arg(defVal, byteCount * 2, 16, QChar('0')).toUpper());
ui->expressionLineEdit->selectAll();
ui->expressionLineEdit->setFocus();
}
duint WordEditDialog::getVal()
{
return mWord;
}
void WordEditDialog::expressionChanged(bool validExpression, bool validPointer, dsint value)
{
Q_UNUSED(validPointer);
if(validExpression)
{
ui->btnOk->setEnabled(true);
//hex
mWord = value;
duint hexWord = 0;
unsigned char* hex = (unsigned char*)&hexWord;
unsigned char* word = (unsigned char*)&mWord;
// ascii
int asciiWidth = 0;
#ifdef _WIN64
hex[0] = word[7];
hex[1] = word[6];
hex[2] = word[5];
hex[3] = word[4];
hex[4] = word[3];
hex[5] = word[2];
hex[6] = word[1];
hex[7] = word[0];
asciiWidth = 8;
#else //x86
hex[0] = word[3];
hex[1] = word[2];
hex[2] = word[1];
hex[3] = word[0];
asciiWidth = 4;
#endif //_WIN64
// Save the original index for inputs
saveCursorPositions();
// Byte edit line
ui->hexLineEdit->setText(ToPtrString(hexWord));
// Signed edit
ui->signedLineEdit->setText(QString::number((dsint)mWord));
// Unsigned edit
ui->unsignedLineEdit->setText(QString::number((duint)mWord));
// ASCII edit
QString asciiExp;
for(int i = 0; i < asciiWidth; i++)
{
// replace non-printable chars with a dot
if(hex[i] != NULL && QChar(hex[i]).isPrint())
asciiExp.append(QChar(hex[i]));
else
asciiExp.append("."); // dots padding
}
ui->asciiLineEdit->setText(asciiExp);
// Use the same indices, but with different text
restoreCursorPositions();
}
else
{
ui->expressionLineEdit->setStyleSheet("border: 1px solid red");
ui->btnOk->setEnabled(false);
}
}
void WordEditDialog::on_signedLineEdit_textEdited(const QString & arg1)
{
LONGLONG value;
if(sscanf_s(arg1.toUtf8().constData(), "%lld", &value) == 1)
{
ui->signedLineEdit->setStyleSheet("");
ui->btnOk->setEnabled(true);
ui->expressionLineEdit->setText(ToPtrString((duint)value));
}
else
{
ui->signedLineEdit->setStyleSheet("border: 1px solid red");
ui->btnOk->setEnabled(false);
}
}
void WordEditDialog::on_unsignedLineEdit_textEdited(const QString & arg1)
{
LONGLONG value;
if(sscanf_s(arg1.toUtf8().constData(), "%llu", &value) == 1)
{
ui->unsignedLineEdit->setStyleSheet("");
ui->btnOk->setEnabled(true);
ui->expressionLineEdit->setText(ToPtrString((duint)value));
}
else
{
ui->unsignedLineEdit->setStyleSheet("border: 1px solid red");
ui->btnOk->setEnabled(false);
}
}
void WordEditDialog::saveCursorPositions()
{
// Save the user's cursor index
mHexLineEditPos = ui->hexLineEdit->cursorPosition();
mSignedEditPos = ui->signedLineEdit->cursorPosition();
mUnsignedEditPos = ui->unsignedLineEdit->cursorPosition();
mAsciiLineEditPos = ui->asciiLineEdit->cursorPosition();
}
void WordEditDialog::restoreCursorPositions()
{
// Load the old cursor index (bounds checking is automatic)
ui->hexLineEdit->setCursorPosition(mHexLineEditPos);
ui->signedLineEdit->setCursorPosition(mSignedEditPos);
ui->unsignedLineEdit->setCursorPosition(mUnsignedEditPos);
ui->asciiLineEdit->setCursorPosition(mAsciiLineEditPos);
}