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

258 lines
7.9 KiB
C++

#include "CalculatorDialog.h"
#include "ui_CalculatorDialog.h"
#include "ValidateExpressionThread.h"
CalculatorDialog::CalculatorDialog(QWidget* parent) : QDialog(parent), ui(new Ui::CalculatorDialog)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
connect(this, SIGNAL(validAddress(bool)), ui->btnGoto, SLOT(setEnabled(bool)));
connect(this, SIGNAL(validAddress(bool)), ui->btnGotoDump, SLOT(setEnabled(bool)));
emit validAddress(false);
ui->txtBin->setInputMask(QString("bbbb ").repeated(sizeof(duint) * 2));
ui->txtExpression->setText("0");
ui->txtExpression->selectAll();
ui->txtExpression->setFocus();
mValidateThread = new ValidateExpressionThread(this);
mValidateThread->setOnExpressionChangedCallback(std::bind(&CalculatorDialog::validateExpression, this, std::placeholders::_1));
connect(mValidateThread, SIGNAL(expressionChanged(bool, bool, dsint)), this, SLOT(expressionChanged(bool, bool, dsint)));
connect(ui->txtExpression, SIGNAL(textChanged(QString)), mValidateThread, SLOT(textChanged(QString)));
}
CalculatorDialog::~CalculatorDialog()
{
mValidateThread->stop();
mValidateThread->wait();
delete ui;
}
void CalculatorDialog::validateExpression(QString expression)
{
duint value;
bool validExpression = DbgFunctions()->ValFromString(expression.toUtf8().constData(), &value);
bool validPointer = validExpression && DbgMemIsValidReadPtr(value);
this->mValidateThread->emitExpressionChanged(validExpression, validPointer, value);
}
void CalculatorDialog::showEvent(QShowEvent* event)
{
Q_UNUSED(event);
mValidateThread->start();
}
void CalculatorDialog::hideEvent(QHideEvent* event)
{
Q_UNUSED(event);
mValidateThread->stop();
mValidateThread->wait();
}
void CalculatorDialog::setExpressionFocus()
{
ui->txtExpression->selectAll();
ui->txtExpression->setFocus();
}
void CalculatorDialog::expressionChanged(bool validExpression, bool validPointer, dsint value)
{
if(!validExpression)
{
ui->txtBin->setText("");
ui->txtSignedDec->setText("");
ui->txtUnsignedDec->setText("");
ui->txtHex->setText("");
ui->txtOct->setText("");
ui->txtAscii->setText("");
ui->txtUnicode->setText("");
ui->txtExpression->setStyleSheet("border: 2px solid red");
emit validAddress(false);
}
else
{
ui->txtExpression->setStyleSheet("");
ui->txtHex->setText(inFormat(value, N_HEX));
ui->txtSignedDec->setText(inFormat(value, N_SDEC));
ui->txtUnsignedDec->setText(inFormat(value, N_UDEC));
int cursorpos = ui->txtBin->cursorPosition();
ui->txtBin->setText(inFormat(value, N_BIN));
ui->txtBin->setCursorPosition(cursorpos);
ui->txtOct->setText(inFormat(value, N_OCT));
if(value == (value & 0xFF))
{
QChar c((ushort)value);
if(c.isPrint())
ui->txtAscii->setText(QString(c));
else
ui->txtAscii->setText("???");
}
else
ui->txtAscii->setText("???");
ui->txtAscii->setCursorPosition(0);
ui->txtAscii->selectAll();
if((value == (value & 0xFFFF))) //UNICODE?
{
QChar c = QChar((ushort)value);
if(c.isPrint())
ui->txtUnicode->setText(QString(c));
else
ui->txtUnicode->setText("????");
}
else
{
ui->txtUnicode->setText("????");
}
ui->txtUnicode->setCursorPosition(0);
ui->txtUnicode->selectAll();
emit validAddress(validPointer);
}
}
void CalculatorDialog::on_txtExpression_textChanged(const QString & arg1)
{
Q_UNUSED(arg1);
ui->txtHex->setStyleSheet("");
ui->txtSignedDec->setStyleSheet("");
ui->txtUnsignedDec->setStyleSheet("");
ui->txtOct->setStyleSheet("");
ui->txtBin->setStyleSheet("");
ui->txtAscii->setStyleSheet("");
ui->txtUnicode->setStyleSheet("");
emit validAddress(false);
}
QString CalculatorDialog::inFormat(const duint val, CalculatorDialog::NUMBERFORMAT NF) const
{
switch(NF)
{
default:
case N_HEX:
return QString("%1").arg(val, 1, 16, QChar('0')).toUpper();
case N_SDEC:
return QString("%1").arg((dsint)val);
case N_UDEC:
return QString("%1").arg(val);
case N_BIN:
{
QString binary = QString("%1").arg(val, 8 * sizeof(duint), 2, QChar('0')).toUpper();
QString ans = "";
for(int i = 0; i < sizeof(duint) * 8; i++)
{
if((i % 4 == 0) && (i != 0))
ans += " ";
ans += binary[i];
}
return ans;
}
case N_OCT:
return QString("%1").arg(val, 1, 8, QChar('0')).toUpper();
case N_ASCII:
return QString("%1").arg(QChar((ushort)val));
}
}
void CalculatorDialog::on_btnGoto_clicked()
{
DbgCmdExecDirect(QString("disasm " + ui->txtExpression->text()).toUtf8().constData());
}
void CalculatorDialog::on_txtHex_textEdited(const QString & arg1)
{
bool ok = false;
ULONGLONG val = arg1.toULongLong(&ok, 16);
if(!ok)
{
ui->txtHex->setStyleSheet("border: 2px solid red");
return;
}
ui->txtHex->setStyleSheet("");
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
}
void CalculatorDialog::on_txtSignedDec_textEdited(const QString & arg1)
{
bool ok = false;
LONGLONG val = arg1.toLongLong(&ok, 10);
if(!ok)
{
ui->txtUnsignedDec->setStyleSheet("border: 2px solid red");
return;
}
ui->txtUnsignedDec->setStyleSheet("");
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
}
void CalculatorDialog::on_txtUnsignedDec_textEdited(const QString & arg1)
{
bool ok = false;
LONGLONG val = arg1.toULongLong(&ok, 10);
if(!ok)
{
ui->txtUnsignedDec->setStyleSheet("border: 2px solid red");
return;
}
ui->txtUnsignedDec->setStyleSheet("");
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
}
void CalculatorDialog::on_txtOct_textEdited(const QString & arg1)
{
bool ok = false;
ULONGLONG val = arg1.toULongLong(&ok, 8);
if(!ok)
{
ui->txtOct->setStyleSheet("border: 2px solid red");
return;
}
ui->txtOct->setStyleSheet("");
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
}
void CalculatorDialog::on_txtBin_textEdited(const QString & arg1)
{
bool ok = false;
QString text = arg1;
text = text.replace(" ", "");
ULONGLONG val = text.toULongLong(&ok, 2);
if(!ok)
{
ui->txtBin->setStyleSheet("border: 2px solid red");
return;
}
ui->txtBin->setStyleSheet("");
ui->txtExpression->setText(QString("%1").arg(val, 1, 16, QChar('0')).toUpper());
}
void CalculatorDialog::on_txtAscii_textEdited(const QString & arg1)
{
QString text = arg1;
ui->txtAscii->setStyleSheet("");
ui->txtExpression->setText(QString().sprintf("%X", text[0].unicode()));
ui->txtAscii->setCursorPosition(0);
ui->txtAscii->selectAll();
}
void CalculatorDialog::on_txtUnicode_textEdited(const QString & arg1)
{
QString text = arg1;
ui->txtUnicode->setStyleSheet("");
ui->txtExpression->setText(QString().sprintf("%X", text[0].unicode()));
ui->txtUnicode->setCursorPosition(0);
ui->txtUnicode->selectAll();
}
void CalculatorDialog::on_txtAscii_clicked()
{
ui->txtAscii->selectAll();
}
void CalculatorDialog::on_txtUnicode_clicked()
{
ui->txtUnicode->selectAll();
}
void CalculatorDialog::on_btnGotoDump_clicked()
{
DbgCmdExecDirect(QString("dump " + ui->txtExpression->text()).toUtf8().constData());
}