1
0
Fork 0

Added AssembleDialog with "Keep Size" checkbox to check give feedback to the user about the length of the instruction he's typing/vs the one to replace

This commit is contained in:
Herzeh 2015-12-03 19:53:08 +01:00
parent 5e647ecea7
commit 149b3c5c23
8 changed files with 379 additions and 19 deletions

View File

@ -0,0 +1,144 @@
#include "AssembleDialog.h"
#include "ui_AssembleDialog.h"
#include <QMessageBox>
bool AssembleDialog::bWarningShowedOnce = false;
AssembleDialog::AssembleDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AssembleDialog)
{
ui->setupUi(this);
setModal(true);
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint);
#endif
setFixedSize(this->size()); //fixed size
bKeepSizeChecked = false;
bFillWithNopsChecked = false;
selectedInstrVa = 0;
}
AssembleDialog::~AssembleDialog()
{
delete ui;
}
void AssembleDialog::setTextEditValue(const QString &text)
{
ui->lineEdit->setText(text);
}
void AssembleDialog::setKeepSizeChecked(bool checked)
{
ui->checkBoxKeepSize->setChecked(checked);
bKeepSizeChecked = checked;
}
void AssembleDialog::setKeepSizeLabel(const QString &text)
{
ui->labelKeepSize->setText(text);
}
void AssembleDialog::setFillWithNopsChecked(bool checked)
{
ui->checkBoxFillWithNops->setChecked(checked);
bFillWithNopsChecked = checked;
}
void AssembleDialog::setFillWithNopsLabel(const QString &text)
{
ui->labelFillWithNops->setText(text);
}
void AssembleDialog::setSelectedInstrVa(const duint va)
{
this->selectedInstrVa = va;
}
void AssembleDialog::compareTypedInstructionToSelected()
{
char error[MAX_ERROR_SIZE] = "";
BASIC_INSTRUCTION_INFO basicInstrInfo;
int typedInstructionSize = 0, selectedInstructionSize = 0;
// Get selected instruction info (size here)
DbgDisasmFastAt(this->selectedInstrVa, &basicInstrInfo);
selectedInstructionSize = basicInstrInfo.size;
// Get typed in instruction size
if(!DbgFunctions()->Assemble(0, NULL, &typedInstructionSize, editText.toUtf8().constData(), error) || selectedInstructionSize == 0)
{
this->setKeepSizeLabel("<font color='orange'><b>Instruction decoding error : " + QString(error) + "</b></font>");
return;
}
if(typedInstructionSize > selectedInstructionSize)
{
int sizeDifference = typedInstructionSize - selectedInstructionSize;
QString errorMessage = "<font color='red'><b>Instruction bigger by " + QString::number(sizeDifference);
(sizeDifference == 1) ? errorMessage += QString(" byte</b></font>") : errorMessage += QString(" bytes</b></font>");
this->setKeepSizeLabel(errorMessage);
this->setOkButtonEnabled(false);
}
else
{
int sizeDifference = selectedInstructionSize - typedInstructionSize;
QString message;
if(!sizeDifference)
message = "<font color='#00cc00'><b>Instruction is same size</b></font>";
else
{
message = "<font color='#00cc00'><b>Instruction smaller by " + QString::number(sizeDifference);
(sizeDifference == 1) ? message += QString(" byte</b></font>") : message += QString(" bytes</b></font>");
}
this->setKeepSizeLabel(message);
this->setOkButtonEnabled(true);
}
}
void AssembleDialog::setOkButtonEnabled(bool enabled)
{
ui->pushButtonOk->setEnabled(enabled);
}
void AssembleDialog::on_lineEdit_textChanged(const QString &arg1)
{
editText = arg1;
if(ui->checkBoxKeepSize->isChecked() && editText.size())
compareTypedInstructionToSelected();
}
void AssembleDialog::on_checkBoxKeepSize_clicked(bool checked)
{
// If first time ticking this checkbox, warn user about possible short dialog freeze when typing invalid instruction
if(checked && !AssembleDialog::bWarningShowedOnce)
{
int answer = QMessageBox::question(this, "Possible dialog freeze", "Enabling this option may cause this dialog to freeze for a short amount of time when typing invalid instruction. Do you still want to enable this ?", QMessageBox::Yes | QMessageBox::No);
if(answer == QMessageBox::No)
{
ui->checkBoxKeepSize->setChecked(false);
return;
}
else
AssembleDialog::bWarningShowedOnce = true;
}
if(checked && editText.size())
compareTypedInstructionToSelected();
else
{
ui->labelKeepSize->setText("");
ui->pushButtonOk->setEnabled(true);
}
bKeepSizeChecked = checked;
}
void AssembleDialog::on_checkBoxFillWithNops_clicked(bool checked)
{
bFillWithNopsChecked = checked;
}

View File

@ -0,0 +1,47 @@
#ifndef ASSEMBLEDIALOG_H
#define ASSEMBLEDIALOG_H
#include <QDialog>
#include <functional>
#include "Bridge.h"
namespace Ui
{
class AssembleDialog;
}
class AssembleDialog : public QDialog
{
Q_OBJECT
public:
explicit AssembleDialog(QWidget *parent = 0);
~AssembleDialog();
QString editText;
static bool bWarningShowedOnce;
void setTextEditValue(const QString & text);
bool bKeepSizeChecked;
void setKeepSizeChecked(bool checked);
void setKeepSizeLabel(const QString & text);
bool bFillWithNopsChecked;
void setFillWithNopsChecked(bool checked);
void setFillWithNopsLabel(const QString & text);
void setSelectedInstrVa(const duint va);
void compareTypedInstructionToSelected();
void setOkButtonEnabled(bool enabled);
private slots:
void on_lineEdit_textChanged(const QString &arg1);
void on_checkBoxKeepSize_clicked(bool checked);
void on_checkBoxFillWithNops_clicked(bool checked);
private:
Ui::AssembleDialog *ui;
duint selectedInstrVa;
};
#endif // ASSEMBLEDIALOG_H

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AssembleDialog</class>
<widget class="QDialog" name="AssembleDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>433</width>
<height>114</height>
</rect>
</property>
<property name="windowTitle">
<string>0</string>
</property>
<property name="windowIcon">
<iconset resource="../../resource.qrc">
<normaloff>:/icons/images/ui-combo-box-edit.png</normaloff>:/icons/images/ui-combo-box-edit.png</iconset>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>6</number>
</property>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="minimumSize">
<size>
<width>0</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="checkBoxKeepSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Keep Size</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelKeepSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="checkBoxFillWithNops">
<property name="text">
<string>Fill with NOP's</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelFillWithNops">
<property name="minimumSize">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonOk">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButtonCancel">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../../resource.qrc"/>
</resources>
<connections>
<connection>
<sender>pushButtonOk</sender>
<signal>clicked()</signal>
<receiver>AssembleDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>265</x>
<y>77</y>
</hint>
<hint type="destinationlabel">
<x>217</x>
<y>49</y>
</hint>
</hints>
</connection>
<connection>
<sender>pushButtonCancel</sender>
<signal>clicked()</signal>
<receiver>AssembleDialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>373</x>
<y>77</y>
</hint>
<hint type="destinationlabel">
<x>217</x>
<y>49</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -8,6 +8,7 @@
#include "WordEditDialog.h"
#include "HexEditDialog.h"
#include "YaraRuleSelectionDialog.h"
#include "AssembleDialog.h"
CPUDisassembly::CPUDisassembly(CPUWidget* parent) : Disassembly(parent)
{
@ -617,6 +618,8 @@ void CPUDisassembly::assembleSlot()
if(!DbgIsDebugging())
return;
AssembleDialog assembleDialog;
do
{
dsint wRVA = getInitialSelection();
@ -647,32 +650,34 @@ void CPUDisassembly::assembleSlot()
bool assembly_error;
do
{
char error[MAX_ERROR_SIZE] = "";
assembly_error = false;
LineEditDialog mLineEdit(this);
mLineEdit.setText(actual_inst);
mLineEdit.setWindowTitle("Assemble at " + addr_text);
mLineEdit.setCheckBoxText("&Fill with NOPs");
mLineEdit.enableCheckBox(true);
mLineEdit.setCheckBox(ConfigBool("Disassembler", "FillNOPs"));
if(mLineEdit.exec() != QDialog::Accepted)
assembleDialog.setSelectedInstrVa(wVA);
assembleDialog.setTextEditValue(actual_inst);
assembleDialog.setWindowTitle("Assemble at " + addr_text);
assembleDialog.setFillWithNopsChecked(ConfigBool("Disassembler", "FillNOPs"));
assembleDialog.setKeepSizeChecked(ConfigBool("Disassembler", "KeepSize"));
if(assembleDialog.exec() != QDialog::Accepted)
return;
//if the instruction its unkown or is the old instruction or empty (easy way to skip from GUI) skipping
if(mLineEdit.editText == QString("???") || mLineEdit.editText.toLower() == instr.instStr.toLower() || mLineEdit.editText == QString(""))
//if the instruction its unknown or is the old instruction or empty (easy way to skip from GUI) skipping
if(assembleDialog.editText == QString("???") || assembleDialog.editText.toLower() == instr.instStr.toLower() || assembleDialog.editText == QString(""))
break;
Config()->setBool("Disassembler", "FillNOPs", mLineEdit.bChecked);
Config()->setBool("Disassembler", "FillNOPs", assembleDialog.bFillWithNopsChecked);
Config()->setBool("Disassembler", "KeepSize", assembleDialog.bKeepSizeChecked);
char error[MAX_ERROR_SIZE] = "";
if(!DbgFunctions()->AssembleAtEx(wVA, mLineEdit.editText.toUtf8().constData(), error, mLineEdit.bChecked))
if(!DbgFunctions()->AssembleAtEx(wVA, assembleDialog.editText.toUtf8().constData(), error, assembleDialog.bFillWithNopsChecked))
{
QMessageBox msg(QMessageBox::Critical, "Error!", "Failed to assemble instruction \"" + mLineEdit.editText + "\" (" + error + ")");
QMessageBox msg(QMessageBox::Critical, "Error!", "Failed to assemble instruction \"" + assembleDialog.editText + "\" (" + error + ")");
msg.setWindowIcon(QIcon(":/icons/images/compile-error.png"));
msg.setParent(this, Qt::Dialog);
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
msg.exec();
actual_inst = mLineEdit.editText;
actual_inst = assembleDialog.editText;
assembly_error = true;
}
}

View File

@ -1228,7 +1228,7 @@ void MainWindow::tabMovedSlot(int from, int to)
void MainWindow::chkSaveloadTabSavedOrderStateChangedSlot(bool state)
{
if(state == Qt::Checked)
if(state)
loadTabSavedOrder();
else
loadTabDefaultOrder();

View File

@ -510,7 +510,7 @@
<item>
<widget class="QCheckBox" name="chkSaveLoadTabOrder">
<property name="text">
<string>Load/Save Tab Order</string>
<string>Enable Load/Save Tab Order</string>
</property>
</widget>
</item>

View File

@ -159,6 +159,7 @@ Configuration::Configuration() : QObject()
QMap<QString, bool> disassemblyBool;
disassemblyBool.insert("ArgumentSpaces", false);
disassemblyBool.insert("MemorySpaces", false);
disassemblyBool.insert("KeepSize", false);
disassemblyBool.insert("FillNOPs", false);
disassemblyBool.insert("Uppercase", false);
disassemblyBool.insert("FindCommandEntireBlock", false);

View File

@ -139,7 +139,8 @@ SOURCES += \
Src/Gui/EntropyDialog.cpp \
Src/Gui/NotesManager.cpp \
Src/Gui/NotepadView.cpp \
Src/Gui/CPUMultiDump.cpp
Src/Gui/CPUMultiDump.cpp \
Src/Gui/AssembleDialog.cpp
HEADERS += \
@ -220,7 +221,8 @@ HEADERS += \
Src/Gui/NotepadView.h \
Src/Utils/MenuBuilder.h \
Src/Utils/QActionLambda.h \
Src/Gui/CPUMultiDump.h
Src/Gui/CPUMultiDump.h \
Src/Gui/AssembleDialog.h
FORMS += \
Src/Gui/MainWindow.ui \
@ -245,7 +247,8 @@ FORMS += \
Src/Gui/SelectFields.ui \
Src/Gui/YaraRuleSelectionDialog.ui \
Src/Gui/DataCopyDialog.ui \
Src/Gui/EntropyDialog.ui
Src/Gui/EntropyDialog.ui \
Src/Gui/AssembleDialog.ui
##
## Libraries