Add feature to apply structure offset and fix some issues in EditVariablesDialog (#1215)

* Fixed EditVariablesDialog

* Added feature to apply structure offset in disassembly and graph view
This commit is contained in:
Gaurav Kumar Ghildiyal 2019-02-24 22:55:38 +05:30 committed by Itay Cohen
parent fa708143ac
commit a10ca8f033
5 changed files with 84 additions and 1 deletions

View File

@ -565,6 +565,16 @@ void CutterCore::setCurrentBits(int bits, RVA offset)
emit instructionChanged(offset);
}
void CutterCore::applyStructureOffset(const QString &structureOffset, RVA offset)
{
if (offset == RVA_INVALID) {
offset = getOffset();
}
this->cmdRaw("ta " + structureOffset + " @ " + QString::number(offset));
emit instructionChanged(offset);
}
void CutterCore::seek(ut64 offset)
{
// Slower than using the API, but the API is not complete

View File

@ -106,6 +106,15 @@ public:
void setImmediateBase(const QString &r2BaseName, RVA offset = RVA_INVALID);
void setCurrentBits(int bits, RVA offset = RVA_INVALID);
/*!
* \brief Changes immediate displacement to structure offset
* This function makes use of the "ta" command of r2 to apply structure
* offset to the immediate displacement used in the given instruction
* \param structureOffset The name of struct which will be applied
* \param offset The address of the instruction where the struct will be applied
*/
void applyStructureOffset(const QString &structureOffset, RVA offset = RVA_INVALID);
/* Classes */
QList<QString> getAllAnalClasses(bool sorted);
QList<AnalMethodDescription> getAnalClassMethods(const QString &cls);

View File

@ -41,6 +41,9 @@ void EditVariablesDialog::applyFields()
if (newName != desc.name) {
Core()->cmdRaw(QString("afvn %1 %2").arg(desc.name).arg(newName));
}
// Refresh the views to reflect the changes to vars
emit Core()->refreshCodeViews();
}
void EditVariablesDialog::updateFields()
@ -63,7 +66,7 @@ void EditVariablesDialog::populateTypesComboBox()
ui->typeComboBox->addItems(userStructures);
ui->typeComboBox->insertSeparator(ui->typeComboBox->count());
primitiveTypesTypeList = Core()->getAllTypes();
primitiveTypesTypeList = Core()->getAllPrimitiveTypes();
for (const TypeDescription &thisType : primitiveTypesTypeList) {
ui->typeComboBox->addItem(thisType.type);

View File

@ -71,6 +71,10 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
addSetBitsMenu();
structureOffsetMenu = addMenu(tr("Structure offset"));
connect(structureOffsetMenu, SIGNAL(triggered(QAction*)),
this, SLOT(on_actionStructureOffsetMenu_triggered(QAction*)));
initAction(&actionSetToCode, tr("Set as Code"),
SLOT(on_actionSetToCode_triggered()), getSetToCodeSequence());
addAction(&actionSetToCode);
@ -245,6 +249,48 @@ void DisassemblyContextMenu::aboutToShowSlot()
setBaseMenu->menuAction()->setVisible(immBase);
setBitsMenu->menuAction()->setVisible(true);
// Create structure offset menu if it makes sense
QString memBaseReg; // Base register
QVariant memDisp; // Displacement
if (instObject.contains("opex") && instObject["opex"].toObject().contains("operands")) {
// Loop through both the operands of the instruction
for (const QJsonValue value: instObject["opex"].toObject()["operands"].toArray()) {
QJsonObject operand = value.toObject();
if (operand.contains("type") && operand["type"].toString() == "mem" &&
operand.contains("base") && !operand["base"].toString().contains("bp") &&
operand.contains("disp") && operand["disp"].toVariant().toLongLong() > 0) {
// The current operand is the one which has an immediate displacement
memBaseReg = operand["base"].toString();
memDisp = operand["disp"].toVariant();
break;
}
}
}
if (memBaseReg.isEmpty()) {
// hide structure offset menu
structureOffsetMenu->menuAction()->setVisible(false);
} else {
// show structure offset menu
structureOffsetMenu->menuAction()->setVisible(true);
structureOffsetMenu->clear();
// Get the possible offsets using the "tas" command
// TODO: add tasj command to radare2 and then use it here
QString ret = Core()->cmd("tas " + memDisp.toString());
for (QString val: ret.split("\n")) {
if (val.isEmpty()) {
continue;
}
structureOffsetMenu->addAction("[" + memBaseReg + " + " + val + "]")->setData(val);
}
if (structureOffsetMenu->isEmpty()) {
// No possible offset was found so hide the menu
structureOffsetMenu->menuAction()->setVisible(false);
}
}
actionAnalyzeFunction.setVisible(true);
QString comment = Core()->cmd("CC." + RAddressString(offset));
@ -699,6 +745,11 @@ void DisassemblyContextMenu::on_actionSetToDataEx_triggered()
setToData(dialog->getItemSize(), dialog->getItemCount());
}
void DisassemblyContextMenu::on_actionStructureOffsetMenu_triggered(QAction *action)
{
Core()->applyStructureOffset(action->data().toString(), offset);
}
void DisassemblyContextMenu::on_actionDeleteComment_triggered()
{
Core()->delComment(offset);

View File

@ -55,6 +55,14 @@ private slots:
void on_actionSetToData_triggered();
void on_actionSetToDataEx_triggered();
/*!
* \brief Executed on selecting an offset from the structureOffsetMenu
* Uses the applyStructureOffset() function of CutterCore to apply the
* structure offset
* \param action The action which trigered the event
*/
void on_actionStructureOffsetMenu_triggered(QAction *action);
private:
QKeySequence getCopySequence() const;
QKeySequence getCommentSequence() const;
@ -100,6 +108,8 @@ private:
QAction actionDeleteFlag;
QAction actionDeleteFunction;
QMenu *structureOffsetMenu;
QMenu *setBaseMenu;
QAction actionSetBaseBinary;
QAction actionSetBaseOctal;