Add a button "Version Information" in Dashboard (iVj) #317 (#468)

This commit is contained in:
rrreeezzz 2018-05-01 19:53:14 +01:00 committed by xarkes
parent e97c22f214
commit f5f2c4702e
9 changed files with 405 additions and 14 deletions

View File

@ -704,6 +704,11 @@ QJsonDocument CutterCore::getFileInfo()
return cmdj("ij"); return cmdj("ij");
} }
QJsonDocument CutterCore::getFileVersionInfo()
{
return cmdj("iVj");
}
QStringList CutterCore::getStats() QStringList CutterCore::getStats()
{ {
QStringList stats; QStringList stats;

View File

@ -70,6 +70,11 @@ inline QString RSizeString(RVA size)
return QString::asprintf("%lld", size); return QString::asprintf("%lld", size);
} }
inline QString RHexString(RVA size)
{
return QString::asprintf("%#llx", size);
}
struct FunctionDescription { struct FunctionDescription {
RVA offset; RVA offset;
RVA size; RVA size;
@ -390,6 +395,7 @@ public:
QString getDecompiledCode(RVA addr); QString getDecompiledCode(RVA addr);
QString getDecompiledCode(QString addr); QString getDecompiledCode(QString addr);
QJsonDocument getFileInfo(); QJsonDocument getFileInfo();
QJsonDocument getFileVersionInfo();
QStringList getStats(); QStringList getStats();
QString getSimpleGraph(QString function); QString getSimpleGraph(QString function);

View File

@ -156,7 +156,8 @@ SOURCES += \
widgets/CutterDockWidget.cpp \ widgets/CutterDockWidget.cpp \
widgets/GraphWidget.cpp \ widgets/GraphWidget.cpp \
utils/JsonTreeItem.cpp \ utils/JsonTreeItem.cpp \
utils/JsonModel.cpp utils/JsonModel.cpp \
dialogs/VersionInfoDialog.cpp
HEADERS += \ HEADERS += \
Cutter.h \ Cutter.h \
@ -227,7 +228,8 @@ HEADERS += \
widgets/CutterDockWidget.h \ widgets/CutterDockWidget.h \
widgets/GraphWidget.h \ widgets/GraphWidget.h \
utils/JsonTreeItem.h \ utils/JsonTreeItem.h \
utils/JsonModel.h utils/JsonModel.h \
dialogs/VersionInfoDialog.h
FORMS += \ FORMS += \
dialogs/AboutDialog.ui \ dialogs/AboutDialog.ui \
@ -267,7 +269,8 @@ FORMS += \
widgets/TypesWidget.ui \ widgets/TypesWidget.ui \
widgets/SearchWidget.ui \ widgets/SearchWidget.ui \
widgets/JupyterWidget.ui \ widgets/JupyterWidget.ui \
dialogs/R2PluginsDialog.ui dialogs/R2PluginsDialog.ui \
dialogs/VersionInfoDialog.ui
RESOURCES += \ RESOURCES += \
resources.qrc \ resources.qrc \

View File

@ -0,0 +1,170 @@
#include "VersionInfoDialog.h"
#include "ui_VersionInfoDialog.h"
#include "utils/Helpers.h"
#include <QJsonArray>
#include <QStringList>
#include <QJsonObject>
#include <QJsonDocument>
#include <QTreeWidget>
VersionInfoDialog::VersionInfoDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::VersionInfoDialog),
core(Core())
{
ui->setupUi(this);
setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
// Get version information
fillVersionInfo();
}
VersionInfoDialog::~VersionInfoDialog() {}
void VersionInfoDialog::fillVersionInfo(){
QJsonDocument doc = Core()->getFileVersionInfo();
// Case ELF
if (doc.object().contains("verneed")) {
QJsonObject verneed = doc.object()["verneed"].toArray().first().toObject();
QJsonObject versym = doc.object()["versym"].toArray().first().toObject();
// Set labels
ui->leftLabel->setText("Version symbols");
ui->rightLabel->setText("Version need");
//Left tree
QTreeWidgetItem *secNameItemL = new QTreeWidgetItem();
secNameItemL->setText(0, "Section name:");
secNameItemL->setText(1, versym["section_name"].toString());
ui->leftTreeWidget->addTopLevelItem(secNameItemL);
QTreeWidgetItem *addrItemL = new QTreeWidgetItem();
addrItemL->setText(0, "Address:");
addrItemL->setText(1, RAddressString(versym["address"].toDouble()));
ui->leftTreeWidget->addTopLevelItem(addrItemL);
QTreeWidgetItem *offItemL = new QTreeWidgetItem();
offItemL->setText(0, "Offset:");
offItemL->setText(1, RAddressString(versym["offset"].toDouble()));
ui->leftTreeWidget->addTopLevelItem(offItemL);
QTreeWidgetItem *linkItemL = new QTreeWidgetItem();
linkItemL->setText(0, "Link:");
linkItemL->setText(1, QString::number(versym["link"].toDouble()));
ui->leftTreeWidget->addTopLevelItem(linkItemL);
QTreeWidgetItem *linkNameItemL = new QTreeWidgetItem();
linkNameItemL->setText(0, "Link section name:");
linkNameItemL->setText(1, versym["link_section_name"].toString());
ui->leftTreeWidget->addTopLevelItem(linkNameItemL);
QTreeWidgetItem *entriesItemL = new QTreeWidgetItem();
entriesItemL->setText(0, "Entries:");
foreach (QJsonValue val, versym["entries"].toArray()) {
QJsonObject obj = val.toObject();
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, RAddressString(obj["idx"].toDouble()));
tempItem->setText(1, obj["value"].toString());
entriesItemL->addChild(tempItem);
}
ui->leftTreeWidget->addTopLevelItem(entriesItemL);
// Adjust columns to content
qhelpers::adjustColumns(ui->leftTreeWidget, 0);
// Right tree
QTreeWidgetItem *secNameItemR = new QTreeWidgetItem();
secNameItemR->setText(0, "Section name:");
secNameItemR->setText(1, verneed["section_name"].toString());
ui->rightTreeWidget->addTopLevelItem(secNameItemR);
QTreeWidgetItem *addrItemR = new QTreeWidgetItem();
addrItemR->setText(0, "Address:");
addrItemR->setText(1, RAddressString(verneed["address"].toDouble()));
ui->rightTreeWidget->addTopLevelItem(addrItemR);
QTreeWidgetItem *offItemR = new QTreeWidgetItem();
offItemR->setText(0, "Offset:");
offItemR->setText(1, RAddressString(verneed["offset"].toDouble()));
ui->rightTreeWidget->addTopLevelItem(offItemR);
QTreeWidgetItem *linkItemR = new QTreeWidgetItem();
linkItemR->setText(0, "Link:");
linkItemR->setText(1, QString::number(verneed["link"].toDouble()));
ui->rightTreeWidget->addTopLevelItem(linkItemR);
QTreeWidgetItem *linkNameItemR = new QTreeWidgetItem();
linkNameItemR->setText(0, "Link section name:");
linkNameItemR->setText(1, verneed["link_section_name"].toString());
ui->rightTreeWidget->addTopLevelItem(linkNameItemR);
QTreeWidgetItem *entriesItemR = new QTreeWidgetItem();
entriesItemR->setText(0, "Entries:");
foreach (QJsonValue parentVal, verneed["entries"].toArray()) {
QJsonObject parentObj = parentVal.toObject();
QTreeWidgetItem *parentItem = new QTreeWidgetItem();
QString parentString;
parentItem->setText(0, RAddressString(parentObj["idx"].toDouble()));
parentString.append("Version: " + QString::number(parentObj["vn_version"].toDouble()) + "\t");
parentString.append("File: " + parentObj["file_name"].toString());
parentItem->setText(1, parentString);
foreach (QJsonValue childVal, parentObj["vernaux"].toArray()) {
QJsonObject childObj = childVal.toObject();
QTreeWidgetItem *childItem = new QTreeWidgetItem();
QString childString;
childItem->setText(0, RAddressString(childObj["idx"].toDouble()));
childString.append("Name: " + childObj["name"].toString() + "\t");
childString.append("Flags: " + childObj["flags"].toString() + "\t");
childString.append("Version: " + QString::number(childObj["version"].toDouble()));
childItem->setText(1, childString);
parentItem->addChild(childItem);
}
entriesItemR->addChild(parentItem);
}
ui->rightTreeWidget->addTopLevelItem(entriesItemR);
// Adjust columns to content
qhelpers::adjustColumns(ui->rightTreeWidget, 0);
}
// Case PE
else if (doc.object().contains("VS_FIXEDFILEINFO")) {
QJsonObject vs = doc.object()["VS_FIXEDFILEINFO"].toObject();
QJsonObject strings = doc.object()["StringTable"].toObject();
// Set labels
ui->leftLabel->setText("VS Fixed file info");
ui->rightLabel->setText("String table");
// Left tree
foreach (QString key, vs.keys()){
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, key);
if (vs[key].isDouble())
tempItem->setText(1, RHexString(vs[key].toDouble()));
else
tempItem->setText(1, vs[key].toString());
ui->leftTreeWidget->addTopLevelItem(tempItem);
// Adjust columns to content
qhelpers::adjustColumns(ui->leftTreeWidget, 0);
}
// Right tree
foreach (QString key, strings.keys()){
QTreeWidgetItem *tempItem = new QTreeWidgetItem();
tempItem->setText(0, key);
tempItem->setText(1, strings[key].toString());
ui->rightTreeWidget->addTopLevelItem(tempItem);
// Adjust columns to content
qhelpers::adjustColumns(ui->rightTreeWidget, 0);
}
}
}

View File

@ -0,0 +1,29 @@
#ifndef VERSIONINFODIALOG_H
#define VERSIONINFODIALOG_H
#include <QDialog>
#include <memory>
#include "Cutter.h"
namespace Ui {
class VersionInfoDialog;
}
class VersionInfoDialog : public QDialog
{
Q_OBJECT
public:
explicit VersionInfoDialog(QWidget *parent = 0);
~VersionInfoDialog();
private:
std::unique_ptr<Ui::VersionInfoDialog> ui;
CutterCore *core;
void fillVersionInfo();
};
#endif // VERSIONINFODIALOG_H

View File

@ -0,0 +1,142 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VersionInfoDialog</class>
<widget class="QDialog" name="VersionInfoDialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1127</width>
<height>390</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">Version Info</string>
</property>
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="leftLabel">
<property name="font">
<font>
<pointsize>17</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rightLabel">
<property name="font">
<font>
<pointsize>17</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTreeWidget" name="leftTreeWidget">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="autoExpandDelay">
<number>-1</number>
</property>
<property name="indentation">
<number>20</number>
</property>
<attribute name="headerDefaultSectionSize">
<number>200</number>
</attribute>
<column>
<property name="text">
<string>Key</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QTreeWidget" name="rightTreeWidget">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="autoExpandDelay">
<number>-1</number>
</property>
<property name="indentation">
<number>20</number>
</property>
<attribute name="headerDefaultSectionSize">
<number>200</number>
</attribute>
<column>
<property name="text">
<string>Key</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -3,6 +3,7 @@
#include "utils/Helpers.h" #include "utils/Helpers.h"
#include "utils/JsonModel.h" #include "utils/JsonModel.h"
#include "utils/JsonTreeItem.h" #include "utils/JsonTreeItem.h"
#include "dialogs/VersionInfoDialog.h"
#include "MainWindow.h" #include "MainWindow.h"
@ -187,3 +188,17 @@ void Dashboard::on_certificateButton_clicked()
msgBoxCertificateInf.exec(); msgBoxCertificateInf.exec();
} }
} }
void Dashboard::on_versioninfoButton_clicked()
{
static QDialog *infoDialog = nullptr;
if (!infoDialog){
infoDialog = new VersionInfoDialog(this);
}
if (!infoDialog->isVisible()) {
infoDialog->show();
}
}

View File

@ -21,6 +21,7 @@ public:
private slots: private slots:
void updateContents(); void updateContents();
void on_certificateButton_clicked(); void on_certificateButton_clicked();
void on_versioninfoButton_clicked();
private: private:
std::unique_ptr<Ui::Dashboard> ui; std::unique_ptr<Ui::Dashboard> ui;

View File

@ -866,19 +866,39 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item> <item>
<widget class="QPushButton" name="certificateButton"> <widget class="QPushButton" name="certificateButton">
<property name="maximumSize"> <property name="enabled">
<size> <bool>true</bool>
<width>100</width> </property>
<height>167</height> <property name="sizePolicy">
</size> <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>Certificates</string> <string>Certificates</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="versioninfoButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Version info</string>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<widget class="Line" name="line_2"> <widget class="Line" name="line_2">
<property name="orientation"> <property name="orientation">