mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-18 18:38:51 +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 = {};
|
||||
break;
|
||||
case 1:
|
||||
options.analCmd = { "aaa" };
|
||||
options.analCmd = { {"aaa", "Auto analysis"} };
|
||||
break;
|
||||
case 2:
|
||||
options.analCmd = { "aaaa" };
|
||||
options.analCmd = { {"aaaa", "Auto analysis (experimental)"} };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -96,13 +96,13 @@ void AnalTask::runTask()
|
||||
Core()->setConfig("prj.simple", true);
|
||||
|
||||
if (!options.analCmd.empty()) {
|
||||
log(tr("Analyzing..."));
|
||||
for (const QString &cmd : options.analCmd) {
|
||||
log(tr("Executing analysis..."));
|
||||
for (const CommandDescription &cmd : options.analCmd) {
|
||||
if (isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
log(" " + tr("Running") + " " + cmd);
|
||||
Core()->cmd(cmd);
|
||||
log(cmd.description);
|
||||
Core()->cmd(cmd.command);
|
||||
}
|
||||
log(tr("Analysis complete!"));
|
||||
} else {
|
||||
|
@ -4,6 +4,14 @@
|
||||
|
||||
#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
|
||||
{
|
||||
enum class Endianness { Auto, Little, Big };
|
||||
@ -29,8 +37,8 @@ struct InitialOptions
|
||||
|
||||
QString pdbFile;
|
||||
QString script;
|
||||
|
||||
QList<QString> analCmd = { "aaa" };
|
||||
|
||||
QList<CommandDescription> analCmd = { {"aaa", "Auto analysis"} };
|
||||
|
||||
QString shellcode;
|
||||
};
|
||||
|
@ -50,8 +50,36 @@ InitialOptionsDialog::InitialOptionsDialog(MainWindow *main):
|
||||
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->analoptionsFrame->setVisible(false);
|
||||
ui->advancedAnlysisLine->setVisible(false);
|
||||
|
||||
updatePDBLayout();
|
||||
|
||||
@ -86,30 +114,30 @@ void InitialOptionsDialog::updateCPUComboBox()
|
||||
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)
|
||||
{
|
||||
if (options.analCmd.isEmpty()) {
|
||||
analLevel = 0;
|
||||
} else if (options.analCmd == QList<QString>({ "aaa" })) {
|
||||
} else if (options.analCmd.first().command == "aaa" ) {
|
||||
analLevel = 1;
|
||||
} else if (options.analCmd == QList<QString>({ "aaaa" })) {
|
||||
} else if (options.analCmd.first().command == "aaaa" ) {
|
||||
analLevel = 2;
|
||||
} else {
|
||||
analLevel = 3;
|
||||
// TODO: These checks must always be in sync with getSelectedAdvancedAnalCmds(), which is dangerous
|
||||
ui->aa_symbols->setChecked(options.analCmd.contains("aa"));
|
||||
ui->aar_references->setChecked(options.analCmd.contains("aar"));
|
||||
ui->aac_calls->setChecked(options.analCmd.contains("aac"));
|
||||
ui->aab_basicblocks->setChecked(options.analCmd.contains("aab"));
|
||||
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"));
|
||||
AnalysisCommands item;
|
||||
QList<QString> commands = getAnalysisCommands(options);
|
||||
foreach (item, analysisCommands){
|
||||
qInfo() << item.commandDesc.command;
|
||||
item.checkbox->setChecked(commands.contains(item.commandDesc.command));
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.script.isEmpty()) {
|
||||
@ -171,55 +199,15 @@ QString InitialOptionsDialog::getSelectedOS() const
|
||||
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) {
|
||||
// Enable analysis configurations before executing analysis commands
|
||||
if (ui->jmptbl->isChecked()) {
|
||||
advanced << "e! anal.jmptbl";
|
||||
}
|
||||
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";
|
||||
AnalysisCommands item;
|
||||
foreach (item, analysisCommands){
|
||||
if(item.checkbox->isChecked()) {
|
||||
advanced << item.commandDesc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return advanced;
|
||||
@ -269,10 +257,10 @@ void InitialOptionsDialog::setupAndStartAnalysis(/*int level, QList<QString> adv
|
||||
int level = ui->analSlider->value();
|
||||
switch (level) {
|
||||
case 1:
|
||||
options.analCmd = { "aaa" };
|
||||
options.analCmd = { {"aaa", "Auto analysis"} };
|
||||
break;
|
||||
case 2:
|
||||
options.analCmd = { "aaaa" };
|
||||
options.analCmd = { {"aaaa", "Auto analysis (experimental}"} };
|
||||
break;
|
||||
case 3:
|
||||
options.analCmd = getSelectedAdvancedAnalCmds();
|
||||
@ -346,8 +334,10 @@ void InitialOptionsDialog::on_analSlider_valueChanged(int value)
|
||||
ui->analCheckBox->setText(tr("Analysis: Enabled"));
|
||||
if (value == 3) {
|
||||
ui->analoptionsFrame->setVisible(true);
|
||||
ui->advancedAnlysisLine->setVisible(true);
|
||||
} else {
|
||||
ui->analoptionsFrame->setVisible(false);
|
||||
ui->advancedAnlysisLine->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define OPTIONSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QCheckBox>
|
||||
#include <memory>
|
||||
#include "common/InitialOptions.h"
|
||||
|
||||
@ -49,13 +50,20 @@ private:
|
||||
|
||||
|
||||
void updateCPUComboBox();
|
||||
struct AnalysisCommands {
|
||||
CommandDescription commandDesc;
|
||||
QCheckBox *checkbox;
|
||||
bool checked;
|
||||
};
|
||||
QList<AnalysisCommands> analysisCommands;
|
||||
|
||||
QList<QString> getAnalysisCommands(const InitialOptions &options);
|
||||
QString getSelectedArch() const;
|
||||
QString getSelectedCPU() const;
|
||||
int getSelectedBits() const;
|
||||
InitialOptions::Endianness getSelectedEndianness() const;
|
||||
QString getSelectedOS() const;
|
||||
QList<QString> getSelectedAdvancedAnalCmds() const;
|
||||
QList<CommandDescription> getSelectedAdvancedAnalCmds() const;
|
||||
|
||||
public:
|
||||
void loadOptions(const InitialOptions &options);
|
||||
|
@ -221,8 +221,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>564</width>
|
||||
<height>867</height>
|
||||
<width>567</width>
|
||||
<height>418</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
@ -269,9 +269,12 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="analoptionsFrame">
|
||||
@ -300,156 +303,19 @@
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="aa_symbols">
|
||||
<property name="text">
|
||||
<string>Analyze all symbols (aa)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="aar_references">
|
||||
<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">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
<widget class="Line" name="advancedAnlysisLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="writeCheckBox">
|
||||
<property name="text">
|
||||
|
Loading…
Reference in New Issue
Block a user