mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-19 02:48:49 +00:00
Improve InitialOptionsDialog and modify UI terminology for analysis (#1669)
* Define CommandDescription struct * Refactor InitialOptionsDialog to to work with CommandDescription * Clean InitialOptionsDialog UI
This commit is contained in:
parent
2f0c0ddc23
commit
330795a650
@ -173,10 +173,10 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
|
|||||||
options.analCmd = {};
|
options.analCmd = {};
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
options.analCmd = { "aaa" };
|
options.analCmd = { {"aaa", "Auto analysis"} };
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
options.analCmd = { "aaaa" };
|
options.analCmd = { {"aaaa", "Auto analysis (experimental)"} };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,13 +96,13 @@ void AnalTask::runTask()
|
|||||||
Core()->setConfig("prj.simple", true);
|
Core()->setConfig("prj.simple", true);
|
||||||
|
|
||||||
if (!options.analCmd.empty()) {
|
if (!options.analCmd.empty()) {
|
||||||
log(tr("Analyzing..."));
|
log(tr("Executing analysis..."));
|
||||||
for (const QString &cmd : options.analCmd) {
|
for (const CommandDescription &cmd : options.analCmd) {
|
||||||
if (isInterrupted()) {
|
if (isInterrupted()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log(" " + tr("Running") + " " + cmd);
|
log(cmd.description);
|
||||||
Core()->cmd(cmd);
|
Core()->cmd(cmd.command);
|
||||||
}
|
}
|
||||||
log(tr("Analysis complete!"));
|
log(tr("Analysis complete!"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,6 +4,14 @@
|
|||||||
|
|
||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The CommandDescription struct is a pair of a radare2 command and its description
|
||||||
|
*/
|
||||||
|
struct CommandDescription {
|
||||||
|
QString command;
|
||||||
|
QString description;
|
||||||
|
};
|
||||||
|
|
||||||
struct InitialOptions
|
struct InitialOptions
|
||||||
{
|
{
|
||||||
enum class Endianness { Auto, Little, Big };
|
enum class Endianness { Auto, Little, Big };
|
||||||
@ -30,7 +38,7 @@ struct InitialOptions
|
|||||||
QString pdbFile;
|
QString pdbFile;
|
||||||
QString script;
|
QString script;
|
||||||
|
|
||||||
QList<QString> analCmd = { "aaa" };
|
QList<CommandDescription> analCmd = { {"aaa", "Auto analysis"} };
|
||||||
|
|
||||||
QString shellcode;
|
QString shellcode;
|
||||||
};
|
};
|
||||||
|
@ -50,8 +50,36 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main):
|
|||||||
ui->formatComboBox->addItem(plugin.name, QVariant::fromValue(plugin));
|
ui->formatComboBox->addItem(plugin.name, QVariant::fromValue(plugin));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
analysisCommands = {
|
||||||
|
{ { "aa", tr("Analyze all symbols") }, new QCheckBox(), true },
|
||||||
|
{ { "aar", tr("Analyze instructions for references") }, new QCheckBox(), true },
|
||||||
|
{ { "aac", tr("Analyze function calls") }, new QCheckBox(), true },
|
||||||
|
{ { "aab", tr("Analyze all basic blocks") }, new QCheckBox(), false },
|
||||||
|
{ { "aao", tr("Analyze all objc references") }, new QCheckBox(), false },
|
||||||
|
{ { "avrr", tr("Recover class information from RTTI") }, new QCheckBox(), false },
|
||||||
|
{ { "aan", tr("Autoname functions based on context") }, new QCheckBox(), false },
|
||||||
|
{ { "aae", tr("Emulate code to find computed references") }, new QCheckBox(), false },
|
||||||
|
{ { "aat", tr("Analyze all consecutive functions") }, new QCheckBox(), false },
|
||||||
|
{ { "aaft", tr("Type and Argument matching analysis") }, new QCheckBox(), false },
|
||||||
|
{ { "aaT", tr("Analyze code after trap-sleds") }, new QCheckBox(), false },
|
||||||
|
{ { "aap", tr("Analyze function preludes") }, new QCheckBox(), false },
|
||||||
|
{ { "e! anal.jmp.tbl", tr("Analyze jump tables in switch statements") }, new QCheckBox(), false },
|
||||||
|
{ { "e! anal.pushret", tr("Analyze PUSH+RET as JMP") }, new QCheckBox(), false },
|
||||||
|
{ { "e! anal.hasnext", tr("Continue analysis after each function") }, new QCheckBox(), false }};
|
||||||
|
|
||||||
|
// Per each checkbox, set a tooltip desccribing it
|
||||||
|
AnalysisCommands item;
|
||||||
|
foreach (item, analysisCommands){
|
||||||
|
item.checkbox->setText(item.commandDesc.description);
|
||||||
|
item.checkbox->setToolTip(item.commandDesc.command);
|
||||||
|
item.checkbox->setChecked(item.checked);
|
||||||
|
ui->verticalLayout_7->addWidget(item.checkbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ui->hideFrame->setVisible(false);
|
ui->hideFrame->setVisible(false);
|
||||||
ui->analoptionsFrame->setVisible(false);
|
ui->analoptionsFrame->setVisible(false);
|
||||||
|
ui->advancedAnlysisLine->setVisible(false);
|
||||||
|
|
||||||
updatePDBLayout();
|
updatePDBLayout();
|
||||||
|
|
||||||
@ -86,30 +114,30 @@ void InitialOptionsDialog::updateCPUComboBox()
|
|||||||
ui->cpuComboBox->lineEdit()->setText(currentText);
|
ui->cpuComboBox->lineEdit()->setText(currentText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QString> InitialOptionsDialog::getAnalysisCommands(const InitialOptions &options) {
|
||||||
|
QList<QString> commands;
|
||||||
|
for (auto& commandDesc: options.analCmd) {
|
||||||
|
commands << commandDesc.command;
|
||||||
|
}
|
||||||
|
return commands;
|
||||||
|
}
|
||||||
|
|
||||||
void InitialOptionsDialog::loadOptions(const InitialOptions &options)
|
void InitialOptionsDialog::loadOptions(const InitialOptions &options)
|
||||||
{
|
{
|
||||||
if (options.analCmd.isEmpty()) {
|
if (options.analCmd.isEmpty()) {
|
||||||
analLevel = 0;
|
analLevel = 0;
|
||||||
} else if (options.analCmd == QList<QString>({ "aaa" })) {
|
} else if (options.analCmd.first().command == "aaa" ) {
|
||||||
analLevel = 1;
|
analLevel = 1;
|
||||||
} else if (options.analCmd == QList<QString>({ "aaaa" })) {
|
} else if (options.analCmd.first().command == "aaaa" ) {
|
||||||
analLevel = 2;
|
analLevel = 2;
|
||||||
} else {
|
} else {
|
||||||
analLevel = 3;
|
analLevel = 3;
|
||||||
// TODO: These checks must always be in sync with getSelectedAdvancedAnalCmds(), which is dangerous
|
AnalysisCommands item;
|
||||||
ui->aa_symbols->setChecked(options.analCmd.contains("aa"));
|
QList<QString> commands = getAnalysisCommands(options);
|
||||||
ui->aar_references->setChecked(options.analCmd.contains("aar"));
|
foreach (item, analysisCommands){
|
||||||
ui->aac_calls->setChecked(options.analCmd.contains("aac"));
|
qInfo() << item.commandDesc.command;
|
||||||
ui->aab_basicblocks->setChecked(options.analCmd.contains("aab"));
|
item.checkbox->setChecked(commands.contains(item.commandDesc.command));
|
||||||
ui->aan_rename->setChecked(options.analCmd.contains("aan"));
|
}
|
||||||
ui->aae_emulate->setChecked(options.analCmd.contains("aae"));
|
|
||||||
ui->aat_consecutive->setChecked(options.analCmd.contains("aat"));
|
|
||||||
ui->afta_typeargument->setChecked(options.analCmd.contains("afta"));
|
|
||||||
ui->aaT_aftertrap->setChecked(options.analCmd.contains("aaT"));
|
|
||||||
ui->aap_preludes->setChecked(options.analCmd.contains("aap"));
|
|
||||||
ui->jmptbl->setChecked(options.analCmd.contains("e! anal.jmptbl"));
|
|
||||||
ui->pushret->setChecked(options.analCmd.contains("e! anal.pushret"));
|
|
||||||
ui->hasnext->setChecked(options.analCmd.contains("e! anal.hasnext"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.script.isEmpty()) {
|
if (!options.script.isEmpty()) {
|
||||||
@ -171,55 +199,15 @@ QString InitialOptionsDialog::getSelectedOS() const
|
|||||||
return os.isValid() ? os.toString() : nullptr;
|
return os.isValid() ? os.toString() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QString> InitialOptionsDialog::getSelectedAdvancedAnalCmds() const
|
QList<CommandDescription> InitialOptionsDialog::getSelectedAdvancedAnalCmds() const
|
||||||
{
|
{
|
||||||
QList<QString> advanced = QList<QString>();
|
QList<CommandDescription> advanced = QList<CommandDescription>();
|
||||||
if (ui->analSlider->value() == 3) {
|
if (ui->analSlider->value() == 3) {
|
||||||
// Enable analysis configurations before executing analysis commands
|
AnalysisCommands item;
|
||||||
if (ui->jmptbl->isChecked()) {
|
foreach (item, analysisCommands){
|
||||||
advanced << "e! anal.jmptbl";
|
if(item.checkbox->isChecked()) {
|
||||||
|
advanced << item.commandDesc;
|
||||||
}
|
}
|
||||||
if (ui->pushret->isChecked()) {
|
|
||||||
advanced << "e! anal.pushret";
|
|
||||||
}
|
|
||||||
if (ui->hasnext->isChecked()) {
|
|
||||||
advanced << "e! anal.hasnext";
|
|
||||||
}
|
|
||||||
if (ui->aa_symbols->isChecked()) {
|
|
||||||
advanced << "aa";
|
|
||||||
}
|
|
||||||
if (ui->aar_references->isChecked()) {
|
|
||||||
advanced << "aar";
|
|
||||||
}
|
|
||||||
if (ui->aac_calls->isChecked()) {
|
|
||||||
advanced << "aac";
|
|
||||||
}
|
|
||||||
if (ui->aab_basicblocks->isChecked()) {
|
|
||||||
advanced << "aab";
|
|
||||||
}
|
|
||||||
if (ui->aao_objc->isChecked()) {
|
|
||||||
advanced << "aao";
|
|
||||||
}
|
|
||||||
if (ui->avrr_vtables->isChecked()) {
|
|
||||||
advanced << "avrr";
|
|
||||||
}
|
|
||||||
if (ui->aan_rename->isChecked()) {
|
|
||||||
advanced << "aan";
|
|
||||||
}
|
|
||||||
if (ui->aae_emulate->isChecked()) {
|
|
||||||
advanced << "aae";
|
|
||||||
}
|
|
||||||
if (ui->aat_consecutive->isChecked()) {
|
|
||||||
advanced << "aat";
|
|
||||||
}
|
|
||||||
if (ui->afta_typeargument->isChecked()) {
|
|
||||||
advanced << "afta";
|
|
||||||
}
|
|
||||||
if (ui->aaT_aftertrap->isChecked()) {
|
|
||||||
advanced << "aaT";
|
|
||||||
}
|
|
||||||
if (ui->aap_preludes->isChecked()) {
|
|
||||||
advanced << "aap";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return advanced;
|
return advanced;
|
||||||
@ -269,10 +257,10 @@ void InitialOptionsDialog::setupAndStartAnalysis(/*int level, QList<QString> adv
|
|||||||
int level = ui->analSlider->value();
|
int level = ui->analSlider->value();
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case 1:
|
case 1:
|
||||||
options.analCmd = { "aaa" };
|
options.analCmd = { {"aaa", "Auto analysis"} };
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
options.analCmd = { "aaaa" };
|
options.analCmd = { {"aaaa", "Auto analysis (experimental}"} };
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
options.analCmd = getSelectedAdvancedAnalCmds();
|
options.analCmd = getSelectedAdvancedAnalCmds();
|
||||||
@ -346,8 +334,10 @@ void InitialOptionsDialog::on_analSlider_valueChanged(int value)
|
|||||||
ui->analCheckBox->setText(tr("Analysis: Enabled"));
|
ui->analCheckBox->setText(tr("Analysis: Enabled"));
|
||||||
if (value == 3) {
|
if (value == 3) {
|
||||||
ui->analoptionsFrame->setVisible(true);
|
ui->analoptionsFrame->setVisible(true);
|
||||||
|
ui->advancedAnlysisLine->setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
ui->analoptionsFrame->setVisible(false);
|
ui->analoptionsFrame->setVisible(false);
|
||||||
|
ui->advancedAnlysisLine->setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define OPTIONSDIALOG_H
|
#define OPTIONSDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QCheckBox>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/InitialOptions.h"
|
#include "common/InitialOptions.h"
|
||||||
|
|
||||||
@ -49,13 +50,20 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
void updateCPUComboBox();
|
void updateCPUComboBox();
|
||||||
|
struct AnalysisCommands {
|
||||||
|
CommandDescription commandDesc;
|
||||||
|
QCheckBox *checkbox;
|
||||||
|
bool checked;
|
||||||
|
};
|
||||||
|
QList<AnalysisCommands> analysisCommands;
|
||||||
|
|
||||||
|
QList<QString> getAnalysisCommands(const InitialOptions &options);
|
||||||
QString getSelectedArch() const;
|
QString getSelectedArch() const;
|
||||||
QString getSelectedCPU() const;
|
QString getSelectedCPU() const;
|
||||||
int getSelectedBits() const;
|
int getSelectedBits() const;
|
||||||
InitialOptions::Endianness getSelectedEndianness() const;
|
InitialOptions::Endianness getSelectedEndianness() const;
|
||||||
QString getSelectedOS() const;
|
QString getSelectedOS() const;
|
||||||
QList<QString> getSelectedAdvancedAnalCmds() const;
|
QList<CommandDescription> getSelectedAdvancedAnalCmds() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void loadOptions(const InitialOptions &options);
|
void loadOptions(const InitialOptions &options);
|
||||||
|
@ -221,8 +221,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>564</width>
|
<width>567</width>
|
||||||
<height>867</height>
|
<height>418</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
@ -269,9 +269,12 @@
|
|||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>5</number>
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinimumSize</enum>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QFrame" name="analoptionsFrame">
|
<widget class="QFrame" name="analoptionsFrame">
|
||||||
@ -300,156 +303,19 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
</layout>
|
||||||
<widget class="QCheckBox" name="aa_symbols">
|
|
||||||
<property name="text">
|
|
||||||
<string>Analyze all symbols (aa)</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="aar_references">
|
<widget class="Line" name="advancedAnlysisLine">
|
||||||
<property name="text">
|
|
||||||
<string>Analyze for references (aar)</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="aac_calls">
|
|
||||||
<property name="text">
|
|
||||||
<string>Analyze function calls (aac)</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="aab_basicblocks">
|
|
||||||
<property name="text">
|
|
||||||
<string>Analyze all basic blocks (aab)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="aan_rename">
|
|
||||||
<property name="text">
|
|
||||||
<string>Autorename functions based on context (aan)</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="aao_objc">
|
|
||||||
<property name="text">
|
|
||||||
<string> Analyze all objc references (aao)</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="avrr_vtables">
|
|
||||||
<property name="text">
|
|
||||||
<string> Recover class information (avrr)</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Experimental:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="aae_emulate">
|
|
||||||
<property name="text">
|
|
||||||
<string>Emulate code to find computed references (aae)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="aat_consecutive">
|
|
||||||
<property name="text">
|
|
||||||
<string>Analyze for consecutive function (aat)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="afta_typeargument">
|
|
||||||
<property name="text">
|
|
||||||
<string>Type and Argument matching analysis (afta)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="aaT_aftertrap">
|
|
||||||
<property name="text">
|
|
||||||
<string>Analyze code after trap-sleds (aaT)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="aap_preludes">
|
|
||||||
<property name="text">
|
|
||||||
<string>Analyze function preludes (aap)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="jmptbl">
|
|
||||||
<property name="text">
|
|
||||||
<string>Analyze jump tables in switch statements (e! anal.jmptbl)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="pushret">
|
|
||||||
<property name="text">
|
|
||||||
<string>Analyze push+ret as jmp (e! anal.pushret)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="hasnext">
|
|
||||||
<property name="text">
|
|
||||||
<string>Continue analysis after each function (e! anal.hasnext)</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line_4">
|
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="visible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="sizeConstraint">
|
|
||||||
<enum>QLayout::SetMinimumSize</enum>
|
|
||||||
</property>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="writeCheckBox">
|
<widget class="QCheckBox" name="writeCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
Loading…
Reference in New Issue
Block a user