Page MenuHomePhabricator

No OneTemporary

Size
67 KB
Referenced Files
None
Subscribers
None
diff --git a/trunk/argparser.cpp b/trunk/argparser.cpp
index c1d8c13..2824047 100644
--- a/trunk/argparser.cpp
+++ b/trunk/argparser.cpp
@@ -1,127 +1,133 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "argparser.h"
ArgParser::ArgParser(QStringList args) {
this->argv=QStringList(args);
this->argc=this->argv.count();
this->error_msg="";
this->parsed_args.clear();
}
QString ArgParser::GetErrorMsg() {
QString msg=this->error_msg;
this->error_msg="";
return msg;
}
bool ArgParser::ParseArgs() {
int i=0;
int sep_pos=0;
QString cur_arg="";
QString cur_arg_param="";
while(i+1<this->argc) {
// Get current argument
cur_arg=this->argv.at(++i);
if(cur_arg.size()>1) {
// Check for short mode command line args
if(cur_arg[0]=='-' && cur_arg[1]!='-') {
if(cur_arg=="-?" || cur_arg=="-h") {
this->parsed_args.insert(cur_arg.mid(1),QString());
continue;
} else if(cur_arg=="-v") {
this->parsed_args.insert(cur_arg.mid(1),QString());
continue;
} else {
// Unknown argument
this->SetError(QString("Unknown command line argument '%1'!")
.arg(cur_arg));
return false;
}
}
// Check for long mode command line args
if(cur_arg[0]=='-' && cur_arg[1]=='-') {
// Extract argument parameter if there is one
sep_pos=cur_arg.indexOf('=');
if(sep_pos!=-1) {
cur_arg_param=cur_arg.mid(sep_pos+1);
// Remove parameter from arg
cur_arg=cur_arg.left(sep_pos);
} else {
cur_arg_param="";
}
if(cur_arg=="--") {
// Stop processing arguments. Anything that follows this argument is
// considered to be a hive to open
i++;
break;
+ } else if(cur_arg=="--dump-report") {
+ this->parsed_args.insert(cur_arg.mid(2),cur_arg_param);
+ continue;
+ } else if(cur_arg=="--fullscreen") {
+ this->parsed_args.insert(cur_arg.mid(2),cur_arg_param);
+ continue;
} else if(cur_arg=="--help") {
this->parsed_args.insert(cur_arg.mid(2),QString());
continue;
+ } else if(cur_arg=="--maximized") {
+ this->parsed_args.insert(cur_arg.mid(2),cur_arg_param);
+ continue;
} else if(cur_arg=="--version") {
this->parsed_args.insert(cur_arg.mid(2),QString());
continue;
- } else if(cur_arg=="--dump-report") {
- this->parsed_args.insert(cur_arg.mid(2),cur_arg_param);
- continue;
} else {
// Unknown argument
this->SetError(QString("Unknown command line argument '%1'!")
.arg(cur_arg));
return false;
}
}
}
// Found argument not beginning with '-' or '--'
if(i+1==this->argc) {
// If this is the last argument, it should be a hive file
this->parsed_args.insert(QString("hive-file"),cur_arg);
break;
} else {
// If it isn't the last argument, there is an error
this->SetError(QString("Unknown command line argument '%1'!")
.arg(cur_arg));
return false;
}
}
return true;
}
bool ArgParser::IsSet(QString arg) {
return this->parsed_args.contains(arg);
}
QString ArgParser::GetArgVal(QString arg) {
// If arg is not in parsed_args, the following will return a
// "default-constructed value" which should be a QString() according to the
// docs.
return this->parsed_args[arg];
}
void ArgParser::SetError(QString msg) {
this->error_msg=msg;
}
diff --git a/trunk/datainterpreterwidget.cpp b/trunk/datainterpreterwidget.cpp
index f71c7fa..3f80882 100644
--- a/trunk/datainterpreterwidget.cpp
+++ b/trunk/datainterpreterwidget.cpp
@@ -1,202 +1,201 @@
/*******************************************************************************
-* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "datainterpreterwidget.h"
#include "registryhive.h"
DataInterpreterWidget::DataInterpreterWidget(QWidget *p_parent) :
QWidget(p_parent)
{
// Init private vars
this->data=QByteArray();
this->endianness=DataInterpreterWidget::Endianness_LittleEndian;
// Set widget layout. Setting it's parent to "this" will also call
// this->SetLayout.
this->p_widget_layout=new QVBoxLayout(this);
// Create sub-widgets
this->p_data_interpreter_table=new DataInterpreterTable();
this->p_endianness_selector_layout=new QHBoxLayout();
this->p_endianness_selector_le=new QRadioButton(tr("Little endian"));
this->p_endianness_selector_be=new QRadioButton(tr("Big endian"));
// Add endianness selector buttons to their layout
this->p_endianness_selector_layout->addWidget(this->p_endianness_selector_le);
this->p_endianness_selector_layout->addWidget(this->p_endianness_selector_be);
// Add sub-widgets to our layout
this->p_widget_layout->addWidget(this->p_data_interpreter_table);
this->p_widget_layout->addLayout(this->p_endianness_selector_layout);
// Configure widget and sub-widgets
this->setContentsMargins(0,0,0,0);
this->p_widget_layout->setContentsMargins(0,0,0,0);
this->p_endianness_selector_layout->setContentsMargins(0,0,0,0);
this->p_endianness_selector_le->setContentsMargins(0,0,0,0);
this->p_endianness_selector_be->setContentsMargins(0,0,0,0);
- this->setEnabled(false);
// Set initial endianness selector state
this->p_endianness_selector_le->setChecked(
(this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_endianness_selector_be->setChecked(
(this->endianness==DataInterpreterWidget::Endianness_BigEndian));
// Connect signals
this->connect(this->p_endianness_selector_le,
SIGNAL(clicked(bool)),
this,
SLOT(SlotEndiannessSelectorLeClicked(bool)));
this->connect(this->p_endianness_selector_be,
SIGNAL(clicked(bool)),
this,
SLOT(SlotEndiannessSelectorBeClicked(bool)));
}
DataInterpreterWidget::~DataInterpreterWidget() {
delete this->p_endianness_selector_le;
delete this->p_endianness_selector_be;
delete this->p_endianness_selector_layout;
delete this->p_data_interpreter_table;
delete this->p_widget_layout;
}
void DataInterpreterWidget::SetData(QByteArray new_data) {
// Save new data and interpret it
this->data=new_data;
this->InterpretData();
}
void DataInterpreterWidget::InterpretData() {
// Get data length
int data_length=this->data.size();
// Remove old values from data interpreter table
this->p_data_interpreter_table->ClearValues();
if(data_length>=1) {
this->p_data_interpreter_table->AddValue("int8:",
RegistryHive::KeyValueToString(
this->data,
"int8"));
this->p_data_interpreter_table->AddValue("uint8:",
RegistryHive::KeyValueToString(
this->data,
"uint8"));
}
if(data_length>=2) {
this->p_data_interpreter_table->AddValue(
"int16:",
RegistryHive::KeyValueToString(
this->data,
"int16",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_data_interpreter_table->AddValue(
"uint16:",
RegistryHive::KeyValueToString(
this->data,
"uint16",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
}
if(data_length>=4) {
this->p_data_interpreter_table->AddValue(
"int32:",
RegistryHive::KeyValueToString(
this->data,
"int32",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_data_interpreter_table->AddValue(
"uint32:",
RegistryHive::KeyValueToString(
this->data,
"uint32",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_data_interpreter_table->AddValue(
"unixtime:",
RegistryHive::KeyValueToString(
this->data,
"unixtime",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
}
if(data_length>=8) {
this->p_data_interpreter_table->AddValue(
"int64:",
RegistryHive::KeyValueToString(
this->data,
"int64",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
this->p_data_interpreter_table->AddValue(
"uint64:",
RegistryHive::KeyValueToString(
this->data,
"uint64",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
/*
TODO: Check how one could implement this
this->p_data_interpreter_table->AddValue(
"unixtime64:",
RegistryHive::KeyValueToString(
this->data,
"unixtime64",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
*/
this->p_data_interpreter_table->AddValue(
"filetime64:",
RegistryHive::KeyValueToString(
this->data,
"filetime",
0,
0,
this->endianness==DataInterpreterWidget::Endianness_LittleEndian));
}
}
void DataInterpreterWidget::SlotEndiannessSelectorLeClicked(bool checked) {
if(checked) {
// Save selected endianness and update interpreted values
this->endianness=DataInterpreterWidget::Endianness_LittleEndian;
this->InterpretData();
}
}
void DataInterpreterWidget::SlotEndiannessSelectorBeClicked(bool checked) {
if(checked) {
// Save selected endianness and update interpreted values
this->endianness=DataInterpreterWidget::Endianness_BigEndian;
this->InterpretData();
}
}
diff --git a/trunk/datainterpreterwidget.h b/trunk/datainterpreterwidget.h
index 2eeace2..08e4e52 100644
--- a/trunk/datainterpreterwidget.h
+++ b/trunk/datainterpreterwidget.h
@@ -1,72 +1,72 @@
/*******************************************************************************
-* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef DATAINTERPRETERWIDGET_H
#define DATAINTERPRETERWIDGET_H
#include <QWidget>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QRadioButton>
#include <QString>
#include <QByteArray>
#include "datainterpretertable.h"
class DataInterpreterWidget : public QWidget {
Q_OBJECT
public:
enum Endianness {
Endianness_LittleEndian=0,
Endianness_BigEndian
};
explicit DataInterpreterWidget(QWidget *p_parent=0);
~DataInterpreterWidget();
/*
* SetData
*
* Set data to be interpreted (will also interpret it).
*/
void SetData(QByteArray new_data);
private:
// Widget layout
QVBoxLayout *p_widget_layout;
// Sub-widgets
DataInterpreterTable *p_data_interpreter_table;
QHBoxLayout *p_endianness_selector_layout;
QRadioButton *p_endianness_selector_le;
QRadioButton *p_endianness_selector_be;
// Vars
QByteArray data;
int endianness;
void InterpretData();
private slots:
void SlotEndiannessSelectorLeClicked(bool checked);
void SlotEndiannessSelectorBeClicked(bool checked);
};
#endif // DATAINTERPRETERWIDGET_H
diff --git a/trunk/dlgsearch.ui b/trunk/dlgsearch.ui
index c681bd2..4bbfb5b 100644
--- a/trunk/dlgsearch.ui
+++ b/trunk/dlgsearch.ui
@@ -1,146 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgSearch</class>
<widget class="QDialog" name="DlgSearch">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>210</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string> Search</string>
</property>
<property name="windowIcon">
<iconset resource="fred.qrc">
<normaloff>:/icons/resources/fred.png</normaloff>:/icons/resources/fred.png</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Search value</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLineEdit" name="EdtValue"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="CbAscii">
<property name="text">
<string>ASCII</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="CbUtf16">
<property name="text">
<string>UTF16</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="CbHex">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
<property name="text">
<string>Hexadecimal</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Search for</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="CbNodeNames">
<property name="text">
<string>Node names</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="CbKeyNames">
<property name="text">
<string>Key names</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="CbKeyValues">
<property name="text">
<string>Key values</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QPushButton" name="BtnCancel">
<property name="text">
<string>&amp;Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="BtnSearch">
<property name="text">
<string>&amp;Search</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="fred.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/trunk/fred.pro b/trunk/fred.pro
index d4db4c2..d6f5dcc 100644
--- a/trunk/fred.pro
+++ b/trunk/fred.pro
@@ -1,111 +1,113 @@
#*******************************************************************************
# fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
# *
# Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
# with special feautures useful during forensic analysis. *
# *
# This program is free software: you can redistribute it and/or modify it *
# under the terms of the GNU General Public License as published by the Free *
# Software Foundation, either version 3 of the License, or (at your option) *
# any later version. *
# *
# This program is distributed in the hope that it will be useful, but WITHOUT *
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
# more details. *
# *
# You should have received a copy of the GNU General Public License along with *
# this program. If not, see <http://www.gnu.org/licenses/>. *
#******************************************************************************/
# Generate compileinfo.h
system(bash compileinfo.sh > compileinfo.h)
#compileinfo.target = compileinfo.h
#compileinfo.commands = $$PWD/compileinfo.sh > compileinfo.h
#QMAKE_EXTRA_TARGETS += compileinfo
#PRE_TARGETDEPS += compileinfo.h
# Build fred
QMAKE_CXXFLAGS += -Wall
QT += core \
gui \
script \
webkit
CONFIG += console
TARGET = fred
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
registrynode.cpp \
registrynodetreemodel.cpp \
registrykey.cpp \
registrykeytablemodel.cpp \
dlgabout.cpp \
dlgkeydetails.cpp \
qhexedit/qhexedit_p.cpp \
qhexedit/qhexedit.cpp \
reporttemplate.cpp \
datareporter.cpp \
datareporterengine.cpp \
registryhive.cpp \
qtscript_types/bytearray.cpp \
qtscript_types/bytearrayprototype.cpp \
qtscript_types/bytearrayiterator.cpp \
dlgreportviewer.cpp \
registrykeytable.cpp \
registrynodetree.cpp \
dlgsearch.cpp \
threadsearch.cpp \
searchresultwidget.cpp \
tabwidget.cpp \
argparser.cpp \
datainterpretertable.cpp \
- datainterpreterwidget.cpp
+ datainterpreterwidget.cpp \
+ hexeditwidget.cpp
HEADERS += mainwindow.h \
registrynode.h \
registrynodetreemodel.h \
registrykey.h \
registrykeytablemodel.h \
dlgabout.h \
dlgkeydetails.h \
qhexedit/qhexedit_p.h \
qhexedit/qhexedit.h \
reporttemplate.h \
datareporter.h \
datareporterengine.h \
registryhive.h \
qtscript_types/bytearray.h \
qtscript_types/bytearrayprototype.h \
qtscript_types/bytearrayiterator.h \
dlgreportviewer.h \
registrykeytable.h \
registrynodetree.h \
dlgsearch.h \
threadsearch.h \
searchresultwidget.h \
tabwidget.h \
argparser.h \
datainterpretertable.h \
- datainterpreterwidget.h
+ datainterpreterwidget.h \
+ hexeditwidget.h
FORMS += mainwindow.ui \
dlgabout.ui \
dlgkeydetails.ui \
dlgreportviewer.ui \
dlgsearch.ui
#LIBS += -lhivex
LIBS += $$PWD/hivex/lib/.libs/libhivex.a \
#DEFINES += __STDC_FORMAT_MACROS
RESOURCES += fred.qrc
RC_FILE = fred.rc
ICON = resources/fred.icns
diff --git a/trunk/hexeditwidget.cpp b/trunk/hexeditwidget.cpp
new file mode 100644
index 0000000..70ba521
--- /dev/null
+++ b/trunk/hexeditwidget.cpp
@@ -0,0 +1,125 @@
+/*******************************************************************************
+* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* *
+* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
+* with special feautures useful during forensic analysis. *
+* *
+* This program is free software: you can redistribute it and/or modify it *
+* under the terms of the GNU General Public License as published by the Free *
+* Software Foundation, either version 3 of the License, or (at your option) *
+* any later version. *
+* *
+* This program is distributed in the hope that it will be useful, but WITHOUT *
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
+* more details. *
+* *
+* You should have received a copy of the GNU General Public License along with *
+* this program. If not, see <http://www.gnu.org/licenses/>. *
+*******************************************************************************/
+
+#include <QFont>
+#include <QSizePolicy>
+
+#include "hexeditwidget.h"
+
+HexEditWidget::HexEditWidget(QWidget *p_parent) : QWidget(p_parent) {
+ // Init private vars
+ this->data=QByteArray();
+ this->read_only=true;
+
+ // Set widget layout. Setting it's parent to "this" will also call
+ // this->SetLayout.
+ this->p_widget_layout=new QVBoxLayout(this);
+
+ // Create sub-widgets
+ this->p_widget_splitter=new QSplitter(this);
+ this->p_hex_edit_layout_widget=new QWidget(this->p_widget_splitter);
+ this->p_hex_edit_layout=new QVBoxLayout(this->p_hex_edit_layout_widget);
+ this->p_hex_edit=new QHexEdit(this->p_hex_edit_layout_widget);
+ this->p_hex_edit_status_bar=new QLabel();
+ this->p_data_interpreter_widget=
+ new DataInterpreterWidget(this);
+
+ // Add hex edit and hex edit status bar to their layout
+ this->p_hex_edit_layout->addWidget(this->p_hex_edit);
+ this->p_hex_edit_layout->addWidget(this->p_hex_edit_status_bar);
+
+ // Add sub-widgets to splitter and splitter to our layout
+ this->p_widget_splitter->addWidget(this->p_hex_edit_layout_widget);
+ this->p_widget_splitter->addWidget(this->p_data_interpreter_widget);
+ this->p_widget_layout->addWidget(this->p_widget_splitter);
+
+ // Configure widget and sub-widgets
+ this->setContentsMargins(0,0,0,0);
+ this->p_widget_layout->setContentsMargins(0,0,0,0);
+ this->p_widget_splitter->setOrientation(Qt::Horizontal);
+ this->p_hex_edit_layout_widget->setContentsMargins(0,0,0,0);
+ this->p_hex_edit_layout->setContentsMargins(0,0,0,0);
+ this->p_hex_edit->setContentsMargins(0,0,0,0);
+ // 5 pixel bottom margin makes hex edit and data interpreter lignup correctly
+ this->p_hex_edit_status_bar->setContentsMargins(0,0,0,5);
+ this->p_hex_edit->setReadOnly(this->read_only);
+ this->setEnabled(false);
+
+ // Make sure hex edit font is monospaced.
+ QFont mono_font("Monospace");
+ mono_font.setStyleHint(QFont::TypeWriter);
+ this->p_hex_edit->setFont(mono_font);
+
+ // Set size policies of sub-widgets
+ QSizePolicy hex_edit_layout_widget_policy=
+ this->p_hex_edit_layout_widget->sizePolicy();
+ hex_edit_layout_widget_policy.setVerticalStretch(2);
+ hex_edit_layout_widget_policy.setHorizontalStretch(200);
+ this->p_hex_edit_layout_widget->setSizePolicy(hex_edit_layout_widget_policy);
+
+ QSizePolicy data_interpreter_widget_policy=
+ this->p_data_interpreter_widget->sizePolicy();
+ data_interpreter_widget_policy.setVerticalStretch(2);
+ data_interpreter_widget_policy.setHorizontalStretch(0);
+ this->p_data_interpreter_widget->
+ setSizePolicy(data_interpreter_widget_policy);
+
+ // Connect signals
+ this->connect(this->p_hex_edit,
+ SIGNAL(currentAddressChanged(int)),
+ this,
+ SLOT(SlotHexEditOffsetChanged(int)));
+}
+
+HexEditWidget::~HexEditWidget() {
+ delete this->p_data_interpreter_widget;
+ delete this->p_hex_edit_status_bar;
+ delete this->p_hex_edit;
+ delete this->p_hex_edit_layout;
+ delete this->p_hex_edit_layout_widget;
+ delete this->p_widget_splitter;
+ delete this->p_widget_layout;
+}
+
+void HexEditWidget::SetData(QByteArray const &new_data) {
+ this->data=new_data;
+
+ this->p_hex_edit->setData(this->data);
+ if(data.size()!=0) {
+ // Data set, update status bar and init data interpreter
+ this->SlotHexEditOffsetChanged(0);
+ } else {
+ // No data set, clear status bar and data interpreter
+ this->p_hex_edit_status_bar->setText("");
+ this->p_data_interpreter_widget->SetData(QByteArray());
+ }
+}
+
+void HexEditWidget::SlotHexEditOffsetChanged(int offset) {
+ // Update hex edit status bar
+ this->p_hex_edit_status_bar->setText(tr("Byte offset: 0x%1 (%2)")
+ .arg((quint16)offset,
+ 4,
+ 16,
+ QChar('0'))
+ .arg(offset));
+ // Update data interpreter
+ this->p_data_interpreter_widget->SetData(this->data.mid(offset,8));
+}
diff --git a/trunk/datainterpreterwidget.h b/trunk/hexeditwidget.h
similarity index 63%
copy from trunk/datainterpreterwidget.h
copy to trunk/hexeditwidget.h
index 2eeace2..b9d1cf9 100644
--- a/trunk/datainterpreterwidget.h
+++ b/trunk/hexeditwidget.h
@@ -1,72 +1,64 @@
/*******************************************************************************
-* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
-#ifndef DATAINTERPRETERWIDGET_H
-#define DATAINTERPRETERWIDGET_H
+#ifndef HEXEDITWIDGET_H
+#define HEXEDITWIDGET_H
#include <QWidget>
+#include <QSplitter>
#include <QVBoxLayout>
-#include <QHBoxLayout>
-#include <QRadioButton>
-#include <QString>
+#include <QLabel>
#include <QByteArray>
-#include "datainterpretertable.h"
+#include "qhexedit/qhexedit.h"
+#include "datainterpreterwidget.h"
-class DataInterpreterWidget : public QWidget {
+class HexEditWidget : public QWidget {
Q_OBJECT
public:
- enum Endianness {
- Endianness_LittleEndian=0,
- Endianness_BigEndian
- };
+ explicit HexEditWidget(QWidget *p_parent=0);
+ ~HexEditWidget();
- explicit DataInterpreterWidget(QWidget *p_parent=0);
- ~DataInterpreterWidget();
+ void SetData(QByteArray const &data);
- /*
- * SetData
- *
- * Set data to be interpreted (will also interpret it).
- */
- void SetData(QByteArray new_data);
+ signals:
+
+ public slots:
private:
// Widget layout
QVBoxLayout *p_widget_layout;
+ QSplitter *p_widget_splitter;
// Sub-widgets
- DataInterpreterTable *p_data_interpreter_table;
- QHBoxLayout *p_endianness_selector_layout;
- QRadioButton *p_endianness_selector_le;
- QRadioButton *p_endianness_selector_be;
+ QWidget *p_hex_edit_layout_widget;
+ QVBoxLayout *p_hex_edit_layout;
+ QHexEdit *p_hex_edit;
+ QLabel *p_hex_edit_status_bar;
+ DataInterpreterWidget *p_data_interpreter_widget;
// Vars
QByteArray data;
- int endianness;
-
- void InterpretData();
+ bool read_only;
private slots:
- void SlotEndiannessSelectorLeClicked(bool checked);
- void SlotEndiannessSelectorBeClicked(bool checked);
-
+ void SlotHexEditOffsetChanged(int offset);
};
-#endif // DATAINTERPRETERWIDGET_H
+#endif // HEXEDITWIDGET_H
diff --git a/trunk/main.cpp b/trunk/main.cpp
index 052e5d4..f8923cf 100644
--- a/trunk/main.cpp
+++ b/trunk/main.cpp
@@ -1,148 +1,154 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <QtGui/QApplication>
#include <QStringList>
#include <stdio.h>
#include "mainwindow.h"
#include "argparser.h"
#include "compileinfo.h"
#include "datareporter.h"
#include "registryhive.h"
// Forward declarations
void PrintUsage();
void DumpReport(QString report_template, QString hive_file);
// Main entry point
int main(int argc, char *argv[]) {
// Disable output buffering
setbuf(stdout,NULL);
// Init QApplication
QApplication a(argc, argv);
#define PRINT_HEADER { \
printf("%s v%s %s\n\n",APP_NAME,APP_VERSION,APP_COPYRIGHT); \
}
#define PRINT_HEADER_AND_USAGE { \
PRINT_HEADER; \
PrintUsage(); \
}
#define PRINT_VERSION printf("%s\n",APP_VERSION);
#define PRINT_UNKNOWN_ARG_ERROR(s) { \
PRINT_HEADER; \
printf("ERROR: Unknown command line argument '%s'!\n\n",s); \
PrintUsage(); \
}
// Parse command line args
ArgParser args(a.arguments());
if(!args.ParseArgs()) {
PRINT_HEADER;
printf("ERROR: %s\n\n",args.GetErrorMsg().toAscii().constData());
PrintUsage();
exit(1);
}
// Check command line args for correctness
if(args.IsSet("dump-report")) {
if(args.GetArgVal("dump-report")=="") {
PRINT_HEADER;
printf("ERROR: --dump-report specified without a report file!\n\n");
PrintUsage();
exit(1);
}
if(!args.IsSet("hive-file")) {
PRINT_HEADER;
printf("ERROR: --dump-report specified without a hive file!\n\n");
PrintUsage();
exit(1);
}
}
+ if(args.IsSet("fullscreen") && args.IsSet("maximized")) {
+ PRINT_HEADER;
+ printf("ERROR: --fullscreen and --maximized cannot be specified both!\n\n");
+ PrintUsage();
+ exit(1);
+ }
- // React on some command line args
+ // React on some command line args early
if(args.IsSet("?") || args.IsSet("h") || args.IsSet("help")) {
PRINT_HEADER_AND_USAGE;
exit(0);
}
if(args.IsSet("v") || args.IsSet("version")) {
PRINT_VERSION;
exit(0);
}
if(args.IsSet("dump-report")) {
// Dump report to stdout
DumpReport(args.GetArgVal("dump-report"),args.GetArgVal("hive-file"));
exit(0);
}
#undef PRINT_UNKNOWN_ARG_ERROR
#undef PRINT_VERSION
#undef PRINT_HEADER_AND_USAGE
#undef PRINT_HEADER
// Create and show main window
MainWindow w(&args);
w.show();
return a.exec();
}
void PrintUsage() {
printf("Usage:\n");
printf(" %s [opts] [hive]\n\n",
qApp->arguments().at(0).toAscii().constData());
printf("Options:\n");
printf(" opts:\n");
- printf(" -?, -h, --help : Display this help message.\n");
- printf(" -v, --version : Display version info.\n");
-
printf(" --dump-report=FILE : Dump the specified report to stdout.\n");
-
+ printf(" --fullscreen : Display main window in fullscreen mode.\n");
+ printf(" -h, -?, --help : Display this help message.\n");
+ printf(" --maximized : Display main window in maximized mode.\n");
+ printf(" -v, --version : Display version info.\n");
printf(" hive:\n");
- printf(" Use the specified hive file.\n");
+ printf(" Open / Use the specified hive file.\n");
printf("\n");
}
void DumpReport(QString report_template, QString hive_file) {
RegistryHive *p_hive=new RegistryHive();
DataReporter *p_data_reporter=new DataReporter();
// Open hive
if(!p_hive->Open(hive_file,true)) {
printf("ERROR: Unable to open hive file '%s'!\n",
hive_file.toAscii().constData());
exit(1);
}
// Generate report
QString result=p_data_reporter->GenerateReport(p_hive,report_template,true);
// Close hive and free DataReporter and RegistryHive
p_hive->Close();
delete p_data_reporter;
delete p_hive;
// Print result to stdout
printf("%s",result.toAscii().constData());
}
diff --git a/trunk/mainwindow.cpp b/trunk/mainwindow.cpp
index 29faec1..3e6b1e5 100644
--- a/trunk/mainwindow.cpp
+++ b/trunk/mainwindow.cpp
@@ -1,621 +1,566 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef FRED_REPORT_TEMPLATE_DIR
#ifndef __MINGW32__
#define FRED_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates/"
#else
#define FRED_REPORT_TEMPLATE_DIR ".\\report_templates\\"
#endif
#endif
#include <QFileDialog>
#include <QMessageBox>
#include <QStringList>
#include <QDesktopWidget>
#include <QDir>
#include <QSplitter>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dlgabout.h"
#include "dlgkeydetails.h"
#include "dlgreportviewer.h"
#include "dlgsearch.h"
#include "compileinfo.h"
MainWindow::MainWindow(ArgParser *p_arg_parser) :
QMainWindow(0), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Initialize private vars
this->p_args=p_arg_parser;
this->p_hive=new RegistryHive(this);
this->is_hive_open=false;
this->p_reg_node_tree_model=NULL;
this->p_reg_key_table_model=NULL;
this->p_search_thread=NULL;
this->search_result_widgets.clear();
// Check for ~/.fred config dir
this->CheckUserConfigDir();
// Set main window size
int cur_screen=QApplication::desktop()->screenNumber(this);
int window_width=
QApplication::desktop()->availableGeometry(cur_screen).width()*0.5;
int window_height=
QApplication::desktop()->availableGeometry(cur_screen).height()*0.5;
int window_x=
(QApplication::desktop()->availableGeometry(cur_screen).width()/2)-
(window_width/2);
int window_y=
(QApplication::desktop()->availableGeometry(cur_screen).height()/2)-
(window_height/2);
this->setGeometry(window_x,
window_y,
window_width,
window_height);
// Create widgets
this->p_horizontal_splitter=new QSplitter();
this->p_horizontal_splitter->setOrientation(Qt::Horizontal);
this->p_node_tree=new RegistryNodeTree(this->p_horizontal_splitter);
this->p_node_tree->setHeaderHidden(true);
this->p_vertical_splitter=new QSplitter(this->p_horizontal_splitter);
this->p_vertical_splitter->setOrientation(Qt::Vertical);
this->p_key_table=new RegistryKeyTable(this->p_vertical_splitter);
this->p_tab_widget=new TabWidget(this->p_vertical_splitter);
- this->p_horizontal_splitter2=new QSplitter();
- this->p_horizontal_splitter2->setOrientation(Qt::Horizontal);
-
- this->p_hex_edit_widget=new QWidget(this->p_horizontal_splitter2);
- this->p_hex_edit_layout=new QVBoxLayout(this->p_hex_edit_widget);
- this->p_hex_edit_layout->setContentsMargins(0,0,0,0);
- this->p_hex_edit=new QHexEdit();
- this->p_hex_edit->setReadOnly(true);
- this->p_hex_edit_status_bar=new QLabel();
-
- this->p_data_interpreter_widget=
- new DataInterpreterWidget(this->p_horizontal_splitter2);
-
- // Make sure hex viewer font is monospaced.
- QFont mono_font("Monospace");
- mono_font.setStyleHint(QFont::TypeWriter);
- this->p_hex_edit->setFont(mono_font);
+ this->p_hex_edit_widget=new HexEditWidget();
// Add hexedit page to tab_widget
- this->p_tab_widget->addTab(this->p_horizontal_splitter2,tr("Hex viewer"));
-
- // Lay out widgets
- this->p_hex_edit_layout->addWidget(this->p_hex_edit);
- this->p_hex_edit_layout->addWidget(this->p_hex_edit_status_bar);
-
- this->p_horizontal_splitter2->addWidget(this->p_hex_edit_widget);
- this->p_horizontal_splitter2->addWidget(this->p_data_interpreter_widget);
+ this->p_tab_widget->addTab(this->p_hex_edit_widget,tr("Hex viewer"));
+ // Add widgets to their splitters
this->p_vertical_splitter->addWidget(this->p_key_table);
this->p_vertical_splitter->addWidget(this->p_tab_widget);
this->p_horizontal_splitter->addWidget(this->p_node_tree);
this->p_horizontal_splitter->addWidget(this->p_vertical_splitter);
// Set stretch factors
QSizePolicy node_tree_policy=this->p_node_tree->sizePolicy();
node_tree_policy.setHorizontalStretch(1);
node_tree_policy.setVerticalStretch(100);
this->p_node_tree->setSizePolicy(node_tree_policy);
QSizePolicy vertical_splitter_policy=this->p_vertical_splitter->sizePolicy();
vertical_splitter_policy.setHorizontalStretch(4);
vertical_splitter_policy.setVerticalStretch(100);
this->p_vertical_splitter->setSizePolicy(vertical_splitter_policy);
QSizePolicy key_table_policy=this->p_key_table->sizePolicy();
key_table_policy.setVerticalStretch(5);
key_table_policy.setHorizontalStretch(100);
this->p_key_table->setSizePolicy(key_table_policy);
QSizePolicy tab_widget_policy=this->p_tab_widget->sizePolicy();
tab_widget_policy.setVerticalStretch(2);
tab_widget_policy.setHorizontalStretch(200);
this->p_tab_widget->setSizePolicy(tab_widget_policy);
- QSizePolicy hex_edit_widget_policy=this->p_hex_edit_widget->sizePolicy();
- hex_edit_widget_policy.setVerticalStretch(2);
- hex_edit_widget_policy.setHorizontalStretch(200);
- this->p_hex_edit_widget->setSizePolicy(hex_edit_widget_policy);
-
- QSizePolicy data_interpreter_widget_policy=
- this->p_data_interpreter_widget->sizePolicy();
- data_interpreter_widget_policy.setVerticalStretch(2);
- data_interpreter_widget_policy.setHorizontalStretch(0);
- this->p_data_interpreter_widget->
- setSizePolicy(data_interpreter_widget_policy);
-
// Connect signals
this->connect(this->p_node_tree,
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_node_tree,
SIGNAL(activated(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_node_tree,
SIGNAL(CurrentItemChanged(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotKeyTableClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotKeyTableDoubleClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(CurrentItemChanged(QModelIndex)),
this,
SLOT(SlotKeyTableClicked(QModelIndex)));
- this->connect(this->p_hex_edit,
- SIGNAL(currentAddressChanged(int)),
- this,
- SLOT(SlotHexEditAddressChanged(int)));
this->connect(this->p_tab_widget,
SIGNAL(tabCloseRequested(int)),
this,
SLOT(SlotTabCloseButtonClicked(int)));
// Add central widget
this->setCentralWidget(this->p_horizontal_splitter);
this->centralWidget()->setContentsMargins(4,4,4,0);
// Set window title
this->UpdateWindowTitle();
// Set last open location to home dir
this->last_open_location=QDir::homePath();
// Load report templates and update menu
this->p_data_reporter=new DataReporter();
// Load reports from system wide include dir
this->p_data_reporter->LoadReportTemplates(FRED_REPORT_TEMPLATE_DIR);
// Load user's report templates
this->p_data_reporter->LoadReportTemplates(QDir::homePath()
.append(QDir::separator())
.append(".fred")
.append(QDir::separator())
.append("report_templates"));
this->UpdateDataReporterMenu();
// Finally, react on some command line arguments
+ if(this->p_args->IsSet("maximized")) {
+ this->setWindowState(Qt::WindowMaximized);
+ }
+ if(this->p_args->IsSet("fullscreen")) {
+ this->setWindowState(Qt::WindowFullScreen);
+ }
if(this->p_args->IsSet("hive-file")) {
this->OpenHive(this->p_args->GetArgVal("hive-file"));
}
}
MainWindow::~MainWindow() {
if(this->is_hive_open) {
this->p_hive->Close();
}
delete ui;
}
void MainWindow::on_action_Quit_triggered() {
qApp->exit();
}
void MainWindow::on_action_Open_hive_triggered() {
QString hive_file="";
hive_file=QFileDialog::getOpenFileName(this,
tr("Open registry hive"),
this->last_open_location,
tr("All files (*)"));
if(hive_file=="") return;
this->OpenHive(hive_file);
}
void MainWindow::on_action_Close_hive_triggered() {
if(this->is_hive_open) {
// Remove search results
while(this->p_tab_widget->count()>1) {
this->p_tab_widget->removeTab(this->p_tab_widget->count()-1);
delete this->search_result_widgets.at(this->p_tab_widget->count()-1);
this->search_result_widgets.removeLast();
}
// Delete models
if(this->p_reg_node_tree_model!=NULL) {
this->p_node_tree->setModel(NULL);
delete this->p_reg_node_tree_model;
this->p_reg_node_tree_model=NULL;
}
if(this->p_reg_key_table_model!=NULL) {
this->p_key_table->setModel(NULL);
delete this->p_reg_key_table_model;
this->p_reg_key_table_model=NULL;
}
// Remove any data from hex edit and data interpreter
- this->p_hex_edit->setData(QByteArray());
- this->p_hex_edit_status_bar->setText("");
- this->p_data_interpreter_widget->SetData(QByteArray());
- this->p_data_interpreter_widget->setEnabled(false);
+ this->p_hex_edit_widget->SetData(QByteArray());
+ this->p_hex_edit_widget->setEnabled(false);
// Close hive
this->p_hive->Close();
this->is_hive_open=false;
this->ui->action_Close_hive->setEnabled(false);
this->ui->ActionSearch->setEnabled(false);
this->ui->MenuReports->setEnabled(false);
this->UpdateWindowTitle();
}
}
void MainWindow::on_actionAbout_Qt_triggered() {
QMessageBox::aboutQt(this,tr("About Qt"));
}
void MainWindow::on_actionAbout_fred_triggered() {
DlgAbout dlg_about(this);
dlg_about.exec();
}
void MainWindow::on_ActionSearch_triggered() {
DlgSearch dlg_search(this);
if(dlg_search.exec()==QDialog::Accepted) {
// Create search thread and connect needed signals/slots
this->p_search_thread=new ThreadSearch(this);
QList<QByteArray> keywords;
keywords.append(QByteArray(QString("Windows").toAscii()));
// Add new search widget to tabwidget and to internal widget list
SearchResultWidget *p_search_widget=
new SearchResultWidget(this->p_tab_widget);
p_search_widget->setEnabled(false);
this->search_result_widgets.append(p_search_widget);
this->connect(p_search_widget,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotSearchResultWidgetDoubleClicked(QModelIndex)));
this->p_tab_widget->addTab(p_search_widget,tr("Search results"),true);
this->p_tab_widget->setCurrentIndex(this->p_tab_widget->count()-1);
// Connect search thread to result widget
this->connect(this->p_search_thread,
SIGNAL(SignalFoundMatch(ThreadSearch::eMatchType,
QString,QString,QString)),
p_search_widget,
SLOT(SlotFoundMatch(ThreadSearch::eMatchType,
QString,QString,QString)));
this->connect(this->p_search_thread,
SIGNAL(finished()),
this,
SLOT(SlotSearchFinished()));
this->connect(this->p_search_thread,
SIGNAL(finished()),
p_search_widget,
SLOT(SlotSearchFinished()));
// Start searching
this->ui->ActionSearch->setEnabled(false);
p_search_thread->Search(this->p_hive->Filename(),
dlg_search.Keywords(),
dlg_search.SearchNodeNames(),
dlg_search.SearchKeyNames(),
dlg_search.SearchKeyValues());
}
}
void MainWindow::SlotNodeTreeClicked(QModelIndex index) {
QString node_path;
if(!index.isValid()) return;
// Built node path
node_path=this->p_reg_node_tree_model->GetNodePath(index);
// Create table model and attach it to the table view
if(this->p_reg_key_table_model!=NULL) {
// If a previous model was set, delete it and clear hexedit etc...
this->p_key_table->setModel(NULL);
delete this->p_reg_key_table_model;
- this->p_hex_edit->setData(QByteArray());
- this->p_hex_edit_status_bar->setText("");
- this->p_data_interpreter_widget->SetData(QByteArray());
+ this->p_hex_edit_widget->SetData(QByteArray());
}
this->p_reg_key_table_model=new RegistryKeyTableModel(this->p_hive,node_path);
this->p_key_table->setModel(this->p_reg_key_table_model);
// Set focus back to nodetree to be able to navigate with keyboard
this->p_node_tree->setFocus();
}
void MainWindow::SlotKeyTableDoubleClicked(QModelIndex index) {
Q_UNUSED(index);
/*
QModelIndex key_index;
QModelIndex node_index;
QStringList nodes;
QString key_name;
QString key_type;
QByteArray key_value;
if(!index.isValid()) return;
// Get key name, type and value
key_index=this->p_reg_key_table_model->index(index.row(),0);
key_name=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();
key_index=this->p_reg_key_table_model->index(index.row(),1);
key_type=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();ThreadSearch
key_index=this->p_reg_key_table_model->index(index.row(),2);
key_value=this->p_reg_key_table_model->data(key_index,
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
// Get current node
node_index=this->p_node_tree->currentIndex();
//Built node path
nodes.clear();
nodes.append(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
while(this->p_reg_node_tree_model->parent(node_index)!=QModelIndex()) {
// Prepend all parent nodes
node_index=this->p_reg_node_tree_model->parent(node_index);
nodes.prepend(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
}
DlgKeyDetails dlg_key_details(this);
dlg_key_details.SetValues(nodes,key_name,key_type,key_value);
dlg_key_details.exec();
*/
}
void MainWindow::SlotKeyTableClicked(QModelIndex index) {
if(!index.isValid()) return;
this->selected_key_value=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),2),
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
- this->p_hex_edit->setData(this->selected_key_value);
+ this->p_hex_edit_widget->SetData(this->selected_key_value);
// Set focus back to nodetree to be able to navigate with keyboard
this->p_key_table->setFocus();
}
-void MainWindow::SlotHexEditAddressChanged(int hex_offset) {
- if(!this->is_hive_open || this->selected_key_value.isEmpty()) return;
-
- // Update hex edit status bar
- this->p_hex_edit_status_bar->
- setText(QString("Byte offset: 0x%1 (%2)")
- .arg((uint16_t)hex_offset,4,16,QChar('0'))
- .arg(hex_offset));
- // Update data interpreter
- this->UpdateDataInterpreter(hex_offset);
-}
-
void MainWindow::SlotReportClicked() {
// Get report category and name from sender and it's parent
QString category=((QMenu*)((QAction*)QObject::sender())->parent())->title();
QString report=((QAction*)QObject::sender())->text();
// Generate report
QString report_content=this->p_data_reporter->GenerateReport(this->p_hive,
category,
report);
// Show result in report viewer
if(report_content!=QString()) {
DlgReportViewer *p_dlg_report_view=new DlgReportViewer(report_content,this);
p_dlg_report_view->exec();
delete p_dlg_report_view;
} else {
// TODO: Something went wrong!
}
}
void MainWindow::SlotSearchFinished() {
delete this->p_search_thread;
this->p_search_thread=NULL;
this->ui->ActionSearch->setEnabled(true);
// Enable result widget
this->search_result_widgets.last()->setEnabled(true);
}
void MainWindow::SlotSearchResultWidgetDoubleClicked(QModelIndex index) {
SearchResultWidget *p_sender;
QString path;
QString match_type;
QString value;
QString key="";
int i;
if(!index.isValid()) return;
// Get pointer to sender
p_sender=(SearchResultWidget*)QObject::sender();
// Get path and matchtype
path=p_sender->item(index.row(),0)->text();
match_type=p_sender->item(index.row(),1)->text();
value=p_sender->item(index.row(),2)->text();
if(match_type==tr("Node name")) {
// Node name is not part of path. Add it
if(path=="\\") path.append(value);
else path.append("\\").append(value);
} else if(match_type==tr("Key name")) {
// Key name is stored in value
key=value;
} else if(match_type==tr("Key value")) {
// Key name is part of path. Save and remove it
QStringList nodes=path.split("\\",QString::SkipEmptyParts);
key=nodes.at(nodes.count()-1);
// Remove \<key name> from path
path.chop(key.length()+1);
}
// Expand treeview to correct node
QList<QModelIndex> indexes=
this->p_reg_node_tree_model->GetIndexListOf(path);
for(i=0;i<indexes.count();i++) {
this->p_node_tree->expand(indexes.at(i));
}
if(indexes.count()>0) {
// Scroll to last expanded node, select it and update widgets
this->p_node_tree->scrollTo(indexes.at(indexes.count()-1),
QAbstractItemView::PositionAtCenter);
this->p_node_tree->selectionModel()->clear();
this->p_node_tree->selectionModel()->
select(indexes.at(indexes.count()-1),
QItemSelectionModel::Select);
// TODO: This does not work!!
this->SlotNodeTreeClicked(indexes.at(indexes.count()-1));
}
// Select correct key if search matched on keay name / value
if(key!="") {
int row=this->p_reg_key_table_model->GetKeyRow(key);
this->p_key_table->clearSelection();
this->p_key_table->scrollTo(this->p_reg_key_table_model->index(row,0),
QAbstractItemView::PositionAtCenter);
this->p_key_table->selectRow(row);
this->SlotKeyTableClicked(this->p_reg_key_table_model->index(row,0));
}
}
void MainWindow::SlotTabCloseButtonClicked(int index) {
// Delete tab widget and remove tab
this->p_tab_widget->removeTab(index);
delete this->search_result_widgets.at(index-1);
this->search_result_widgets.removeAt(index-1);
}
void MainWindow::CheckUserConfigDir() {
QString user_config_dir=QDir::homePath()
.append(QDir::separator())
.append(".fred");
if(!QDir(user_config_dir).exists()) {
// User config dir does not exists, try to create it
if(!QDir().mkpath(user_config_dir)) {
// TODO: Maybe warn user
return;
}
user_config_dir.append(QDir::separator()).append("report_templates");
if(!QDir().mkpath(user_config_dir)) {
// TODO: Maybe warn user
return;
}
}
}
void MainWindow::UpdateWindowTitle(QString filename) {
if(filename=="") {
this->setWindowTitle(QString("%1 v%2").arg(APP_TITLE,APP_VERSION));
} else {
this->setWindowTitle(QString("%1 v%2 - %3").arg(APP_TITLE,
APP_VERSION,
filename.toLocal8Bit()
.constData()));
}
}
-void MainWindow::UpdateDataInterpreter(int hex_offset) {
- // Update data interpreter. There is currently no interpretition that uses
- // more then 8 bytes, so only pass 8 bytes at max.
- this->p_data_interpreter_widget->SetData(
- this->selected_key_value.mid(hex_offset,8));
-}
-
void MainWindow::UpdateDataReporterMenu() {
int i=0,ii=0;
QMenu *p_category_entry;
QAction *p_report_entry;
QStringList categories=this->p_data_reporter->GetAvailableReportCategories();
QStringList reports;
for(i=0;i<categories.count();i++) {
// First create category submenu
p_category_entry=this->ui->MenuReports->addMenu(categories.value(i));
// Now add category reports
reports=this->p_data_reporter->GetAvailableReports(categories.value(i));
for(ii=0;ii<reports.count();ii++) {
p_report_entry=new QAction(reports.value(ii),p_category_entry);
p_category_entry->addAction(p_report_entry);
this->connect(p_report_entry,
SIGNAL(triggered()),
this,
SLOT(SlotReportClicked()));
}
}
}
void MainWindow::OpenHive(QString hive_file) {
// Update last open location
this->last_open_location=hive_file.left(hive_file.
lastIndexOf(QDir::separator()));
// If another hive is currently open, close it
if(this->is_hive_open) this->on_action_Close_hive_triggered();
// Try to open hive
if(!this->p_hive->Open(hive_file)) {
QMessageBox::critical(this,
tr("Error opening hive file"),
tr("Unable to open file '%1'").arg(hive_file));
return;
}
// Create tree model
this->p_reg_node_tree_model=
new RegistryNodeTreeModel(this->p_hive);
this->p_node_tree->setModel(this->p_reg_node_tree_model);
this->is_hive_open=true;
this->ui->action_Close_hive->setEnabled(true);
this->ui->ActionSearch->setEnabled(true);
this->ui->MenuReports->setEnabled(true);
// Enable data interpreter
- this->p_data_interpreter_widget->setEnabled(true);
+ this->p_hex_edit_widget->setEnabled(true);
this->UpdateWindowTitle(hive_file);
}
diff --git a/trunk/mainwindow.h b/trunk/mainwindow.h
index e1211a9..b27cf14 100644
--- a/trunk/mainwindow.h
+++ b/trunk/mainwindow.h
@@ -1,151 +1,123 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QLabel>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QSplitter>
#include <QString>
#include <QByteArray>
#include <hivex.h>
#include "argparser.h"
#include "registryhive.h"
#include "registrynodetree.h"
#include "registrynodetreemodel.h"
#include "registrykeytable.h"
#include "registrykeytablemodel.h"
-#include "qhexedit/qhexedit.h"
-#include "datainterpreterwidget.h"
+#include "hexeditwidget.h"
#include "datareporter.h"
#include "threadsearch.h"
#include "searchresultwidget.h"
#include "tabwidget.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(ArgParser *p_arg_parser);
~MainWindow();
private slots:
void on_action_Quit_triggered();
void on_action_Open_hive_triggered();
void on_action_Close_hive_triggered();
void on_actionAbout_Qt_triggered();
void on_actionAbout_fred_triggered();
void on_ActionSearch_triggered();
void SlotNodeTreeClicked(QModelIndex index);
void SlotKeyTableClicked(QModelIndex index);
void SlotKeyTableDoubleClicked(QModelIndex index);
- void SlotHexEditAddressChanged(int hex_offset);
void SlotReportClicked();
void SlotSearchFinished();
void SlotSearchResultWidgetDoubleClicked(QModelIndex index);
void SlotTabCloseButtonClicked(int index);
-/*
- void SlotDataInterpreterEndiannessBe(bool checked);
- void SlotDataInterpreterEndiannessLe(bool checked);
-*/
private:
Ui::MainWindow *ui;
ArgParser *p_args;
QString last_open_location;
RegistryHive *p_hive;
bool is_hive_open;
RegistryNodeTreeModel *p_reg_node_tree_model;
RegistryKeyTableModel *p_reg_key_table_model;
QByteArray selected_key_value;
QList<SearchResultWidget*> search_result_widgets;
// Widgets etc...
RegistryNodeTree *p_node_tree;
RegistryKeyTable *p_key_table;
TabWidget *p_tab_widget;
- QWidget *p_hex_edit_widget;
- QVBoxLayout *p_hex_edit_layout;
- QHexEdit *p_hex_edit;
- QLabel *p_hex_edit_status_bar;
-
-/*
- QWidget *p_data_interpreter_widget;
- QVBoxLayout *p_data_interpreter_layout;
- DataInterpreter *p_data_interpreter;
-
- QWidget *p_data_interpreter_endianness_widget;
- QHBoxLayout *p_data_interpreter_endianness_layout;
- QRadioButton *p_data_interpreter_endianness_be;
- QRadioButton *p_data_interpreter_endianness_le;
-*/
- DataInterpreterWidget *p_data_interpreter_widget;
+ HexEditWidget *p_hex_edit_widget;
QSplitter *p_horizontal_splitter;
- QSplitter *p_horizontal_splitter2;
QSplitter *p_vertical_splitter;
DataReporter *p_data_reporter;
ThreadSearch *p_search_thread;
/*
* CheckUserConfigDir
*
* Checks for and possibly creates the ~/.fred directory
*/
void CheckUserConfigDir();
/*
* UpdateWindowTitle
*
* Updates the window title
*/
void UpdateWindowTitle(QString filename="");
- /*
- * UpdateDataInterpreter
- *
- * Update data interpreter
- */
- void UpdateDataInterpreter(int hex_offset);
/*
* UpdateDataReporterMenu
*
*/
void UpdateDataReporterMenu();
/*
* OpenHive
*
* Open a registry hive
*/
void OpenHive(QString hive_file);
};
#endif // MAINWINDOW_H

File Metadata

Mime Type
text/x-diff
Expires
Tue, Dec 24, 3:06 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1176825
Default Alt Text
(67 KB)

Event Timeline