Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F4324571
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
67 KB
Referenced Files
None
Subscribers
None
View Options
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>&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>&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
Details
Attached
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)
Attached To
Mode
rFRED fred
Attached
Detach File
Event Timeline
Log In to Comment