Page MenuHomePhabricator

No OneTemporary

Size
118 KB
Referenced Files
None
Subscribers
None
diff --git a/trunk/dlgreportchooser.cpp b/trunk/dlgreportchooser.cpp
index 223fb92..bb95439 100644
--- a/trunk/dlgreportchooser.cpp
+++ b/trunk/dlgreportchooser.cpp
@@ -1,94 +1,148 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 "dlgreportchooser.h"
#include "ui_dlgreportchooser.h"
#include <QString>
#include <QStringList>
#include <QListIterator>
-DlgReportChooser::DlgReportChooser(Reports *p_reps, QWidget *p_parent)
+#include <QDebug>
+
+DlgReportChooser::DlgReportChooser(Reports *p_reps,
+ QString hive_type_string,
+ QWidget *p_parent)
: QDialog(p_parent), ui(new Ui::DlgReportChooser)
{
- QTreeWidgetItem *p_category;
- QTreeWidgetItem *p_category_report;
+ QStringList tree_cats;
+ QString cur_tree_cat;
+ QTreeWidgetItem *p_tree_cat_widget;
+ QTreeWidgetItem *p_tree_cat_rep_widget;
+ QList<ReportTemplate*> tree_cat_reports;
+ ReportTemplate* p_report;
+ // Init private vars
this->ui->setupUi(this);
-
- // Save values for later use
this->p_reports=p_reps;
+ this->hive_type=hive_type_string;
+ this->tree_category_items.clear();
+ this->selected_reports.clear();
// Populate tree with reports
- QStringList report_cats=this->p_reports->GetAvailableReportCategories();
- QListIterator<QString> cat_it(report_cats);
- QString cur_cat;
- while(cat_it.hasNext()) {
- cur_cat=cat_it.next();
- p_category=new QTreeWidgetItem(this->ui->TrReports);
- p_category->setText(0,cur_cat);
- QStringList reports=this->p_reports->GetAvailableReports(cur_cat);
- QListIterator<QString> rep_it(reports);
- while(rep_it.hasNext()) {
- p_category_report=new QTreeWidgetItem(p_category);
- p_category_report->setText(0,rep_it.next());
- p_category_report->setFlags(Qt::ItemIsEnabled|
- Qt::ItemIsSelectable|
- Qt::ItemIsUserCheckable);
- p_category_report->setCheckState(0,Qt::Unchecked);
+ tree_cats=this->p_reports->GetAvailableReportCategories();
+ QListIterator<QString> tree_cat_it(tree_cats);
+ while(tree_cat_it.hasNext()) {
+ cur_tree_cat=tree_cat_it.next();
+ p_tree_cat_widget=new QTreeWidgetItem(this->ui->TrReports);
+ p_tree_cat_widget->setText(0,cur_tree_cat);
+ p_tree_cat_widget->setFlags(Qt::ItemIsEnabled|
+ Qt::ItemIsUserCheckable|
+ Qt::ItemIsTristate);
+ p_tree_cat_widget->setCheckState(0,Qt::Unchecked);
+ tree_cat_reports=this->p_reports->GetAvailableReports(cur_tree_cat);
+ QListIterator<ReportTemplate*> tree_cat_rep_it(tree_cat_reports);
+ while(tree_cat_rep_it.hasNext()) {
+ p_report=tree_cat_rep_it.next();
+
+ p_tree_cat_rep_widget=new QTreeWidgetItem(p_tree_cat_widget);
+ // Save pointer to ReportTemplate alongside
+ p_tree_cat_rep_widget->setData(0,
+ Qt::UserRole,
+ QVariant().fromValue(p_report));
+ p_tree_cat_rep_widget->setText(0,p_report->Name());
+ p_tree_cat_rep_widget->setFlags(Qt::ItemIsEnabled|
+ Qt::ItemIsSelectable|
+ Qt::ItemIsUserCheckable);
+ if(this->hive_type!="UNKNOWN" && this->hive_type==p_report->Hive()) {
+ p_tree_cat_rep_widget->setCheckState(0,Qt::Checked);
+ } else {
+ p_tree_cat_rep_widget->setCheckState(0,Qt::Unchecked);
+ }
}
+ this->tree_category_items.append(p_tree_cat_widget);
}
+
+ // Finally, expand all categories
+ this->ui->TrReports->expandAll();
}
DlgReportChooser::~DlgReportChooser() {
delete this->ui;
}
+QList<ReportTemplate*> DlgReportChooser::GetSelectedReports()
+{
+ return this->selected_reports;
+}
+
void DlgReportChooser::changeEvent(QEvent *e) {
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
this->ui->retranslateUi(this);
break;
default:
break;
}
}
void DlgReportChooser::on_BtnCancel_clicked() {
this->reject();
}
-void DlgReportChooser::on_TrReports_currentItemChanged(QTreeWidgetItem *current,
- QTreeWidgetItem *previous)
+void DlgReportChooser::on_TrReports_currentItemChanged(
+ QTreeWidgetItem *p_current, QTreeWidgetItem *p_previous)
{
- QString category,name;
-
- if(current->parent()==NULL) return;
-
- category=current->parent()->text(0);
- name=current->text(0);
- QMap<QString,QString> report_infos=
- this->p_reports->GetReportInfo(category,name);
- this->ui->LblAuthor->setText(tr("Author: %1")
- .arg(report_infos["report_author"]));
- this->ui->LblDesc->setText(tr("Description:\n\n %1")
- .arg(report_infos["report_desc"]));
+ Q_UNUSED(p_previous)
+
+ // If item has no parent, clear labels and return
+ if(p_current->parent()==NULL) {
+ this->ui->LblAuthor->clear();
+ this->ui->LblDesc->clear();
+ return;
+ }
+
+ // Update labels
+ this->ui->LblAuthor->setText(
+ p_current->data(0,Qt::UserRole).value<ReportTemplate*>()->Author());
+ this->ui->LblDesc->setText(
+ p_current->data(0,Qt::UserRole).value<ReportTemplate*>()->Description());
+}
+
+void DlgReportChooser::on_BtnGenerate_clicked() {
+ QTreeWidgetItem *p_cat;
+ int i;
+
+ // Add selected reports to selected_reports
+ QListIterator<QTreeWidgetItem*> cat_it(this->tree_category_items);
+ while(cat_it.hasNext()) {
+ p_cat=cat_it.next();
+ for(i=0;i<p_cat->childCount();i++) {
+ if(p_cat->child(i)->checkState(0)==Qt::Checked) {
+ // Get saved pointer to ReportTemplate and append it to selected_reps
+ this->selected_reports.append(p_cat->
+ child(i)->data(0,Qt::UserRole).value<ReportTemplate*>());
+ }
+ }
+ }
+
+ this->accept();
}
diff --git a/trunk/dlgreportchooser.h b/trunk/dlgreportchooser.h
index 8751723..a8820b7 100644
--- a/trunk/dlgreportchooser.h
+++ b/trunk/dlgreportchooser.h
@@ -1,53 +1,62 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 DLGREPORTCHOOSER_H
#define DLGREPORTCHOOSER_H
#include "reports.h"
#include <QDialog>
+#include <QList>
#include <QTreeWidgetItem>
namespace Ui {
class DlgReportChooser;
}
class DlgReportChooser : public QDialog {
Q_OBJECT
public:
- explicit DlgReportChooser(Reports *p_reps, QWidget *p_parent=0);
+ explicit DlgReportChooser(Reports *p_reps,
+ QString hive_type_string,
+ QWidget *p_parent=0);
~DlgReportChooser();
+ QList<ReportTemplate*> GetSelectedReports();
+
protected:
void changeEvent(QEvent *e);
private slots:
void on_BtnCancel_clicked();
-
- void on_TrReports_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
+ void on_TrReports_currentItemChanged(QTreeWidgetItem *p_current,
+ QTreeWidgetItem *p_previous);
+ void on_BtnGenerate_clicked();
private:
Ui::DlgReportChooser *ui;
Reports *p_reports;
+ QString hive_type;
+ QList<QTreeWidgetItem*> tree_category_items;
+ QList<ReportTemplate*> selected_reports;
};
#endif // DLGREPORTCHOOSER_H
diff --git a/trunk/dlgreportchooser.ui b/trunk/dlgreportchooser.ui
index 6e4877d..6d023e3 100644
--- a/trunk/dlgreportchooser.ui
+++ b/trunk/dlgreportchooser.ui
@@ -1,125 +1,209 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgReportChooser</class>
<widget class="QDialog" name="DlgReportChooser">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
+ <width>599</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Generate report</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>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="title">
<string>Available reports</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
+ <property name="topMargin">
+ <number>9</number>
+ </property>
+ <property name="rightMargin">
+ <number>9</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item>
<widget class="QTreeWidget" name="TrReports">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="headerHidden">
<bool>true</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>3</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
<property name="title">
<string>Report details</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>9</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ <underline>true</underline>
+ </font>
+ </property>
+ <property name="text">
+ <string>Author:</string>
+ </property>
+ </widget>
+ </item>
<item>
<widget class="QLabel" name="LblAuthor">
<property name="text">
<string/>
</property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="font">
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ <underline>true</underline>
+ </font>
+ </property>
+ <property name="text">
+ <string>Description:</string>
+ </property>
</widget>
</item>
<item>
<widget class="QLabel" name="LblDesc">
<property name="text">
<string/>
</property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<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="BtnGenerate">
<property name="text">
<string>&amp;Generate</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
+ <tabstops>
+ <tabstop>BtnGenerate</tabstop>
+ <tabstop>BtnCancel</tabstop>
+ <tabstop>TrReports</tabstop>
+ </tabstops>
<resources>
<include location="fred.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/trunk/dlgreportviewer.cpp b/trunk/dlgreportviewer.cpp
index a962057..30d5675 100644
--- a/trunk/dlgreportviewer.cpp
+++ b/trunk/dlgreportviewer.cpp
@@ -1,88 +1,107 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 "dlgreportviewer.h"
#include "ui_dlgreportviewer.h"
#include <QPrinter>
#include <QPrintDialog>
+#include <QFileDialog>
+#include <QTextDocument>
+#include <QTextDocumentWriter>
DlgReportViewer::DlgReportViewer(QString &report_data, QWidget *p_parent)
: QMainWindow(p_parent,Qt::Dialog | Qt::Popup), ui(new Ui::DlgReportViewer)
{
// Init local vars
ui->setupUi(this);
this->p_local_event_loop=NULL;
+ this->orig_report_data=report_data;
// Set report content
this->ui->WebView->setHtml(report_data);
// Set dialog title based on report content title
QString report_title=this->ui->WebView->title();
- if(report_title.isEmpty()) this->setWindowTitle("Report Viewer");
- else this->setWindowTitle(report_title.prepend("Report Viewer : "));
+ this->setWindowTitle("Report Viewer");
}
DlgReportViewer::~DlgReportViewer() {
delete ui;
if(this->p_local_event_loop!=NULL) this->p_local_event_loop->exit();
}
void DlgReportViewer::changeEvent(QEvent *e) {
QMainWindow::changeEvent(e);
switch(e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void DlgReportViewer::closeEvent(QCloseEvent *event) {
// Make sure we exit the local event loop on exit
if(this->p_local_event_loop!=NULL) {
this->p_local_event_loop->exit();
this->p_local_event_loop=NULL;
}
event->accept();
}
void DlgReportViewer::exec() {
// Create local event loop
this->p_local_event_loop=new QEventLoop(this);
// Show window and enter loop
this->show();
this->p_local_event_loop->exec();
}
void DlgReportViewer::on_action_Print_triggered() {
// Print report
QPrinter printer;
QPrintDialog *p_dlg_print=new QPrintDialog(&printer);
if(p_dlg_print->exec()==QDialog::Accepted) {
this->ui->WebView->print(&printer);
}
delete p_dlg_print;
}
void DlgReportViewer::on_action_Close_triggered() {
this->close();
}
+
+void DlgReportViewer::on_action_Save_triggered() {
+ QString filename=QFileDialog::getSaveFileName(this,
+ tr("Save report as"),
+ "",
+ "ODF file (*.odf)");
+ if(filename!="") {
+ QTextDocument *p_doc=new QTextDocument(this);
+ p_doc->setHtml(this->orig_report_data);
+ QTextDocumentWriter *p_doc_writer=new QTextDocumentWriter(filename);
+ p_doc_writer->setFormat(QByteArray("ODF"));
+ p_doc_writer->write(p_doc);
+ delete p_doc_writer;
+ delete p_doc;
+ }
+}
diff --git a/trunk/dlgreportviewer.h b/trunk/dlgreportviewer.h
index 88c182f..89fc1d5 100644
--- a/trunk/dlgreportviewer.h
+++ b/trunk/dlgreportviewer.h
@@ -1,56 +1,59 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 DLGREPORTVIEWER_H
#define DLGREPORTVIEWER_H
#include <QMainWindow>
#include <QEventLoop>
#include <QCloseEvent>
namespace Ui {
class DlgReportViewer;
}
class DlgReportViewer : public QMainWindow {
Q_OBJECT
public:
explicit DlgReportViewer(QString &report_data,
QWidget *p_parent=0);
~DlgReportViewer();
void exec();
protected:
void changeEvent(QEvent *e);
void closeEvent(QCloseEvent *event);
private slots:
void on_action_Print_triggered();
void on_action_Close_triggered();
-private:
+ void on_action_Save_triggered();
+
+ private:
Ui::DlgReportViewer *ui;
QEventLoop *p_local_event_loop;
+ QString orig_report_data;
};
#endif // DLGREPORTVIEWER_H
diff --git a/trunk/dlgreportviewer.ui b/trunk/dlgreportviewer.ui
index 8e90a91..20a6ff9 100644
--- a/trunk/dlgreportviewer.ui
+++ b/trunk/dlgreportviewer.ui
@@ -1,82 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgReportViewer</class>
<widget class="QMainWindow" name="DlgReportViewer">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>605</width>
<height>497</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<property name="windowIcon">
<iconset resource="fred.qrc">
<normaloff>:/icons/resources/fred.png</normaloff>:/icons/resources/fred.png</iconset>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QWebView" name="WebView">
- <property name="url">
+ <widget class="QWebView" name="WebView" native="true">
+ <property name="url" stdset="0">
<url>
<string>about:blank</string>
</url>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>605</width>
- <height>27</height>
+ <height>29</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
+ <addaction name="action_Save"/>
<addaction name="action_Print"/>
<addaction name="separator"/>
<addaction name="action_Close"/>
</widget>
<addaction name="menu_File"/>
</widget>
- <action name="action_Save">
- <property name="text">
- <string>&amp;Save</string>
- </property>
- </action>
<action name="action_Print">
<property name="text">
<string>&amp;Print</string>
</property>
</action>
<action name="action_Close">
<property name="text">
<string>&amp;Close</string>
</property>
</action>
+ <action name="action_Save">
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ </action>
</widget>
<customwidgets>
<customwidget>
<class>QWebView</class>
<extends>QWidget</extends>
<header>QtWebKit/QWebView</header>
</customwidget>
</customwidgets>
<resources>
<include location="fred.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/trunk/mainwindow.cpp b/trunk/mainwindow.cpp
index 7ddfe45..22d10e2 100644
--- a/trunk/mainwindow.cpp
+++ b/trunk/mainwindow.cpp
@@ -1,599 +1,637 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 <QDebug>
+
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dlgabout.h"
#include "dlgkeydetails.h"
#include "dlgreportchooser.h"
#include "dlgreportviewer.h"
#include "dlgsearch.h"
#include "compileinfo.h"
+/*******************************************************************************
+ * Public
+ ******************************************************************************/
+
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_node_tree_model_proxy=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_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_hex_edit_widget=new HexEditWidget();
// Add hexedit page to tab_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);
// 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_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
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();
*/
// Load report templates
this->p_reports=new Reports();
// Load reports from system wide include dir
this->p_reports->LoadReportTemplates(FRED_REPORT_TEMPLATE_DIR);
// Load user's report templates
this->p_reports->LoadReportTemplates(QDir::homePath()
.append(QDir::separator())
.append(".fred")
.append(QDir::separator())
.append("report_templates"));
// 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;
}
+/*******************************************************************************
+ * Private slots
+ ******************************************************************************/
+
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_proxy;
delete this->p_reg_node_tree_model;
this->p_reg_node_tree_model_proxy=NULL;
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_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);
// 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::on_ActionGenerateReport_triggered() {
+ DlgReportChooser dlg_repchooser(this->p_reports,
+ this->p_hive->HiveTypeToString(
+ this->p_hive->HiveType()),
+ this);
+ if(dlg_repchooser.exec()==QDialog::Accepted) {
+ QList<ReportTemplate*> selected_reports;
+
+ // Get selected report
+ selected_reports=dlg_repchooser.GetSelectedReports();
+ if(selected_reports.isEmpty()) return;
+
+ // Generate report(s)
+ QString report_result="";
+ if(this->p_reports->GenerateReport(this->p_hive,
+ selected_reports,
+ report_result,
+ false))
+ {
+ // Report generation was successfull, show reports
+ DlgReportViewer *p_dlg_report_view=new DlgReportViewer(report_result,
+ this);
+ p_dlg_report_view->exec();
+ delete p_dlg_report_view;
+ } else {
+ // TODO: Inform user
+ qDebug()<<"ERROR: "<<report_result;
+ }
+ }
+}
+
void MainWindow::SlotNodeTreeClicked(QModelIndex index) {
QString node_path;
if(!index.isValid()) return;
// Map proxy index to tree model index
index=this->p_reg_node_tree_model_proxy->mapToSource(index);
// 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_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::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_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::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_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::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++) {
indexes.replace(i,this->p_reg_node_tree_model_proxy->
mapFromSource(indexes.at(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);
}
+/*******************************************************************************
+ * Private
+ ******************************************************************************/
+
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::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 & proxy
this->p_reg_node_tree_model=new RegistryNodeTreeModel(this->p_hive);
this->p_reg_node_tree_model_proxy=new RegistryNodeTreeModelProxy(this);
//this->p_reg_node_tree_model_proxy->setDynamicSortFilter(true);
this->p_reg_node_tree_model_proxy->
setSourceModel(this->p_reg_node_tree_model);
this->p_node_tree->setModel(this->p_reg_node_tree_model_proxy);
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_hex_edit_widget->setEnabled(true);
this->UpdateWindowTitle(hive_file);
}
-
-void MainWindow::on_ActionGenerateReport_triggered() {
- DlgReportChooser dlg_repchooser(this->p_reports,this);
- if(dlg_repchooser.exec()==QDialog::Accepted) {
-
- }
-}
diff --git a/trunk/mainwindow.h b/trunk/mainwindow.h
index 38de0c8..e20238e 100644
--- a/trunk/mainwindow.h
+++ b/trunk/mainwindow.h
@@ -1,131 +1,130 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 "registrynodetreemodelproxy.h"
#include "registrykeytable.h"
#include "registrykeytablemodel.h"
#include "hexeditwidget.h"
//#include "datareporter.h"
#include "reports.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 on_ActionGenerateReport_triggered();
void SlotNodeTreeClicked(QModelIndex index);
void SlotKeyTableClicked(QModelIndex index);
void SlotKeyTableDoubleClicked(QModelIndex index);
// void SlotReportClicked();
void SlotSearchFinished();
void SlotSearchResultWidgetDoubleClicked(QModelIndex index);
void SlotTabCloseButtonClicked(int index);
- void on_ActionGenerateReport_triggered();
-
private:
Ui::MainWindow *ui;
ArgParser *p_args;
QString last_open_location;
RegistryHive *p_hive;
bool is_hive_open;
QByteArray selected_key_value;
QList<SearchResultWidget*> search_result_widgets;
// Models
RegistryNodeTreeModel *p_reg_node_tree_model;
RegistryNodeTreeModelProxy *p_reg_node_tree_model_proxy;
RegistryKeyTableModel *p_reg_key_table_model;
// Widgets etc...
RegistryNodeTree *p_node_tree;
RegistryKeyTable *p_key_table;
TabWidget *p_tab_widget;
HexEditWidget *p_hex_edit_widget;
QSplitter *p_horizontal_splitter;
QSplitter *p_vertical_splitter;
// DataReporter *p_data_reporter;
Reports *p_reports;
// Threads
ThreadSearch *p_search_thread;
/*
* CheckUserConfigDir
*
* Checks for and possibly creates the ~/.fred directory
*/
void CheckUserConfigDir();
/*
* UpdateWindowTitle
*
* Updates the window title
*/
void UpdateWindowTitle(QString filename="");
/*
* UpdateDataReporterMenu
*
*/
// void UpdateDataReporterMenu();
/*
* OpenHive
*
* Open a registry hive
*/
void OpenHive(QString hive_file);
};
#endif // MAINWINDOW_H
diff --git a/trunk/mainwindow.ui b/trunk/mainwindow.ui
index 4fe3b89..88d50fd 100644
--- a/trunk/mainwindow.ui
+++ b/trunk/mainwindow.ui
@@ -1,154 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
<height>317</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="windowIcon">
<iconset resource="fred.qrc">
<normaloff>:/icons/resources/fred.png</normaloff>:/icons/resources/fred.png</iconset>
</property>
<widget class="QWidget" name="MainWidget"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>508</width>
- <height>27</height>
+ <height>29</height>
</rect>
</property>
<widget class="QMenu" name="MenuFile">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="action_Open_hive"/>
<addaction name="action_Close_hive"/>
<addaction name="separator"/>
<addaction name="action_Quit"/>
</widget>
<widget class="QMenu" name="MenuHelp">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="actionAbout_Qt"/>
<addaction name="actionAbout_fred"/>
</widget>
<widget class="QMenu" name="MenuReports">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>&amp;Reports</string>
</property>
<addaction name="ActionGenerateReport"/>
<addaction name="ActionReloadReportTemplates"/>
</widget>
<widget class="QMenu" name="MenuEdit">
<property name="title">
<string>&amp;Edit</string>
</property>
<addaction name="ActionSearch"/>
<addaction name="separator"/>
<addaction name="ActionPreferences"/>
</widget>
<addaction name="MenuFile"/>
<addaction name="MenuEdit"/>
<addaction name="MenuReports"/>
<addaction name="MenuHelp"/>
</widget>
<widget class="QStatusBar" name="StatusBar"/>
<action name="action_Open_hive">
<property name="text">
<string>&amp;Open hive</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="action_Close_hive">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Close hive</string>
</property>
</action>
<action name="action_Quit">
<property name="text">
<string>&amp;Quit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="actionAbout_Qt">
<property name="text">
<string>About Qt</string>
</property>
</action>
<action name="actionAbout_fred">
<property name="text">
<string>About fred</string>
</property>
</action>
<action name="ActionSearch">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Search</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="ActionPreferences">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Preferences</string>
</property>
</action>
<action name="ActionGenerateReport">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Generate report</string>
</property>
</action>
<action name="ActionReloadReportTemplates">
<property name="text">
<string>Reload report templates</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="fred.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/trunk/registryhive.cpp b/trunk/registryhive.cpp
index fdf90bc..a11abea 100644
--- a/trunk/registryhive.cpp
+++ b/trunk/registryhive.cpp
@@ -1,628 +1,701 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 "registryhive.h"
#include <QStringList>
#include <QDateTime>
#include <stdlib.h>
#include <stdio.h>
// TODO: __WORDSIZE is not defined under mingw and I currently have no idea how
// to identify a 64bit windows
#ifndef __WORDSIZE
#define __WORDSIZE 32
#endif
#if __WORDSIZE == 64
#define EPOCH_DIFF 0x19DB1DED53E8000
#else
#define EPOCH_DIFF 0x19DB1DED53E8000LL
#endif
/*
* RegistryHive
*/
RegistryHive::RegistryHive(QObject *p_parent) : QObject(p_parent) {
this->erro_msg="";
this->is_error=false;
this->hive_file="";
this->p_hive=NULL;
this->is_hive_open=false;
}
/*
* ~RegistryHive
*/
RegistryHive::~RegistryHive() {
if(this->is_hive_open) this->Close();
}
/*
* Error
*/
bool RegistryHive::Error() {
return this->is_error;
}
/*
* GetErrorMsg
*/
QString RegistryHive::GetErrorMsg() {
QString msg=this->erro_msg;
this->erro_msg="";
this->is_error=false;
return msg;
}
/*
* Open
*/
bool RegistryHive::Open(QString file, bool read_only) {
if(this->is_hive_open) return false;
// Open hive file
this->p_hive=hivex_open(file.toAscii().constData(),
read_only ? 0 : HIVEX_OPEN_WRITE);
if(this->p_hive==NULL) return false;
// Set local vars
this->hive_file=file;
this->is_hive_open=true;
return true;
}
/*
* Close
*/
bool RegistryHive::Close(bool commit_changes) {
if(this->is_hive_open) {
if(commit_changes) {
// Commit changes before closing hive.
// TODO: Maybe it would be more secure to commit changes to a new file and
// then move it over the original one.
hivex_commit(this->p_hive,NULL,0);
}
// As hivex_close will _ALWAYS_ free the handle, we don't need the following
// values anymore
this->hive_file="";
this->is_hive_open=false;
// Close hive
if(hivex_close(this->p_hive)!=0) return false;
}
return true;
}
+/*
+ * Filename
+ */
QString RegistryHive::Filename() {
if(this->is_hive_open) return this->hive_file;
return QString();
}
+/*
+ * HiveType
+ */
+RegistryHive::teHiveType RegistryHive::HiveType() {
+ // Check for SYSTEM hive
+ if(this->PathExists("\\Select") && this->PathExists("\\MountedDevices"))
+ return RegistryHive::eHiveType_SYSTEM;
+ // Check for SOFTWARE hive
+ if(this->PathExists("\\Microsoft\\Windows\\CurrentVersion") &&
+ this->PathExists("\\Microsoft\\Windows NT\\CurrentVersion"))
+ return RegistryHive::eHiveType_SOFTWARE;
+ // Check for SAM
+ if(this->PathExists("SAM\\Domains\\Account\\Users"))
+ return RegistryHive::eHiveType_SAM;
+ // Check for SECURITY
+ if(this->PathExists("\\Policy\\Accounts") &&
+ this->PathExists("\\Policy\\PolAdtEv"))
+ return RegistryHive::eHiveType_SECURITY;
+ // Check for NTUSER.DAT
+ if(this->PathExists("\\Software\\Microsoft\\Windows\\CurrentVersion"))
+ return RegistryHive::eHiveType_NTUSER;
+ // Unknown hive
+ return RegistryHive::eHiveType_UNKNOWN;
+}
+
+/*
+ * HiveTypeToString
+ */
+QString RegistryHive::HiveTypeToString(teHiveType hive_type) {
+ switch(hive_type) {
+ case RegistryHive::eHiveType_SYSTEM:
+ return "SYSTEM";
+ break;
+ case RegistryHive::eHiveType_SOFTWARE:
+ return "SOFTWARE";
+ break;
+ case RegistryHive::eHiveType_SAM:
+ return "SAM";
+ break;
+ case RegistryHive::eHiveType_SECURITY:
+ return "SECURITY";
+ break;
+ case RegistryHive::eHiveType_NTUSER:
+ return "NTUSER";
+ break;
+ default:
+ return "UNKNOWN";
+ }
+}
+
/*
* GetNodes
*/
QMap<QString,int> RegistryHive::GetNodes(QString path) {
hive_node_h parent_node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QMap<QString,int>();
// Get and return nodes
return this->GetNodesHelper(parent_node);
}
/*
* GetNodes
*/
QMap<QString,int> RegistryHive::GetNodes(int parent_node) {
if(parent_node==0) {
this->SetError(tr("Invalid parent node handle specified!"));
return QMap<QString,int>();
}
// Get and return nodes
return this->GetNodesHelper(parent_node);
}
/*
* GetKeys
*/
QMap<QString,int> RegistryHive::GetKeys(QString path) {
hive_node_h parent_node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QMap<QString,int>();
// Get and return keys
return this->GetKeysHelper(parent_node);
}
/*
* GetKeys
*/
QMap<QString,int> RegistryHive::GetKeys(int parent_node) {
if(parent_node==0) {
this->SetError(tr("Invalid parent node handle specified!"));
return QMap<QString,int>();
}
// Get and return keys
return this->GetKeysHelper(parent_node);
}
/*
* GetKeyValue
*/
QByteArray RegistryHive::GetKeyValue(QString path,
QString key,
int *p_value_type,
size_t *p_value_len)
{
hive_node_h parent_node;
hive_value_h hive_key;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QByteArray();
// Get key handle
hive_key=hivex_node_get_value(this->p_hive,
parent_node,key.toAscii().constData());
if(hive_key==0) {
this->SetError(tr("Unable to get key handle!"));
*p_value_len=-1;
return QByteArray();
}
// Get and return key value
return this->GetKeyValueHelper(hive_key,p_value_type,p_value_len);
}
/*
* GetKeyValue
*/
QByteArray RegistryHive::GetKeyValue(int hive_key,
int *p_value_type,
size_t *p_value_len)
{
if(hive_key==0) {
this->SetError(tr("Invalid key handle specified!"));
*p_value_type=-1;
return QByteArray();
}
// Get and return key value
return this->GetKeyValueHelper(hive_key,p_value_type,p_value_len);
}
/*
* GetKeyModTime
*/
int64_t RegistryHive::GetNodeModTime(QString path) {
hive_node_h node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&node)) {
this->SetError(tr("Unable to get node handle!"));
return 0;
}
// Get and return node's last modification timestamp
return this->GetNodeModTime(node);
}
/*
* GetKeyModTime
*/
int64_t RegistryHive::GetNodeModTime(int node) {
if(node==0) {
this->SetError(tr("Invalid node handle specified!"));
return 0;
}
// Get and return key's last modification timestamp
return hivex_node_timestamp(this->p_hive,node);
}
/*
* KeyValueToString
*/
QString RegistryHive::KeyValueToString(QByteArray value, int value_type) {
QString ret="";
int i=0;
#define ToHexStr() { \
for(i=0;i<value.size();i++) { \
ret.append(QString().sprintf("%02X ",(uint8_t)(value.constData()[i]))); \
} \
ret.chop(1); \
}
switch(value_type) {
case hive_t_REG_NONE:
// Just a key without a value, but to be certain...
ToHexStr();
break;
case hive_t_REG_SZ:
// A Windows string (encoding is unknown, but often UTF16-LE)
// TODO: What happens if encoding is not UTF16-LE ??? Thx Billy!!!
ret=value.size() ? QString().fromUtf16((ushort*)(value.constData())) : "";
break;
case hive_t_REG_EXPAND_SZ:
// A Windows string that contains %env% (environment variable expansion)
ret=value.size() ? QString().fromUtf16((ushort*)(value.constData())) : "";
break;
case hive_t_REG_BINARY:
// A blob of binary
ToHexStr();
break;
case hive_t_REG_DWORD:
// DWORD (32 bit integer), little endian
ret=QString().sprintf("0x%08X",*(uint32_t*)value.constData());
break;
case hive_t_REG_DWORD_BIG_ENDIAN:
// DWORD (32 bit integer), big endian
ret=QString().sprintf("0x%08X",*(uint32_t*)value.constData());
break;
case hive_t_REG_LINK:
// Symbolic link to another part of the registry tree
ToHexStr();
break;
case hive_t_REG_MULTI_SZ:
// Multiple Windows strings.
// See http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx
ToHexStr();
break;
case hive_t_REG_RESOURCE_LIST:
// Resource list
ToHexStr();
break;
case hive_t_REG_FULL_RESOURCE_DESCRIPTOR:
// Resource descriptor
ToHexStr();
break;
case hive_t_REG_RESOURCE_REQUIREMENTS_LIST:
// Resouce requirements list
ToHexStr();
break;
case hive_t_REG_QWORD:
// QWORD (64 bit integer). Usually little endian.
ret=
QString("0x%1").arg((quint64)(*(uint64_t*)value.constData()),16,16,QChar('0'));
break;
default:
ToHexStr();
}
#undef ToHexStr
return ret;
}
/*
* KeyValueToString
*/
QString RegistryHive::KeyValueToString(QByteArray key_value,
QString format,
int offset,
int length,
bool little_endian)
{
int remaining_data_len;
const char *p_data;
QString ret="";
// Calculate how many bytes are remainig after specified offset
remaining_data_len=key_value.size()-offset;
if(!remaining_data_len>0) {
// Nothing to show
return QString();
}
// Get pointer to data at specified offset
p_data=key_value.constData();
p_data+=offset;
// TODO: This will fail on platforms with different endianness!
#define bswap_16(value) ((((value) & 0xff) << 8) | ((value) >> 8))
#define bswap_32(value) \
(((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
(uint32_t)bswap_16((uint16_t)((value) >> 16)))
#define bswap_64(value) \
(((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) << 32) | \
(uint64_t)bswap_32((uint32_t)((value) >> 32))) \
// ConvertFull name
if(format=="int8" && remaining_data_len>=1) {
ret=QString().sprintf("%d",*(int8_t*)p_data);
} else if(format=="uint8" && remaining_data_len>=1) {
ret=QString().sprintf("%u",*(uint8_t*)p_data);
} else if(format=="int16" && remaining_data_len>=2) {
int16_t val=*(int16_t*)p_data;
if(little_endian) ret=QString().sprintf("%d",val);
else ret=QString().sprintf("%d",bswap_16(val));
} else if(format=="uint16" && remaining_data_len>=2) {
uint16_t val=*(uint16_t*)p_data;
if(little_endian) ret=QString().sprintf("%u",val);
else ret=QString().sprintf("%u",bswap_16(val));
} else if(format=="int32" && remaining_data_len>=4) {
int32_t val=*(int32_t*)p_data;
if(little_endian) ret=QString().sprintf("%d",val);
else ret=QString().sprintf("%d",bswap_32(val));
} else if(format=="uint32" && remaining_data_len>=4) {
uint32_t val=*(uint32_t*)p_data;
if(little_endian) ret=QString().sprintf("%u",val);
else ret=QString().sprintf("%u",bswap_32(val));
} else if(format=="unixtime" && remaining_data_len>=4) {
uint32_t val=*(uint32_t*)p_data;
if(!little_endian) val=bswap_32(val);
if(val==0) {
ret="n/a";
} else {
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(val);
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
} else if(format=="int64" && remaining_data_len>=8) {
int64_t val=*(int64_t*)p_data;
if(little_endian) ret=QString("%1").arg(val);
else ret=QString("%1").arg((int64_t)bswap_64(val));
} else if(format=="uint64" && remaining_data_len>=8) {
uint64_t val=*(uint64_t*)p_data;
if(little_endian) ret=QString("%1").arg(val);
else ret=QString("%1").arg(bswap_64(val));
/*
// TODO: Check how one could implement this
} else if(format=="unixtime64" && remaining_data_len>=8) {
if(*(uint64_t*)p_data==0) {
ret="n/a";
} else {
uint64_t secs=*(uint64_t*)p_data;
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
// Set 32bit part of date/time
date_time.setTime_t(secs&0xFFFFFFFF);
// Now add high 32bit part of date/time
date_time.addSecs(secs>>32);
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
*/
} else if(format=="filetime" && remaining_data_len>=8) {
uint64_t val=*(uint64_t*)p_data;
if(!little_endian) val=bswap_64(val);
if(val==0) {
ret="n/a";
} else {
// TODO: Warn if >32bit
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(RegistryHive::FiletimeToUnixtime(val));
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
} else if(format=="ascii") {
// TODO: This fails bad if the string is not null terminated!! It might be
// wise checking for a null char here
ret=QString().fromAscii((char*)p_data,length);
} else if(format=="utf16" && remaining_data_len>=2) {
ret=QString().fromUtf16((ushort*)p_data,length);
} else {
// Unknown variant type or another error
return QString();
}
return ret;
}
/*
* KeyTypeToString
*/
QString RegistryHive::KeyTypeToString(int value_type) {
QString ret="";
switch(value_type) {
case hive_t_REG_NONE:
ret="REG_NONE";
break;
case hive_t_REG_SZ:
ret="REG_SZ";
break;
case hive_t_REG_EXPAND_SZ:
ret="REG_EXPAND_SZ";
break;
case hive_t_REG_BINARY:
ret="REG_BINARY";
break;
case hive_t_REG_DWORD:
ret="REG_DWORD";
break;
case hive_t_REG_DWORD_BIG_ENDIAN:
ret="REG_DWORD_BIG_ENDIAN";
break;
case hive_t_REG_LINK:
ret="REG_LINK";
break;
case hive_t_REG_MULTI_SZ:
ret="REG_MULTI_SZ";
break;
case hive_t_REG_RESOURCE_LIST:
ret="REG_RESOURCE_LIST";
break;
case hive_t_REG_FULL_RESOURCE_DESCRIPTOR:
ret="REG_FULL_RESOURCE_DESC";
break;
case hive_t_REG_RESOURCE_REQUIREMENTS_LIST:
ret="REG_RESOURCE_REQ_LIST";
break;
case hive_t_REG_QWORD:
ret="REG_QWORD";
break;
default:
ret=QString().sprintf("0x%08X",(uint32_t)value_type);
}
return ret;
}
/*
* FiletimeToUnixtime
*/
uint64_t RegistryHive::FiletimeToUnixtime(int64_t filetime) {
return (unsigned)((filetime-EPOCH_DIFF)/10000000);
}
/*
* SetError
*/
void RegistryHive::SetError(QString msg) {
this->erro_msg=msg;
this->is_error=true;
}
/*
* GetNodeHandle
*/
bool RegistryHive::GetNodeHandle(QString &path, hive_node_h *p_node) {
QStringList nodes;
int i=0;
// Get root node handle
*p_node=hivex_root(this->p_hive);
if(*p_node==0) {
this->SetError(tr("Unable to get root node!"));
return false;
}
if(path!="\\") {
// If we aren't listing the root node, we have to get a handle to the
// last node in the path. Split path into nodes
nodes=path.split('\\',QString::SkipEmptyParts);
// Iterate to the correct parent node
for(i=0;i<nodes.count();i++) {
// printf("Spotting node '%s'\n",nodes.value(i).toAscii().constData());
*p_node=hivex_node_get_child(this->p_hive,
*p_node,
nodes.value(i).toAscii().constData());
if(*p_node==0) {
this->SetError(tr("Unable to find node '%1'!").arg(nodes.value(i)));
return false;
}
}
}
return true;
}
/*
* GetNodesHelper
*/
QMap<QString,int> RegistryHive::GetNodesHelper(hive_node_h parent_node) {
QMap<QString,int> keys;
char *p_name;
int i=0;
// Get child nodes
hive_node_h *child_nodes=hivex_node_children(this->p_hive,parent_node);
if(child_nodes==NULL) {
this->SetError(
tr("Unable to enumerate child nodes!"));
return QMap<QString,int>();
}
// Build result
keys.clear();
i=0;
while(child_nodes[i]) {
p_name=hivex_node_name(this->p_hive,child_nodes[i]);
if(p_name==NULL) {
this->SetError(tr("Unable to get node name!"));
free(child_nodes);
return QMap<QString,int>();
}
keys.insert(QString(p_name),(int)child_nodes[i]);
free(p_name);
i++;
}
free(child_nodes);
return keys;
}
/*
* GetKeysHelper
*/
QMap<QString,int> RegistryHive::GetKeysHelper(hive_node_h parent_node) {
QMap<QString,int> keys;
char *p_name;
int i=0;
// Get child keys
hive_value_h *p_keys=hivex_node_values(this->p_hive,parent_node);
if(p_keys==NULL) {
this->SetError(
tr("Unable to enumerate child keys!"));
return QMap<QString,int>();
}
// Build result list
keys.clear();
i=0;
while(p_keys[i]) {
p_name=hivex_value_key(this->p_hive,p_keys[i]);
if(p_name==NULL) {
this->SetError(tr("Unable to get key name!"));
return QMap<QString,int>();
}
keys.insert(QString(p_name),p_keys[i]);
free(p_name);
i++;
}
free(p_keys);
return keys;
}
+/*
+ * GetKeyValueHelper
+ */
QByteArray RegistryHive::GetKeyValueHelper(hive_value_h hive_key,
int *p_value_type,
size_t *p_value_len)
{
QByteArray key_value;
char *p_key_value;
p_key_value=hivex_value_value(this->p_hive,
hive_key,
(hive_type*)p_value_type,
p_value_len);
if(p_key_value==NULL) {
this->SetError(tr("Unable to get key value!"));
*p_value_type=-1;
return QByteArray();
}
// Feed QByteArray and free p_key_value
key_value=QByteArray(p_key_value,*p_value_len);
free(p_key_value);
return key_value;
}
+
+/*
+ * PathExists
+ */
+bool RegistryHive::PathExists(QString path) {
+ bool ret;
+ hive_node_h node;
+
+ ret=this->GetNodeHandle(path,&node);
+ if(!ret || this->Error()) {
+ // Clear error and return false
+ this->GetErrorMsg();
+ return false;
+ }
+
+ return true;
+}
diff --git a/trunk/registryhive.h b/trunk/registryhive.h
index d6b65f2..e2f307f 100644
--- a/trunk/registryhive.h
+++ b/trunk/registryhive.h
@@ -1,83 +1,95 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 REGISTRYHIVE_H
#define REGISTRYHIVE_H
#include <QObject>
#include <QMap>
#include <hivex.h>
class RegistryHive : public QObject {
Q_OBJECT
public:
+ typedef enum eHiveType {
+ eHiveType_UNKNOWN=0,
+ eHiveType_SYSTEM,
+ eHiveType_SOFTWARE,
+ eHiveType_SAM,
+ eHiveType_SECURITY,
+ eHiveType_NTUSER
+ } teHiveType;
+
explicit RegistryHive(QObject *p_parent=0);
~RegistryHive();
bool Error();
QString GetErrorMsg();
bool Open(QString file, bool read_only=true);
bool Close(bool commit_changes=false);
QString Filename();
+ teHiveType HiveType();
+ QString HiveTypeToString(teHiveType hive_type);
QMap<QString,int> GetNodes(QString path="\\");
QMap<QString,int> GetNodes(int parent_node=0);
QMap<QString,int> GetKeys(QString path="\\");
QMap<QString,int> GetKeys(int parent_node=0);
QByteArray GetKeyValue(QString path,
QString key,
int *p_value_type,
size_t *p_value_len);
QByteArray GetKeyValue(int hive_key,
int *p_value_type,
size_t *p_value_len);
int64_t GetNodeModTime(QString path);
int64_t GetNodeModTime(int node);
static QString KeyValueToString(QByteArray value, int value_type);
static QString KeyValueToString(QByteArray value,
QString format,
int offset=0,
int length=0,
bool little_endian=true);
static QString KeyTypeToString(int value_type);
static uint64_t FiletimeToUnixtime(int64_t filetime);
private:
QString erro_msg;
bool is_error;
QString hive_file;
hive_h *p_hive;
bool is_hive_open;
void SetError(QString msg);
bool GetNodeHandle(QString &path, hive_node_h *p_node);
QMap<QString,int> GetNodesHelper(hive_node_h parent_node);
QMap<QString,int> GetKeysHelper(hive_node_h parent_node);
QByteArray GetKeyValueHelper(hive_value_h hive_key,
int *p_value_type,
size_t *p_value_len);
+ bool PathExists(QString path);
};
#endif // REGISTRYHIVE_H
diff --git a/trunk/reportengine.cpp b/trunk/reportengine.cpp
index 638b60f..8784e26 100644
--- a/trunk/reportengine.cpp
+++ b/trunk/reportengine.cpp
@@ -1,446 +1,518 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 "reportengine.h"
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QtDebug>
/*******************************************************************************
* Public
******************************************************************************/
ReportEngine::ReportEngine(RegistryHive *p_hive) : QScriptEngine() {
// Init vars
this->p_registry_hive=p_hive;
this->report_content="";
// Add our constants
this->globalObject().setProperty("ENGINE_API_VERSION",
FRED_REPORTENGINE_API_VERSION,
QScriptValue::ReadOnly|
QScriptValue::Undeletable);
/*
this->globalObject().setProperty("HIVE_FILE",
this->p_registry_hive->Filename(),
QScriptValue::ReadOnly|
QScriptValue::Undeletable);
*/
// Add our types to engine
qScriptRegisterMetaType<s_RegistryKeyValue>(this,
this->RegistryKeyValueToScript,
this->RegistryKeyValueFromScript);
this->p_type_byte_array=new ByteArray(this);
this->globalObject().setProperty("ByteArray",
this->p_type_byte_array->constructor());
// Add our functions
// print
QScriptValue func_print=this->newFunction(this->Print);
this->globalObject().setProperty("print",func_print);
// println
QScriptValue func_println=this->newFunction(this->PrintLn);
this->globalObject().setProperty("println",func_println);
- // GetRegistryNodes
- QScriptValue func_get_nodes=this->newFunction(this->GetRegistryNodes,1);
- func_get_nodes.setData(this->newQObject(this->p_registry_hive));
- this->globalObject().setProperty("GetRegistryNodes",func_get_nodes);
- // GetRegistryKeys
- QScriptValue func_get_keys=this->newFunction(this->GetRegistryKeys,1);
- func_get_keys.setData(this->newQObject(this->p_registry_hive));
- this->globalObject().setProperty("GetRegistryKeys",func_get_keys);
- // GetRegistryKeyValue
- QScriptValue func_get_key_value=this->newFunction(this->GetRegistryKeyValue,
- 2);
- func_get_key_value.setData(this->newQObject(this->p_registry_hive));
- this->globalObject().setProperty("GetRegistryKeyValue",func_get_key_value);
- // GetRegistryNodeModTime
- QScriptValue func_get_node_modt=
- this->newFunction(this->GetRegistryNodeModTime,1);
- func_get_node_modt.setData(this->newQObject(this->p_registry_hive));
- this->globalObject().setProperty("GetRegistryNodeModTime",func_get_node_modt);
+
// RegistryKeyValueToString
QScriptValue func_value_to_string=
this->newFunction(this->RegistryKeyValueToString,2);
this->globalObject().setProperty("RegistryKeyValueToString",
func_value_to_string);
// RegistryKeyValueToVariant
QScriptValue func_value_to_variant=
this->newFunction(this->RegistryKeyValueToVariant);
this->globalObject().setProperty("RegistryKeyValueToVariant",
func_value_to_variant);
// RegistryKeyTypeToString
QScriptValue func_type_to_string=
this->newFunction(this->RegistryKeyTypeToString,1);
this->globalObject().setProperty("RegistryKeyTypeToString",
func_type_to_string);
}
ReportEngine::~ReportEngine() {
delete this->p_type_byte_array;
}
/*
* GetReportTemplateInfo
*/
QMap<QString,QVariant> ReportEngine::GetReportTemplateInfo(QString file) {
- // Open report template file
- QFile template_file(file);
- if(!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ // Read template file
+ QString report_code;
+ if(!this->GetReportTemplateFileContents(file,report_code)) {
QMap<QString,QVariant> error_msg;
- error_msg["error"]=QString("Couldn't open report template file '%1'!")
- .arg(file);
+ error_msg["error"]=report_code;
return error_msg;
}
- // Read template file and close it
- QString report_code;
- QTextStream in(&template_file);
- while(!in.atEnd()) report_code.append(in.readLine()).append("\n");
- template_file.close();
-
// Evaluate report template script
QScriptValue report_result=this->evaluate(report_code,file);
if (report_result.isError() || this->hasUncaughtException()) {
QMap<QString,QVariant> error_msg;
error_msg["error"]=QString("File: %1\n Line: %2\nError: %3")
.arg(file)
.arg(report_result.property("lineNumber").toInt32())
.arg(report_result.toString());
return error_msg;
}
// Try to call the fred_report_info script function and return result
QScriptValue fred_report_info_func=
this->globalObject().property("fred_report_info");
if(!fred_report_info_func.isFunction()) {
QMap<QString,QVariant> error_msg;
error_msg["error"]=
QString("Report template '%1' does not have a fred_report_info function!")
.arg(file)
.arg(report_result.property("lineNumber").toInt32())
.arg(report_result.toString());
return error_msg;
}
QScriptValue fred_report_info_res=fred_report_info_func.call();
// TODO: Maybe do more checking on return value
return fred_report_info_res.toVariant().toMap();
}
+/*
+ * GenerateReport
+ */
+bool ReportEngine::GenerateReport(RegistryHive *p_hive,
+ QString report_file,
+ QString &report_result,
+ bool console_mode)
+{
+ // Clear internal buffer
+ this->report_content.clear();
+
+ // Update exported functions
+ this->UpdateExportedFunctions(p_hive);
+
+ // Read template file
+ QString report_code;
+ if(!this->GetReportTemplateFileContents(report_file,report_code)) {
+ report_result=report_code;
+ return false;
+ }
+
+ // Evaluate report template script
+ QScriptValue script_result=this->evaluate(report_code,report_file);
+ if (script_result.isError() || this->hasUncaughtException()) {
+ script_result=QString("File: %1\n Line: %2\nError: %3")
+ .arg(report_file)
+ .arg(script_result.property("lineNumber").toInt32())
+ .arg(script_result.toString());
+ return false;
+ }
+
+ // Try to call the fred_report_html script function and return result
+ QScriptValue fred_report_html_func=
+ this->globalObject().property("fred_report_html");
+ if(!fred_report_html_func.isFunction()) {
+ report_result=
+ QString("Report template '%1' does not have a fred_report_info function!")
+ .arg(report_file)
+ .arg(script_result.property("lineNumber").toInt32())
+ .arg(script_result.toString());
+ return false;
+ }
+ QScriptValue fred_report_html_res=fred_report_html_func.call();
+
+ // TODO: Maybe do more checking on return value
+ report_result=this->report_content;
+ return true;
+}
+
/*******************************************************************************
* Public Slots
******************************************************************************/
/*******************************************************************************
* Private
******************************************************************************/
/*
* Print
*/
QScriptValue ReportEngine::Print(QScriptContext *context,
QScriptEngine *engine)
{
int i;
QString content;
// Append all arguments to content
for(i=0;i<context->argumentCount();++i) {
//if(i>0) content.append(" ");
content.append(context->argument(i).toString());
}
qobject_cast<ReportEngine*>(engine)->report_content.append(content);
return engine->undefinedValue();
}
/*
* PrintLn
*/
QScriptValue ReportEngine::PrintLn(QScriptContext *context,
QScriptEngine *engine)
{
int i;
QString content;
// Append all arguments to content
for(i=0;i<context->argumentCount();++i) {
//if(i>0) content.append(" ");
content.append(context->argument(i).toString());
}
qobject_cast<ReportEngine*>(engine)->
report_content.append(content).append("\n");
return engine->undefinedValue();
}
/*
* GetRegistryNodes
*/
QScriptValue ReportEngine::GetRegistryNodes(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QMap<QString,int> nodes;
QScriptValue ret_nodes;
int ii=0;
// This function needs one argument, parent node path
if(context->argumentCount()!=1) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
// Get nodes
nodes=p_hive->GetNodes(context->argument(0).toString());
if(p_hive->Error()) {
// Clear error state
p_hive->GetErrorMsg();
return engine->undefinedValue();
}
// Build script array
ret_nodes=engine->newArray(nodes.count());
QMapIterator<QString,int> i(nodes);
while(i.hasNext()) {
i.next();
ret_nodes.setProperty(ii++,QScriptValue(i.key()));
}
return ret_nodes;
}
/*
* GetRegistryKeys
*/
QScriptValue ReportEngine::GetRegistryKeys(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QMap<QString,int> keys;
QScriptValue ret_keys;
int ii=0;
// This function needs one argument, parent node path
if(context->argumentCount()!=1) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
// Get keys
keys=p_hive->GetKeys(context->argument(0).toString());
if(p_hive->Error()) {
// Clear error state
p_hive->GetErrorMsg();
return engine->undefinedValue();
}
// Build script array
ret_keys=engine->newArray(keys.count());
QMapIterator<QString,int> i(keys);
while(i.hasNext()) {
i.next();
ret_keys.setProperty(ii++,QScriptValue(i.key()));
}
return ret_keys;
}
/*
* RegistryKeyValueToScript
*/
QScriptValue ReportEngine::RegistryKeyValueToScript(QScriptEngine *engine,
const s_RegistryKeyValue &s)
{
QScriptValue obj=engine->newObject();
obj.setProperty("type",s.type);
obj.setProperty("length",s.length);
ByteArray *p_byte_array=new ByteArray(engine);
obj.setProperty("value",p_byte_array->newInstance(s.value));
return obj;
}
/*
* RegistryKeyValueFromScriptValue
*/
void ReportEngine::RegistryKeyValueFromScript(const QScriptValue &obj,
s_RegistryKeyValue &s)
{
s.type=obj.property("type").toInt32();
s.length=obj.property("length").toInt32();
// TODO: Don't know if this works, but it probably does ;)
s.value=qvariant_cast<QByteArray>(obj.property("value").data().toVariant());
}
/*
* GetRegistryKeyValue
*/
QScriptValue ReportEngine::GetRegistryKeyValue(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QByteArray key_value;
int key_type=0;
size_t key_length=0;
s_RegistryKeyValue script_key_value;
// This function needs two arguments, key path and key name
if(context->argumentCount()!=2) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
// Get key value
key_value=p_hive->GetKeyValue(context->argument(0).toString(),
context->argument(1).toString(),
&key_type,
&key_length);
if(p_hive->Error()) {
// Get error message to clear error state
p_hive->GetErrorMsg();
// printf("\nError: %s\n",p_hive->GetErrorMsg().toAscii().constData());
return engine->undefinedValue();
}
// Save key value to s_RegistryKeyValue struct
script_key_value.type=key_type;
script_key_value.length=key_length;
script_key_value.value=key_value;
return ReportEngine::RegistryKeyValueToScript(engine,script_key_value);
}
/*
* RegistryKeyValueToString
*/
QScriptValue ReportEngine::RegistryKeyValueToString(QScriptContext *context,
QScriptEngine *engine)
{
QByteArray key_value;
QString ret="";
// This function needs two arguments, key value and value type
if(context->argumentCount()!=2) return engine->undefinedValue();
// Cast ByteArray argument to QByteArray and convert
key_value=qvariant_cast<QByteArray>(context->argument(0).data().toVariant());
ret=RegistryHive::KeyValueToString(key_value,
context->argument(1).toInt32());
return engine->newVariant(ret);
}
/*
* RegistryKeyValueToVariant
*/
QScriptValue ReportEngine::RegistryKeyValueToVariant(QScriptContext *context,
QScriptEngine *engine)
{
int offset=0;
int length=-1;
bool little_endian=true;
QByteArray key_value;
QString format="";
QString ret="";
// This function needs at least two arguments, key value and variant type,
// and may have three optional arguments, offset, length and little_endian
if(context->argumentCount()<2 || context->argumentCount()>5) {
return engine->undefinedValue();
}
if(context->argumentCount()==3) {
offset=context->argument(2).toInt32();
}
if(context->argumentCount()==4) {
offset=context->argument(2).toInt32();
length=context->argument(3).toInt32();
}
if(context->argumentCount()==5) {
offset=context->argument(2).toInt32();
length=context->argument(3).toInt32();
little_endian=(context->argument(4).toInt32()==1);
}
// Cast ByteArray argument to QByteArray
key_value=qvariant_cast<QByteArray>(context->argument(0).data().toVariant());
format=context->argument(1).toString();
ret=RegistryHive::KeyValueToString(key_value,format,offset,length,little_endian);
return engine->newVariant(ret);
}
/*
* RegistryKeyTypeToString
*/
QScriptValue ReportEngine::RegistryKeyTypeToString(QScriptContext *context,
QScriptEngine *engine)
{
QString ret="";
// This function needs one argument, key type
if(context->argumentCount()!=1) return engine->undefinedValue();
ret=RegistryHive::KeyTypeToString(context->argument(0).toInt32());
return engine->newVariant(ret);
}
/*
* GetRegistryNodeModTime
*/
QScriptValue ReportEngine::GetRegistryNodeModTime(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
int64_t mod_time=0;
// This function needs one argument, node path
if(context->argumentCount()!=1) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
mod_time=p_hive->GetNodeModTime(context->argument(0).toString());
if(p_hive->Error()) {
// Get error message to clear error state
p_hive->GetErrorMsg();
return engine->undefinedValue();
}
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(RegistryHive::FiletimeToUnixtime(mod_time));
return engine->newVariant(date_time.toString("yyyy/MM/dd hh:mm:ss"));
}
+
+/*
+ * GetReportTemplateFileContents
+ */
+bool ReportEngine::GetReportTemplateFileContents(QString file,
+ QString &contents)
+{
+ // Open report template file
+ QFile template_file(file);
+ if(!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ contents=QString("Couldn't open report template file '%1'!").arg(file);
+ return false;
+ }
+
+ // Read template file and close it
+ contents.clear();
+ QTextStream in(&template_file);
+ while(!in.atEnd()) contents.append(in.readLine()).append("\n");
+ template_file.close();
+
+ return true;
+}
+
+/*
+ * UpdateExportedFunctions
+ */
+void ReportEngine::UpdateExportedFunctions(RegistryHive *p_hive) {
+ this->p_registry_hive=p_hive;
+ // GetRegistryNodes
+ QScriptValue func_get_nodes=this->newFunction(this->GetRegistryNodes,1);
+ func_get_nodes.setData(this->newQObject(this->p_registry_hive));
+ this->globalObject().setProperty("GetRegistryNodes",func_get_nodes);
+ // GetRegistryKeys
+ QScriptValue func_get_keys=this->newFunction(this->GetRegistryKeys,1);
+ func_get_keys.setData(this->newQObject(this->p_registry_hive));
+ this->globalObject().setProperty("GetRegistryKeys",func_get_keys);
+ // GetRegistryKeyValue
+ QScriptValue func_get_key_value=this->newFunction(this->GetRegistryKeyValue,
+ 2);
+ func_get_key_value.setData(this->newQObject(this->p_registry_hive));
+ this->globalObject().setProperty("GetRegistryKeyValue",func_get_key_value);
+ // GetRegistryNodeModTime
+ QScriptValue func_get_node_modt=
+ this->newFunction(this->GetRegistryNodeModTime,1);
+ func_get_node_modt.setData(this->newQObject(this->p_registry_hive));
+ this->globalObject().setProperty("GetRegistryNodeModTime",func_get_node_modt);
+}
diff --git a/trunk/reportengine.h b/trunk/reportengine.h
index b1bfd10..a66e151 100644
--- a/trunk/reportengine.h
+++ b/trunk/reportengine.h
@@ -1,81 +1,89 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 REPORTENGINE_H
#define REPORTENGINE_H
#include <QObject>
#include <QtScript/QScriptEngine>
#include <QtScript/QScriptValue>
#include <QtScript/QScriptContext>
#include <QString>
#include <QVariant>
#include <QMap>
#include "registryhive.h"
#include "qtscript_types/bytearray.h"
#define FRED_REPORTENGINE_API_VERSION 2
class ReportEngine : public QScriptEngine {
Q_OBJECT
public:
struct s_RegistryKeyValue {
int type;
int length;
QByteArray value;
};
RegistryHive *p_registry_hive;
QString report_content;
ReportEngine(RegistryHive *p_hive);
~ReportEngine();
+
QMap<QString,QVariant> GetReportTemplateInfo(QString file);
+ bool GenerateReport(RegistryHive *p_hive,
+ QString report_file,
+ QString &report_result,
+ bool console_mode=true);
private:
ByteArray *p_type_byte_array;
static QScriptValue Print(QScriptContext *context, QScriptEngine *engine);
static QScriptValue PrintLn(QScriptContext *context, QScriptEngine *engine);
static QScriptValue GetRegistryNodes(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue GetRegistryKeys(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToScript(QScriptEngine *engine,
const s_RegistryKeyValue &s);
static void RegistryKeyValueFromScript(const QScriptValue &obj,
s_RegistryKeyValue &s);
static QScriptValue GetRegistryKeyValue(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToString(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToVariant(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyTypeToString(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue GetRegistryNodeModTime(QScriptContext *context,
QScriptEngine *engine);
+
+ bool GetReportTemplateFileContents(QString file, QString &contents);
+ void UpdateExportedFunctions(RegistryHive *p_hive);
};
Q_DECLARE_METATYPE(ReportEngine::s_RegistryKeyValue)
#endif // REPORTENGINE_H
diff --git a/trunk/reports.cpp b/trunk/reports.cpp
index 2f673e8..15a5b43 100644
--- a/trunk/reports.cpp
+++ b/trunk/reports.cpp
@@ -1,161 +1,183 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 "reports.h"
#include <QListIterator>
#include <QDir>
#include <QMap>
#include <QDebug>
+/*******************************************************************************
+ * Public
+ ******************************************************************************/
+
Reports::Reports() {
this->p_engine=new ReportEngine(NULL);
this->report_templates.clear();
}
Reports::~Reports() {
qDeleteAll(this->report_templates);
delete this->p_engine;
}
void Reports::LoadReportTemplates(QString dir) {
QString report_template="";
QString report_category,report_name,report_author,report_desc,report_hive;
bool found;
int i;
ReportTemplate *p_report;
// Get all template files in report_templates directory
QDir report_dir(dir);
QStringList found_report_templates=report_dir.
entryList(QStringList()<<"*.qs");
QListIterator<QString> it(found_report_templates);
while(it.hasNext()) {
// Build path to template file
report_template=report_dir.path();
report_template.append(QDir::separator());
report_template.append(it.next());
// Get report info
QMap<QString,QVariant> report_info=this->p_engine->
GetReportTemplateInfo(report_template);
if(report_info.contains("error")) {
// TODO: Inform user
qDebug()<<"Error in report '"<<report_template<<"'\n"
<<report_info["error"].toString();
continue;
}
// Make sure report is compatible with current API
if(report_info.value("fred_api",QVariant(0)).toInt()>
FRED_REPORTENGINE_API_VERSION)
{
// TODO: Inform user
qDebug()<<"Report '"<<report_template<<"' is not compatible with current API!";
}
// Extract info values. If a value isn't present, it will be set to ""
report_category=report_info.value("report_cat").toString();
report_name=report_info.value("report_name").toString();
report_author=report_info.value("report_author").toString();
report_desc=report_info.value("report_desc").toString();
- report_hive=report_info.value("report_hive").toString();
+ report_hive=report_info.value("hive").toString().toUpper();
// Check if a report with the same category and name was already added
found=false;
for(i=0;i<this->report_templates.count();i++) {
if(this->report_templates.at(i)->Category()==report_category &&
this->report_templates.at(i)->Name()==report_name)
{
found=true;
break;
}
}
// Add to or update report template list
if(!found) {
// Add report to list
p_report=new ReportTemplate(report_template,
report_category,
report_name,
report_author,
report_desc,
report_hive);
this->report_templates.append(p_report);
} else {
// Update report entry
p_report=this->report_templates.at(i);
p_report->SetFile(report_template);
p_report->SetAuthor(report_author);
p_report->SetDescription(report_desc);
}
}
}
QStringList Reports::GetAvailableReportCategories() {
QStringList ret;
QString cat;
int i;
ret.clear();
for(i=0;i<this->report_templates.count();i++) {
cat=this->report_templates.value(i)->Category();
if(!ret.contains(cat)) ret.append(cat);
}
ret.sort();
return ret;
}
-QStringList Reports::GetAvailableReports(QString category) {
- QStringList ret;
+QList<ReportTemplate*> Reports::GetAvailableReports(QString category) {
+ QList<ReportTemplate*> ret;
QString cat;
int i=0;
ret.clear();
for(i=0;i<this->report_templates.count();i++) {
cat=this->report_templates.value(i)->Category();
- if(cat==category) ret.append(this->report_templates.value(i)->Name());
+ if(cat==category) ret.append(this->report_templates.value(i));
}
- ret.sort();
return ret;
}
-QMap<QString,QString> Reports::GetReportInfo(QString category, QString name) {
- QMap<QString,QString> ret;
- int i=0;
+bool Reports::GenerateReport(RegistryHive *p_hive,
+ QString report_file,
+ QString &report_result,
+ bool console_mode)
+{
+ return this->p_engine->GenerateReport(p_hive,
+ report_file,
+ report_result,
+ console_mode);
+}
- // Search requested report
- for(i=0;i<this->report_templates.count();i++) {
- if(this->report_templates.value(i)->Category()==category &&
- this->report_templates.value(i)->Name()==name)
- {
- ret["report_author"]=this->report_templates.value(i)->Author();
- ret["report_desc"]=this->report_templates.value(i)->Description();
- break;
- }
+bool Reports::GenerateReport(RegistryHive *p_hive,
+ QList<ReportTemplate*> report_list,
+ QString &report_result,
+ bool console_mode)
+{
+ bool ret;
+ QString res;
+
+ QListIterator<ReportTemplate*> rep_it(report_list);
+ while(rep_it.hasNext()) {
+ res="";
+ ret=this->GenerateReport(p_hive,
+ rep_it.next()->File(),
+ res,
+ console_mode);
+ if(ret) report_result.append(res);
+ // TODO: Inform user something didn't work
}
- return ret;
+ return true;
}
+
+/*******************************************************************************
+ * Private
+ ******************************************************************************/
diff --git a/trunk/reports.h b/trunk/reports.h
index 397b89e..13fcba3 100644
--- a/trunk/reports.h
+++ b/trunk/reports.h
@@ -1,54 +1,53 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 REPORTS_H
#define REPORTS_H
#include "reporttemplate.h"
#include "reportengine.h"
#include <QList>
-#include <QMap>
#include <QString>
+#include <QStringList>
class Reports {
public:
Reports();
~Reports();
void LoadReportTemplates(QString dir);
QStringList GetAvailableReportCategories();
- QStringList GetAvailableReports(QString category);
- QMap<QString,QString> GetReportInfo(QString category, QString name);
+ QList<ReportTemplate*> GetAvailableReports(QString category);
-/*
- QString GenerateReport(RegistryHive *p_hive,
- QString report_category,
- QString report_name);
- QString GenerateReport(RegistryHive *p_hive,
- QString report_template,
- bool console_mode=false);
-*/
+ bool GenerateReport(RegistryHive *p_hive,
+ QString report_file,
+ QString &report_result,
+ bool console_mode=false);
+ bool GenerateReport(RegistryHive *p_hive,
+ QList<ReportTemplate*> report_list,
+ QString &report_result,
+ bool console_mode=false);
private:
QList<ReportTemplate*> report_templates;
ReportEngine *p_engine;
};
#endif // REPORTS_H
diff --git a/trunk/reporttemplate.h b/trunk/reporttemplate.h
index 2a3fba1..84ff695 100644
--- a/trunk/reporttemplate.h
+++ b/trunk/reporttemplate.h
@@ -1,58 +1,61 @@
/*******************************************************************************
* fred Copyright (c) 2011-2013 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 REPORTTEMPLATE_H
#define REPORTTEMPLATE_H
+#include <QMetaType>
#include <QString>
class ReportTemplate {
public:
ReportTemplate(QString report_template_file,
QString report_category,
QString report_name,
QString report_author,
QString report_desc,
QString report_hive);
void SetFile(QString new_file);
void SetCategory(QString new_category);
void SetName(QString new_name);
void SetAuthor(QString new_author);
void SetDescription(QString new_desc);
void SetHive(QString new_hive);
QString File();
QString Category();
QString Name();
QString Author();
QString Description();
QString Hive();
private:
QString template_file;
QString category;
QString name;
QString author;
QString description;
QString hive;
};
+Q_DECLARE_METATYPE(ReportTemplate*)
+
#endif // REPORTTEMPLATE_H

File Metadata

Mime Type
text/x-diff
Expires
Mon, Dec 23, 5:22 AM (49 m, 43 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1176854
Default Alt Text
(118 KB)

Event Timeline