mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-20 20:06:12 +00:00
parent
cd776c24ef
commit
b857e724e8
@ -1046,6 +1046,37 @@ QList<HeaderDescription> CutterCore::getAllHeaders()
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<ZignatureDescription> CutterCore::getAllZignatures()
|
||||
{
|
||||
CORE_LOCK();
|
||||
QList<ZignatureDescription> ret;
|
||||
|
||||
QJsonArray zignaturesArray = cmdj("zj").array();
|
||||
|
||||
for (QJsonValue value : zignaturesArray) {
|
||||
QJsonObject zignatureObject = value.toObject();
|
||||
|
||||
ZignatureDescription zignature;
|
||||
|
||||
zignature.name = zignatureObject["name"].toString();
|
||||
zignature.bytes = zignatureObject["bytes"].toString();
|
||||
zignature.offset = zignatureObject["offset"].toVariant().toULongLong();
|
||||
for (QJsonValue ref : zignatureObject["refs"].toArray()) {
|
||||
zignature.refs << ref.toString();
|
||||
}
|
||||
|
||||
QJsonObject graphObject = zignatureObject["graph"].toObject();
|
||||
zignature.cc = graphObject["cc"].toVariant().toULongLong();
|
||||
zignature.nbbs = graphObject["nbbs"].toVariant().toULongLong();
|
||||
zignature.edges = graphObject["edges"].toVariant().toULongLong();
|
||||
zignature.ebbs = graphObject["ebbs"].toVariant().toULongLong();
|
||||
|
||||
ret << zignature;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<CommentDescription> CutterCore::getAllComments(const QString &filterType)
|
||||
{
|
||||
CORE_LOCK();
|
||||
|
14
src/Cutter.h
14
src/Cutter.h
@ -116,6 +116,18 @@ struct HeaderDescription
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct ZignatureDescription
|
||||
{
|
||||
QString name;
|
||||
QString bytes;
|
||||
RVA cc;
|
||||
RVA nbbs;
|
||||
RVA edges;
|
||||
RVA ebbs;
|
||||
RVA offset;
|
||||
QStringList refs;
|
||||
};
|
||||
|
||||
struct TypeDescription {
|
||||
QString type;
|
||||
int size;
|
||||
@ -284,6 +296,7 @@ Q_DECLARE_METATYPE(ResourcesDescription)
|
||||
Q_DECLARE_METATYPE(VTableDescription)
|
||||
Q_DECLARE_METATYPE(TypeDescription)
|
||||
Q_DECLARE_METATYPE(HeaderDescription)
|
||||
Q_DECLARE_METATYPE(ZignatureDescription)
|
||||
Q_DECLARE_METATYPE(SearchDescription)
|
||||
Q_DECLARE_METATYPE(SectionDescription)
|
||||
|
||||
@ -439,6 +452,7 @@ public:
|
||||
QList<ExportDescription> getAllExports();
|
||||
QList<SymbolDescription> getAllSymbols();
|
||||
QList<HeaderDescription> getAllHeaders();
|
||||
QList<ZignatureDescription> getAllZignatures();
|
||||
QList<CommentDescription> getAllComments(const QString &filterType);
|
||||
QList<RelocDescription> getAllRelocs();
|
||||
QList<StringDescription> getAllStrings();
|
||||
|
@ -158,7 +158,8 @@ SOURCES += \
|
||||
widgets/GraphWidget.cpp \
|
||||
utils/JsonTreeItem.cpp \
|
||||
utils/JsonModel.cpp \
|
||||
dialogs/VersionInfoDialog.cpp
|
||||
dialogs/VersionInfoDialog.cpp \
|
||||
widgets/ZignaturesWidget.cpp
|
||||
|
||||
HEADERS += \
|
||||
Cutter.h \
|
||||
@ -231,7 +232,8 @@ HEADERS += \
|
||||
widgets/GraphWidget.h \
|
||||
utils/JsonTreeItem.h \
|
||||
utils/JsonModel.h \
|
||||
dialogs/VersionInfoDialog.h
|
||||
dialogs/VersionInfoDialog.h \
|
||||
widgets/ZignaturesWidget.h
|
||||
|
||||
FORMS += \
|
||||
dialogs/AboutDialog.ui \
|
||||
@ -273,7 +275,8 @@ FORMS += \
|
||||
widgets/SearchWidget.ui \
|
||||
widgets/JupyterWidget.ui \
|
||||
dialogs/R2PluginsDialog.ui \
|
||||
dialogs/VersionInfoDialog.ui
|
||||
dialogs/VersionInfoDialog.ui \
|
||||
widgets/ZignaturesWidget.ui
|
||||
|
||||
RESOURCES += \
|
||||
resources.qrc \
|
||||
|
@ -69,6 +69,7 @@
|
||||
#include "widgets/VTablesWidget.h"
|
||||
#include "widgets/JupyterWidget.h"
|
||||
#include "widgets/HeadersWidget.h"
|
||||
#include "widgets/ZignaturesWidget.h"
|
||||
|
||||
// graphics
|
||||
#include <QGraphicsEllipseItem>
|
||||
@ -169,6 +170,7 @@ void MainWindow::initUI()
|
||||
importsDock = new ImportsWidget(this, ui->actionImports);
|
||||
exportsDock = new ExportsWidget(this, ui->actionExports);
|
||||
headersDock = new HeadersWidget(this, ui->actionHeaders);
|
||||
zignaturesDock = new ZignaturesWidget(this, ui->actionZignatures);
|
||||
typesDock = new TypesWidget(this, ui->actionTypes);
|
||||
searchDock = new SearchWidget(this, ui->actionSearch);
|
||||
symbolsDock = new SymbolsWidget(this, ui->actionSymbols);
|
||||
@ -464,6 +466,7 @@ void MainWindow::restoreDocks()
|
||||
tabifyDockWidget(dashboardDock, typesDock);
|
||||
tabifyDockWidget(dashboardDock, searchDock);
|
||||
tabifyDockWidget(dashboardDock, headersDock);
|
||||
tabifyDockWidget(dashboardDock, zignaturesDock);
|
||||
tabifyDockWidget(dashboardDock, symbolsDock);
|
||||
tabifyDockWidget(dashboardDock, classesDock);
|
||||
tabifyDockWidget(dashboardDock, resourcesDock);
|
||||
|
@ -41,6 +41,7 @@ class ResourcesWidget;
|
||||
class VTablesWidget;
|
||||
class TypesWidget;
|
||||
class HeadersWidget;
|
||||
class ZignaturesWidget;
|
||||
class SearchWidget;
|
||||
#ifdef CUTTER_ENABLE_JUPYTER
|
||||
class JupyterWidget;
|
||||
@ -196,6 +197,7 @@ private:
|
||||
QLineEdit *gotoEntry = nullptr;
|
||||
SdbDock *sdbDock = nullptr;
|
||||
SectionsWidget *sectionsDock = nullptr;
|
||||
ZignaturesWidget *zignaturesDock = nullptr;
|
||||
ConsoleWidget *consoleDock = nullptr;
|
||||
ClassesWidget *classesDock = nullptr;
|
||||
ResourcesWidget *resourcesDock = nullptr;
|
||||
|
@ -251,6 +251,7 @@ border-top: 0px;
|
||||
<addaction name="actionFlags"/>
|
||||
<addaction name="actionSections"/>
|
||||
<addaction name="actionHeaders"/>
|
||||
<addaction name="actionZignatures"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionComments"/>
|
||||
<addaction name="actionConsole"/>
|
||||
@ -1073,6 +1074,17 @@ background-color: palette(dark);
|
||||
<string>Show/Hide Headers panel</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionZignatures">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Zignatures</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Show/Hide Zignatures panel</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionJupyter">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
161
src/widgets/ZignaturesWidget.cpp
Normal file
161
src/widgets/ZignaturesWidget.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
#include "ZignaturesWidget.h"
|
||||
#include "ui_ZignaturesWidget.h"
|
||||
#include "MainWindow.h"
|
||||
#include "utils/Helpers.h"
|
||||
|
||||
ZignaturesModel::ZignaturesModel(QList<ZignatureDescription> *zignatures, QObject *parent)
|
||||
: QAbstractListModel(parent),
|
||||
zignatures(zignatures)
|
||||
{
|
||||
}
|
||||
|
||||
int ZignaturesModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return zignatures->count();
|
||||
}
|
||||
|
||||
int ZignaturesModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
return ZignaturesModel::ColumnCount;
|
||||
}
|
||||
|
||||
QVariant ZignaturesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.row() >= zignatures->count())
|
||||
return QVariant();
|
||||
|
||||
const ZignatureDescription &zignature = zignatures->at(index.row());
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (index.column()) {
|
||||
case OffsetColumn:
|
||||
return RAddressString(zignature.offset);
|
||||
case NameColumn:
|
||||
return zignature.name;
|
||||
case ValueColumn:
|
||||
return zignature.bytes;
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
case ZignatureDescriptionRole:
|
||||
return QVariant::fromValue(zignature);
|
||||
|
||||
case Qt::ToolTipRole: {
|
||||
QString tmp = QString("Graph:\n\n Cyclomatic complexity: " + RSizeString(zignature.cc) +
|
||||
"\n Nodes / basicblocks: " + RSizeString(zignature.nbbs) +
|
||||
"\n Edges: " + RSizeString(zignature.edges) +
|
||||
"\n Ebbs: " + RSizeString(zignature.ebbs) +
|
||||
"\n\nRefs:\n");
|
||||
for (QString ref : zignature.refs) {
|
||||
tmp.append("\n " + ref);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant ZignaturesModel::headerData(int section, Qt::Orientation, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
switch (section) {
|
||||
case OffsetColumn:
|
||||
return tr("Offset");
|
||||
case NameColumn:
|
||||
return tr("Name");
|
||||
case ValueColumn:
|
||||
return tr("Bytes");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
void ZignaturesModel::beginReloadZignatures()
|
||||
{
|
||||
beginResetModel();
|
||||
}
|
||||
|
||||
void ZignaturesModel::endReloadZignatures()
|
||||
{
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
ZignaturesProxyModel::ZignaturesProxyModel(ZignaturesModel *sourceModel, QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
bool ZignaturesProxyModel::filterAcceptsRow(int row, const QModelIndex &parent) const
|
||||
{
|
||||
QModelIndex index = sourceModel()->index(row, 0, parent);
|
||||
ZignatureDescription item = index.data(ZignaturesModel::ZignatureDescriptionRole).value<ZignatureDescription>();
|
||||
return item.name.contains(filterRegExp());
|
||||
}
|
||||
|
||||
bool ZignaturesProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
ZignatureDescription leftZignature = left.data(ZignaturesModel::ZignatureDescriptionRole).value<ZignatureDescription>();
|
||||
ZignatureDescription rightZignature = right.data(ZignaturesModel::ZignatureDescriptionRole).value<ZignatureDescription>();
|
||||
|
||||
switch (left.column()) {
|
||||
case ZignaturesModel::OffsetColumn:
|
||||
return leftZignature.offset < rightZignature.offset;
|
||||
case ZignaturesModel::NameColumn:
|
||||
return leftZignature.name < rightZignature.name;
|
||||
case ZignaturesModel::ValueColumn:
|
||||
return leftZignature.bytes < rightZignature.bytes;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return leftZignature.offset < rightZignature.offset;
|
||||
}
|
||||
|
||||
ZignaturesWidget::ZignaturesWidget(MainWindow *main, QAction *action) :
|
||||
CutterDockWidget(main, action),
|
||||
ui(new Ui::ZignaturesWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
zignaturesModel = new ZignaturesModel(&zignatures, this);
|
||||
zignaturesProxyModel = new ZignaturesProxyModel(zignaturesModel, this);
|
||||
ui->zignaturesTreeView->setModel(zignaturesProxyModel);
|
||||
ui->zignaturesTreeView->sortByColumn(ZignaturesModel::OffsetColumn, Qt::AscendingOrder);
|
||||
|
||||
setScrollMode();
|
||||
|
||||
connect(Core(), &CutterCore::refreshAll, this, &ZignaturesWidget::refreshZignatures);
|
||||
}
|
||||
|
||||
ZignaturesWidget::~ZignaturesWidget() {}
|
||||
|
||||
void ZignaturesWidget::refreshZignatures()
|
||||
{
|
||||
zignaturesModel->beginReloadZignatures();
|
||||
zignatures = Core()->getAllZignatures();
|
||||
zignaturesModel->endReloadZignatures();
|
||||
|
||||
ui->zignaturesTreeView->resizeColumnToContents(0);
|
||||
ui->zignaturesTreeView->resizeColumnToContents(1);
|
||||
ui->zignaturesTreeView->resizeColumnToContents(2);
|
||||
}
|
||||
|
||||
void ZignaturesWidget::setScrollMode()
|
||||
{
|
||||
qhelpers::setVerticalScrollMode(ui->zignaturesTreeView);
|
||||
}
|
||||
|
||||
void ZignaturesWidget::on_zignaturesTreeView_doubleClicked(const QModelIndex &index)
|
||||
{
|
||||
ZignatureDescription item = index.data(ZignaturesModel::ZignatureDescriptionRole).value<ZignatureDescription>();
|
||||
Core()->seek(item.offset);
|
||||
}
|
83
src/widgets/ZignaturesWidget.h
Normal file
83
src/widgets/ZignaturesWidget.h
Normal file
@ -0,0 +1,83 @@
|
||||
#ifndef ZIGNATURESWIDGET_H
|
||||
#define ZIGNATURESWIDGET_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Cutter.h"
|
||||
#include "CutterDockWidget.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class MainWindow;
|
||||
class QTreeWidget;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ZignaturesWidget;
|
||||
}
|
||||
|
||||
class ZignaturesModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Column { OffsetColumn = 0, NameColumn, ValueColumn, ColumnCount };
|
||||
enum Role { ZignatureDescriptionRole = Qt::UserRole };
|
||||
|
||||
ZignaturesModel(QList<ZignatureDescription> *zignatures, QObject *parent = 0);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
|
||||
void beginReloadZignatures();
|
||||
void endReloadZignatures();
|
||||
|
||||
private:
|
||||
QList<ZignatureDescription> *zignatures;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ZignaturesProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ZignaturesProxyModel(ZignaturesModel *sourceModel, QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int row, const QModelIndex &parent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ZignaturesWidget : public CutterDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ZignaturesWidget(MainWindow *main, QAction *action = nullptr);
|
||||
~ZignaturesWidget();
|
||||
|
||||
private slots:
|
||||
void on_zignaturesTreeView_doubleClicked(const QModelIndex &index);
|
||||
|
||||
void refreshZignatures();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Ui::ZignaturesWidget> ui;
|
||||
|
||||
ZignaturesModel *zignaturesModel;
|
||||
ZignaturesProxyModel *zignaturesProxyModel;
|
||||
QList<ZignatureDescription> zignatures;
|
||||
|
||||
void setScrollMode();
|
||||
};
|
||||
|
||||
#endif // ZIGNATURESWIDGET_H
|
70
src/widgets/ZignaturesWidget.ui
Normal file
70
src/widgets/ZignaturesWidget.ui
Normal file
@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ZignaturesWidget</class>
|
||||
<widget class="QDockWidget" name="ZignaturesWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Zignatures</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeView" name="zignaturesTreeView">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QTreeView::item
|
||||
{
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="autoScroll">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Reference in New Issue
Block a user