afvn/afvt support via context menu (#708)

* Added ability to re-type local vars in Dissassembly Widget.  Can re-type to any loaded structs, types or enums
* afvn support via context menu
This commit is contained in:
jamieb122 2018-10-03 13:10:53 -07:00 committed by xarkes
parent e3bc744024
commit be4144babe
6 changed files with 359 additions and 3 deletions

View File

@ -194,7 +194,8 @@ SOURCES += \
dialogs/BreakpointsDialog.cpp \
dialogs/AttachProcDialog.cpp \
widgets/RegisterRefsWidget.cpp \
dialogs/SetToDataDialog.cpp
dialogs/SetToDataDialog.cpp \
dialogs/SetFunctionVarTypes.cpp
HEADERS += \
Cutter.h \
@ -289,7 +290,8 @@ HEADERS += \
dialogs/AttachProcDialog.h \
widgets/RegisterRefsWidget.h \
dialogs/SetToDataDialog.h \
utils/InitialOptions.h
utils/InitialOptions.h \
dialogs/SetFunctionVarTypes.h
FORMS += \
dialogs/AboutDialog.ui \
@ -343,7 +345,8 @@ FORMS += \
dialogs/BreakpointsDialog.ui \
dialogs/AttachProcDialog.ui \
widgets/RegisterRefsWidget.ui \
dialogs/SetToDataDialog.ui
dialogs/SetToDataDialog.ui \
dialogs/SetFunctionVarTypes.ui
RESOURCES += \
resources.qrc \

View File

@ -0,0 +1,118 @@
#include "SetFunctionVarTypes.h"
#include "ui_SetFunctionVarTypes.h"
#include <QMetaType>
#include <QComboBox>
SetFunctionVarTypes::SetFunctionVarTypes(QWidget *parent) :
QDialog(parent),
ui(new Ui::SetFunctionVarTypes)
{
ui->setupUi(this);
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(on_OkPressed()));
connect(ui->dropdownLocalVars, SIGNAL(currentIndexChanged(QString)),
SLOT(on_ComboBoxChanged(QString)));
populateTypesComboBox();
}
SetFunctionVarTypes::~SetFunctionVarTypes()
{
delete ui;
}
void SetFunctionVarTypes::setUserMessage(const QString userMessage)
{
ui->userMessage->setText(userMessage);
}
void SetFunctionVarTypes::setFcn(RAnalFunction *fcn)
{
RListIter *iter;
RAnalVar *var;
if (fcn == nullptr) {
ui->userMessage->setText(tr("You must be in a function to define variable types."));
ui->labelSetTypeTo->setVisible(false);
ui->selectedTypeForVar->setVisible(false);
ui->dropdownLocalVars->setVisible(false);
this->validFcn = false;
return;
}
ui->userMessage->setVisible(true);
ui->labelSetTypeTo->setVisible(true);
ui->selectedTypeForVar->setVisible(true);
ui->dropdownLocalVars->setVisible(true);
this->validFcn = true;
this->fcn = fcn;
this->fcnVars = r_anal_var_all_list(Core()->core()->anal, this->fcn);
for (iter = this->fcnVars->head; iter
&& (var = static_cast<RAnalVar *>(iter->data)); iter = iter->n) {
ui->dropdownLocalVars->addItem(var->name,
QVariant::fromValue(static_cast<void *>(var)));
}
}
void SetFunctionVarTypes::on_OkPressed()
{
RAnalVar *selectedVar;
QVariant selectedVarVariant;
if (!this->validFcn) {
return;
}
selectedVarVariant = ui->dropdownLocalVars->currentData();
selectedVar = static_cast<RAnalVar *>(selectedVarVariant.value<void *>());
Core()->cmd(QString("afvt %1 %2")
.arg(selectedVar->name)
.arg(ui->selectedTypeForVar->currentText()));
Core()->cmd(QString("afvn %1 %2")
.arg(ui->newVarName->text().replace(" ", "_"))
.arg(ui->dropdownLocalVars->currentText()));
}
void SetFunctionVarTypes::on_ComboBoxChanged(QString varName)
{
ui->newVarName->setText(varName);
}
void SetFunctionVarTypes::populateTypesComboBox()
{
//gets all loaded types, structures and enums and puts them in a list
QString res;
QStringList userStructures;
QStringList userEnumerations;
QList<TypeDescription> primitiveTypesTypeList;
res = Core()->cmd(QString("ts"));
userStructures = res.split("\n");
userStructures.removeAll(QString(""));
ui->selectedTypeForVar->addItems(userStructures);
ui->selectedTypeForVar->insertSeparator(ui->selectedTypeForVar->count());
primitiveTypesTypeList = Core()->getAllTypes();
for (TypeDescription thisType : primitiveTypesTypeList) {
ui->selectedTypeForVar->addItem(thisType.type);
}
ui->selectedTypeForVar->insertSeparator(ui->selectedTypeForVar->count());
res = Core()->cmd(QString("te"));
userStructures = res.split("\n");
userStructures.removeAll(QString(""));
ui->selectedTypeForVar->addItems(userStructures);
return;
}

View File

@ -0,0 +1,36 @@
#ifndef SETFUNCTIONVARTYPES_H
#define SETFUNCTIONVARTYPES_H
#include "Cutter.h"
#include <QDialog>
namespace Ui {
class SetFunctionVarTypes;
}
class SetFunctionVarTypes : public QDialog
{
Q_OBJECT
public:
explicit SetFunctionVarTypes(QWidget *parent = nullptr);
~SetFunctionVarTypes();
void setUserMessage(const QString userMessage);
void setFcn(RAnalFunction *fcn);
public slots:
void on_OkPressed();
void on_ComboBoxChanged(QString varName);
private:
RList *fcnVars;
RAnalFunction *fcn;
Ui::SetFunctionVarTypes *ui;
bool validFcn;
void populateTypesComboBox();
};
#endif // SETFUNCTIONVARTYPES_H

View File

@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SetFunctionVarTypes</class>
<widget class="QDialog" name="SetFunctionVarTypes">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>636</width>
<height>327</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>10</x>
<y>290</y>
<width>621</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="userMessage">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>601</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QComboBox" name="dropdownLocalVars">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>271</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="labelSetTypeTo">
<property name="geometry">
<rect>
<x>30</x>
<y>180</y>
<width>91</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Set Type To:</string>
</property>
</widget>
<widget class="QComboBox" name="selectedTypeForVar">
<property name="geometry">
<rect>
<x>30</x>
<y>210</y>
<width>261</width>
<height>31</height>
</rect>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="maxVisibleItems">
<number>15</number>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>110</y>
<width>241</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Set Name To:</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Modify:</string>
</property>
</widget>
<widget class="QLineEdit" name="newVarName">
<property name="geometry">
<rect>
<x>30</x>
<y>140</y>
<width>261</width>
<height>31</height>
</rect>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SetFunctionVarTypes</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SetFunctionVarTypes</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -5,6 +5,7 @@
#include "dialogs/FlagDialog.h"
#include "dialogs/RenameDialog.h"
#include "dialogs/XrefsDialog.h"
#include "dialogs/SetFunctionVarTypes.h"
#include "dialogs/SetToDataDialog.h"
#include <QtCore>
#include <QShortcut>
@ -41,6 +42,10 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent)
SLOT(on_actionRenameUsedHere_triggered()), getRenameUsedHereSequence());
addAction(&actionRenameUsedHere);
initAction(&actionSetFunctionVarTypes, tr("Re-type function local vars"),
SLOT(on_actionSetFunctionVarTypes_triggered()), getRetypeSequence());
addAction(&actionSetFunctionVarTypes);
initAction(&actionDeleteComment, tr("Delete comment"), SLOT(on_actionDeleteComment_triggered()));
addAction(&actionDeleteComment);
@ -246,6 +251,7 @@ void DisassemblyContextMenu::aboutToShowSlot()
RCore *core = Core()->core();
RAnalFunction *fcn = r_anal_get_fcn_at (core->anal, offset, R_ANAL_FCN_TYPE_NULL);
RAnalFunction *in_fcn = Core()->functionAt(offset);
RFlagItem *f = r_flag_get_i (core->flags, offset);
actionDeleteFlag.setVisible(f ? true : false);
@ -262,6 +268,16 @@ void DisassemblyContextMenu::aboutToShowSlot()
actionRename.setVisible(false);
}
//only show retype for local vars if in a function
if(in_fcn)
{
actionSetFunctionVarTypes.setVisible(true);
}
else
{
actionSetFunctionVarTypes.setVisible(false);
}
// only show "rename X used here" if there is something to rename
QJsonArray thingUsedHereArray = Core()->cmdj("anj @ " + QString::number(offset)).array();
@ -331,6 +347,11 @@ QKeySequence DisassemblyContextMenu::getRenameUsedHereSequence() const
return {Qt::SHIFT + Qt::Key_N};
}
QKeySequence DisassemblyContextMenu::getRetypeSequence() const
{
return {Qt::Key_Y};
}
QKeySequence DisassemblyContextMenu::getXRefSequence() const
{
return {Qt::Key_X};
@ -587,6 +608,25 @@ void DisassemblyContextMenu::on_actionRenameUsedHere_triggered()
}
}
void DisassemblyContextMenu::on_actionSetFunctionVarTypes_triggered()
{
SetFunctionVarTypes *dialog;
RAnalFunction *fcn = Core()->functionAt(offset);
dialog = new SetFunctionVarTypes(this);
if(fcn)
{
dialog->setWindowTitle(tr("Set Variable Types for Function: %1").arg(fcn->name));
}
dialog->setFcn(fcn);
dialog->exec();
}
void DisassemblyContextMenu::on_actionXRefs_triggered()
{
XrefsDialog *dialog = new XrefsDialog(this);

View File

@ -37,6 +37,7 @@ private slots:
void on_actionAddFlag_triggered();
void on_actionRename_triggered();
void on_actionRenameUsedHere_triggered();
void on_actionSetFunctionVarTypes_triggered();
void on_actionXRefs_triggered();
void on_actionDisplayOptions_triggered();
@ -61,6 +62,7 @@ private:
QKeySequence getAddFlagSequence() const;
QKeySequence getRenameSequence() const;
QKeySequence getRenameUsedHereSequence() const;
QKeySequence getRetypeSequence() const;
QKeySequence getXRefSequence() const;
QKeySequence getDisplayOptionsSequence() const;
QList<QKeySequence> getAddBPSequence() const;
@ -86,6 +88,7 @@ private:
QAction actionAnalyzeFunction;
QAction actionRename;
QAction actionRenameUsedHere;
QAction actionSetFunctionVarTypes;
QAction actionXRefs;
QAction actionDisplayOptions;