Page MenuHomePhabricator

No OneTemporary

Size
144 KB
Referenced Files
None
Subscribers
None
diff --git a/trunk/datareporter.cpp b/trunk/datareporter.cpp
index b994245..cdea365 100644
--- a/trunk/datareporter.cpp
+++ b/trunk/datareporter.cpp
@@ -1,137 +1,155 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 <QDir>
-
#include "datareporter.h"
-#include "reporttemplatexmlhandler.h"
+
+#include <QDir>
+#include <QTextStream>
+#include <QtScript/QScriptEngine>
+#include <QMessageBox>
DataReporter::DataReporter() {
this->report_templates.clear();
+ //this->p_report_engine=new DataReporterEngine();
}
DataReporter::~DataReporter() {
+ //delete this->p_report_engine;
qDeleteAll(this->report_templates);
}
void DataReporter::LoadReportTemplates() {
QString report_template="";
- QXmlSimpleReader xml_parser;
int i=0;
+ QString report_category="";
+ QString report_name="";
ReportTemplate *p_report;
+ // Get all template files in report_templates directory
QDir report_dir("../trunk/report_templates/");
- QStringList found_report_templates=report_dir.entryList(QStringList()<<"*.fred");
+ QStringList found_report_templates=report_dir.
+ entryList(QStringList()<<"*.js");
for(i=0;i<found_report_templates.count();i++) {
+ // Build complete path to template file
report_template=report_dir.path();
report_template.append(QDir::separator());
report_template.append(found_report_templates.value(i));
- QFile *p_report_template_file=new QFile(report_template);
- QXmlInputSource *p_xml_file=new QXmlInputSource(p_report_template_file);
- ReportTemplateXmlHandler *p_report_handler=new ReportTemplateXmlHandler();
-
- xml_parser.setContentHandler(p_report_handler);
- xml_parser.setErrorHandler(p_report_handler);
- if(xml_parser.parse(p_xml_file)) {
- p_report=new ReportTemplate(p_report_handler->GetReportCategory(),
- p_report_handler->GetReportName(),
- report_template);
- this->report_templates.append(p_report);
- } else {
- qDebug("Error loading template");
- }
-
- delete p_report_handler;
- delete p_xml_file;
- delete p_report_template_file;
+ // Extract report category and name from file name (<category>_<name>.js)
+ report_category=found_report_templates.value(i).left(
+ found_report_templates.value(i).indexOf("_"));
+ report_name=found_report_templates.value(i).mid(
+ found_report_templates.value(i).indexOf("_")+1);
+ report_name=report_name.left(report_name.lastIndexOf(".")-1);
+
+ // Add report to list
+ p_report=new ReportTemplate(report_category,
+ report_name,
+ report_template);
+ this->report_templates.append(p_report);
}
}
QStringList DataReporter::GetAvailableReportCategories() {
QStringList 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(!ret.contains(cat)) ret.append(cat);
}
-
ret.sort();
return ret;
}
QStringList DataReporter::GetAvailableReports(QString category) {
QStringList 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());
}
-
ret.sort();
return ret;
}
-QString DataReporter::GenerateReport(hive_h *hhive,
+QString DataReporter::GenerateReport(RegistryHive *p_hive,
QString report_category,
QString report_name)
{
- QString ret=QString();
int i=0;
- QXmlSimpleReader xml_parser;
ReportTemplate *p_report;
+ DataReporterEngine engine(p_hive);
+ QString report_code;
+ //ReportData report_data;
for(i=0;i<this->report_templates.count();i++) {
p_report=this->report_templates.value(i);
if(p_report->Category()!=report_category || p_report->Name()!=report_name) {
continue;
}
- QFile *p_template_file=new QFile(p_report->File());
- QXmlInputSource *p_xml_input=new QXmlInputSource(p_template_file);
- ReportTemplateXmlHandler *p_report_handler=
- new ReportTemplateXmlHandler(hhive,false);
-
- xml_parser.setContentHandler(p_report_handler);
- xml_parser.setErrorHandler(p_report_handler);
- if(xml_parser.parse(p_xml_input)) {
- ret=p_report_handler->ReportData();
- } else {
- qDebug("Error loading template");
+ QScriptValue hive_value=engine.newQObject(p_hive);
+ engine.globalObject().setProperty("RegistryHive",hive_value);
+ //QScriptValue return_value=engine.newQObject(&report_data);
+ //engine.globalObject().setProperty("ReportData",return_value);
+
+ // Open report template
+ QFile template_file(p_report->File());
+ if(!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qDebug("Couldn't open file '%s'",p_report->File().toAscii().constData());
+ break;
+ }
+ // Read template file
+ QTextStream in(&template_file);
+ while(!in.atEnd()) {
+ report_code.append(in.readLine());
}
+ // Close report template file
+ template_file.close();
+
+ QScriptValue report_result=engine.evaluate(report_code,p_report->File());
+
+ if (report_result.isError()) {
+ QMessageBox::critical(0,
+ "Hello Script",
+ QString::fromLatin1("%0:%1: %2")
+ .arg(p_report->File())
+ .arg(report_result.property("lineNumber").toInt32())
+ .arg(report_result.toString()));
+ break;
+ }
+
- delete p_report_handler;
- delete p_xml_input;
- delete p_template_file;
+ if(engine.hasUncaughtException()) qDebug("Exception in processing!");
break;
}
- return ret;
+ return engine.report_content;
}
diff --git a/trunk/datareporter.h b/trunk/datareporter.h
index 92f06c2..2bac96f 100644
--- a/trunk/datareporter.h
+++ b/trunk/datareporter.h
@@ -1,47 +1,48 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 DATAREPORTER_H
#define DATAREPORTER_H
#include <QList>
-#include <hivex.h>
-
#include "reporttemplate.h"
+#include "datareporterengine.h"
+#include "registryhive.h"
class DataReporter {
public:
DataReporter();
~DataReporter();
void LoadReportTemplates();
QStringList GetAvailableReportCategories();
QStringList GetAvailableReports(QString category);
- QString GenerateReport(hive_h *hhive,
+ QString GenerateReport(RegistryHive *p_hive,
QString report_category,
QString report_name);
private:
QList<ReportTemplate*> report_templates;
+ //DataReporterEngine *p_report_engine;
};
#endif // DATAREPORTER_H
diff --git a/trunk/datareporterengine.cpp b/trunk/datareporterengine.cpp
index 6a89589..0543710 100644
--- a/trunk/datareporterengine.cpp
+++ b/trunk/datareporterengine.cpp
@@ -1,7 +1,196 @@
+/*******************************************************************************
+* fred Copyright (c) 2011 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 "datareporterengine.h"
-DataReporterEngine::DataReporterEngine(QObject *p_parent)
- : QScriptEngine(p_parent)
+#include <QString>
+
+DataReporterEngine::DataReporterEngine(RegistryHive *p_hive) : QScriptEngine() {
+ // Init vars
+ this->p_registry_hive=p_hive;
+ this->report_content="";
+
+ // 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);
+ // GetRegistryKeyValue
+ QScriptValue func_get_key_value=this->newFunction(this->GetRegistryKeyValue);
+ func_get_key_value.setData(this->newQObject(this->p_registry_hive));
+ this->globalObject().setProperty("GetRegistryKeyValue",func_get_key_value);
+ // RegistryKeyValueToString
+ QScriptValue func_value_to_string=
+ this->newFunction(this->RegistryKeyValueToString);
+ this->globalObject().setProperty("RegistryKeyValueToString",
+ func_value_to_string);
+ // RegistryKeyTypeToString
+ QScriptValue func_type_to_string=
+ this->newFunction(this->RegistryKeyTypeToString);
+ this->globalObject().setProperty("RegistryKeyTypeToString",
+ func_type_to_string);
+}
+
+DataReporterEngine::~DataReporterEngine() {
+ delete this->p_type_byte_array;
+}
+
+QScriptValue DataReporterEngine::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());
+ }
+
+ //QScriptValue calleeData=context->callee().data();
+ //DataReporterEngine *engine=
+ // qobject_cast<DataReporterEngine*>(calleeData.toQObject());
+ qobject_cast<DataReporterEngine*>(engine)->report_content.append(content);
+
+ return engine->undefinedValue();
+}
+
+QScriptValue DataReporterEngine::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<DataReporterEngine*>(engine)->
+ report_content.append(content).append("\n");
+
+ return engine->undefinedValue();
+}
+
+/*
+ * RegistryKeyValueToScript
+ */
+QScriptValue DataReporterEngine::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 DataReporterEngine::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
+ s.value=obj.property("value").toVariant().toByteArray();
+}
+
+QScriptValue DataReporterEngine::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() || key_length==-1) {
+ // Get error message ro clear error state
+ p_hive->GetErrorMsg();
+ 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 DataReporterEngine::RegistryKeyValueToScript(engine,script_key_value);
+}
+
+QScriptValue DataReporterEngine::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();
+
+ // TODO: Does not work!!
+ //key_value=qscriptvalue_cast<QByteArray>(context->argument(0));
+ key_value=context->argument(0).toVariant().toByteArray();
+ ret=RegistryHive::KeyValueToString(key_value,
+ hive_t_REG_SZ /*context->argument(1).toInteger()*/);
+
+ qDebug("Type: %u Sring: %c",
+ context->argument(1).toInteger(),
+ ret.toAscii().constData());
+
+ return engine->newVariant(ret);
+}
+
+QScriptValue DataReporterEngine::RegistryKeyTypeToString(
+ QScriptContext *context,
+ QScriptEngine *engine)
+{
+ // This function needs one arguments, key type
+ if(context->argumentCount()!=2) return engine->undefinedValue();
}
diff --git a/trunk/datareporterengine.h b/trunk/datareporterengine.h
index fed2ea9..2bf7ee6 100644
--- a/trunk/datareporterengine.h
+++ b/trunk/datareporterengine.h
@@ -1,15 +1,68 @@
+/*******************************************************************************
+* fred Copyright (c) 2011 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 DATAREPORTERENGINE_H
#define DATAREPORTERENGINE_H
+#include <QObject>
+#include <QString>
#include <QtScript/QScriptEngine>
+#include <QtScript/QScriptValue>
+#include <QtScript/QScriptContext>
+
+#include "registryhive.h"
+#include "qtscript_types/bytearray.h"
class DataReporterEngine : public QScriptEngine {
+ Q_OBJECT
+
public:
- DataReporterEngine(QObject *p_parent=0);
+ struct s_RegistryKeyValue {
+ int type;
+ int length;
+ QByteArray value;
+ };
+ RegistryHive *p_registry_hive;
+ QString report_content;
+ DataReporterEngine(RegistryHive *p_hive);
+ ~DataReporterEngine();
+ private:
+ ByteArray *p_type_byte_array;
+ static QScriptValue Print(QScriptContext *context, QScriptEngine *engine);
+ static QScriptValue PrintLn(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 RegistryKeyTypeToString(QScriptContext *context,
+ QScriptEngine *engine);
};
+Q_DECLARE_METATYPE(DataReporterEngine::s_RegistryKeyValue)
+
#endif // DATAREPORTERENGINE_H
diff --git a/trunk/datareporter.h b/trunk/dlgreportviewer.cpp
similarity index 72%
copy from trunk/datareporter.h
copy to trunk/dlgreportviewer.cpp
index 92f06c2..2eeccde 100644
--- a/trunk/datareporter.h
+++ b/trunk/dlgreportviewer.cpp
@@ -1,47 +1,50 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 DATAREPORTER_H
-#define DATAREPORTER_H
-
-#include <QList>
-
-#include <hivex.h>
-
-#include "reporttemplate.h"
-
-class DataReporter {
- public:
- DataReporter();
- ~DataReporter();
-
- void LoadReportTemplates();
- QStringList GetAvailableReportCategories();
- QStringList GetAvailableReports(QString category);
-
- QString GenerateReport(hive_h *hhive,
- QString report_category,
- QString report_name);
-
- private:
- QList<ReportTemplate*> report_templates;
-};
-
-#endif // DATAREPORTER_H
+#include "dlgreportviewer.h"
+#include "ui_dlgreportviewer.h"
+
+#include <QUrl>
+
+DlgReportViewer::DlgReportViewer(QString &report_data, QWidget *p_parent)
+ : QDialog(p_parent), ui(new Ui::DlgReportViewer)
+{
+ ui->setupUi(this);
+ this->ui->WebView->setHtml(report_data);
+}
+
+DlgReportViewer::~DlgReportViewer() {
+ delete ui;
+}
+
+void DlgReportViewer::changeEvent(QEvent *e) {
+ QDialog::changeEvent(e);
+ switch(e->type()) {
+ case QEvent::LanguageChange:
+ ui->retranslateUi(this);
+ break;
+ default:
+ break;
+ }
+}
+
+void DlgReportViewer::on_BtnClose_clicked() {
+ this->accept();
+}
diff --git a/trunk/datareporter.h b/trunk/dlgreportviewer.h
similarity index 74%
copy from trunk/datareporter.h
copy to trunk/dlgreportviewer.h
index 92f06c2..4a8c7e9 100644
--- a/trunk/datareporter.h
+++ b/trunk/dlgreportviewer.h
@@ -1,47 +1,48 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 DATAREPORTER_H
-#define DATAREPORTER_H
+#ifndef DLGREPORTVIEWER_H
+#define DLGREPORTVIEWER_H
-#include <QList>
+#include <QDialog>
-#include <hivex.h>
+namespace Ui {
+ class DlgReportViewer;
+}
-#include "reporttemplate.h"
+class DlgReportViewer : public QDialog {
+ Q_OBJECT
-class DataReporter {
public:
- DataReporter();
- ~DataReporter();
+ explicit DlgReportViewer(QString &report_data,
+ QWidget *p_parent=0);
+ ~DlgReportViewer();
- void LoadReportTemplates();
- QStringList GetAvailableReportCategories();
- QStringList GetAvailableReports(QString category);
+ protected:
+ void changeEvent(QEvent *e);
- QString GenerateReport(hive_h *hhive,
- QString report_category,
- QString report_name);
+ private slots:
+ void on_BtnClose_clicked();
- private:
- QList<ReportTemplate*> report_templates;
+private:
+ Ui::DlgReportViewer *ui;
};
-#endif // DATAREPORTER_H
+#endif // DLGREPORTVIEWER_H
diff --git a/trunk/dlgreportviewer.ui b/trunk/dlgreportviewer.ui
new file mode 100644
index 0000000..344233e
--- /dev/null
+++ b/trunk/dlgreportviewer.ui
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DlgReportViewer</class>
+ <widget class="QDialog" name="DlgReportViewer">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>627</width>
+ <height>466</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QWebView" name="WebView">
+ <property name="url">
+ <url>
+ <string>about:blank</string>
+ </url>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="BtnClose">
+ <property name="text">
+ <string>&amp;Close</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QWebView</class>
+ <extends>QWidget</extends>
+ <header>QtWebKit/QWebView</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/trunk/fred.pro b/trunk/fred.pro
index a752ecb..934bb59 100644
--- a/trunk/fred.pro
+++ b/trunk/fred.pro
@@ -1,72 +1,80 @@
#*******************************************************************************
# fred Copyright (c) 2011 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/>. *
#******************************************************************************/
system(bash compileinfo.sh > compileinfo.h)
QT += core \
gui \
xml \
- script
+ script \
+ webkit
TARGET = fred
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
registrynode.cpp \
registrynodetreemodel.cpp \
registrykey.cpp \
registrykeytablemodel.cpp \
dlgabout.cpp \
dlgkeydetails.cpp \
qhexedit/qhexedit_p.cpp \
qhexedit/qhexedit.cpp \
datainterpreter.cpp \
- reporttemplatexmlhandler.cpp \
reporttemplate.cpp \
datareporter.cpp \
datareporterengine.cpp \
- registryhive.cpp
+ registryhive.cpp \
+ qtscript_types/bytearray.cpp \
+ qtscript_types/bytearrayprototype.cpp \
+ qtscript_types/bytearrayiterator.cpp \
+ dlgreportviewer.cpp
HEADERS += mainwindow.h \
registrynode.h \
registrynodetreemodel.h \
registrykey.h \
registrykeytablemodel.h \
dlgabout.h \
dlgkeydetails.h \
qhexedit/qhexedit_p.h \
qhexedit/qhexedit.h \
datainterpreter.h \
- reporttemplatexmlhandler.h \
reporttemplate.h \
datareporter.h \
datareporterengine.h \
- registryhive.h
+ registryhive.h \
+ qtscript_types/bytearray.h \
+ qtscript_types/bytearrayprototype.h \
+ qtscript_types/bytearrayiterator.h \
+ dlgreportviewer.h
FORMS += mainwindow.ui \
dlgabout.ui \
- dlgkeydetails.ui
+ dlgkeydetails.ui \
+ dlgreportviewer.ui
LIBS += -lhivex
RESOURCES += fred.qrc
diff --git a/trunk/mainwindow.cpp b/trunk/mainwindow.cpp
index cb53e66..a02557a 100644
--- a/trunk/mainwindow.cpp
+++ b/trunk/mainwindow.cpp
@@ -1,509 +1,458 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 <QFileDialog>
#include <QMessageBox>
#include <QStringList>
#include <QDesktopWidget>
#include <QDir>
#include <QSplitter>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dlgabout.h"
#include "dlgkeydetails.h"
+#include "dlgreportviewer.h"
#include "compileinfo.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Initialize private vars
- this->hhive=NULL;
+ this->p_hive=new RegistryHive(this);
this->is_hive_open=false;
this->p_reg_node_tree_model=NULL;
this->p_reg_key_table_model=NULL;
// 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 QTreeView(this->p_horizontal_splitter);
this->p_node_tree->setHeaderHidden(true);
this->p_vertical_splitter=new QSplitter(this->p_horizontal_splitter);
this->p_vertical_splitter->setOrientation(Qt::Vertical);
this->p_key_table=new QTableView(this->p_vertical_splitter);
this->p_key_table->setSelectionBehavior(QAbstractItemView::SelectRows);
this->p_horizontal_splitter2=new QSplitter(this->p_vertical_splitter);
this->p_horizontal_splitter2->setOrientation(Qt::Horizontal);
this->p_hex_edit_widget=new QWidget(this->p_horizontal_splitter2);
this->p_hex_edit_layout=new QVBoxLayout(this->p_hex_edit_widget);
this->p_hex_edit_layout->setContentsMargins(0,0,0,0);
this->p_hex_edit=new QHexEdit();
this->p_hex_edit->setReadOnly(true);
this->p_hex_edit_status_bar=new QLabel();
this->p_data_interpreter=new DataInterpreter(this->p_horizontal_splitter2);
// Make sure hex viewer font is monospaced.
QFont mono_font("Monospace");
mono_font.setStyleHint(QFont::TypeWriter);
this->p_hex_edit->setFont(mono_font);
// Lay out widgets
this->p_hex_edit_layout->addWidget(this->p_hex_edit);
this->p_hex_edit_layout->addWidget(this->p_hex_edit_status_bar);
this->p_horizontal_splitter2->addWidget(this->p_hex_edit_widget);
this->p_horizontal_splitter2->addWidget(this->p_data_interpreter);
this->p_vertical_splitter->addWidget(this->p_key_table);
this->p_vertical_splitter->addWidget(this->p_horizontal_splitter2);
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 hex_edit_widget_policy=this->p_hex_edit_widget->sizePolicy();
hex_edit_widget_policy.setVerticalStretch(2);
hex_edit_widget_policy.setHorizontalStretch(200);
this->p_hex_edit_widget->setSizePolicy(hex_edit_widget_policy);
QSizePolicy data_interpreter_policy=this->p_data_interpreter->sizePolicy();
data_interpreter_policy.setVerticalStretch(2);
data_interpreter_policy.setHorizontalStretch(0);
this->p_data_interpreter->setSizePolicy(data_interpreter_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_key_table,
+ this->connect(this->p_key_table /*->selectionModel()*/,
+ /* SIGNAL(selectionChanged(QItemSelection,QItemSelection)) */
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotKeyTableClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotKeyTableDoubleClicked(QModelIndex)));
this->connect(this->p_hex_edit,
SIGNAL(currentAddressChanged(int)),
this,
SLOT(SlotHexEditAddressChanged(int)));
// Add central widget
this->setContentsMargins(4,4,4,0);
this->setCentralWidget(this->p_horizontal_splitter);
// Set window title
this->UpdateWindowTitle();
// Set last open location to home dir
this->last_open_location=QDir::homePath();
// Load report templates and update menu
this->p_data_reporter=new DataReporter();
this->p_data_reporter->LoadReportTemplates();
this->UpdateDataReporterMenu();
}
MainWindow::~MainWindow() {
if(this->is_hive_open) {
- hivex_close(this->hhive);
+ this->p_hive->Close();
}
delete ui;
}
void MainWindow::on_action_Quit_triggered() {
qApp->exit();
}
void MainWindow::on_action_Open_hive_triggered() {
QString hive_file="";
hive_file=QFileDialog::getOpenFileName(this,
tr("Open registry hive"),
this->last_open_location,
tr("All files (*)"));
if(hive_file=="") return;
// 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
- this->hhive=hivex_open(hive_file.toAscii().constData(),0);
- if(this->hhive==NULL) {
+ 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
- hive_node_h root_node=hivex_root(hhive);
- if(root_node==0) {
- QMessageBox::critical(this,
- tr("Error opening hive file"),
- tr("This hive seems to have no root node!")
- .arg(hive_file));
- return;
- }
this->p_reg_node_tree_model=
- new RegistryNodeTreeModel(this->hhive,
- root_node);
+ new RegistryNodeTreeModel(this->p_hive);
this->p_node_tree->setModel(this->p_reg_node_tree_model);
this->is_hive_open=true;
this->ui->action_Close_hive->setEnabled(true);
this->ui->MenuReports->setEnabled(true);
this->UpdateWindowTitle(hive_file);
}
void MainWindow::on_action_Close_hive_triggered() {
if(this->is_hive_open) {
// Delete models
if(this->p_reg_node_tree_model!=NULL) {
delete this->p_reg_node_tree_model;
this->p_reg_node_tree_model=NULL;
}
if(this->p_reg_key_table_model!=NULL) {
delete this->p_reg_key_table_model;
this->p_reg_key_table_model=NULL;
}
// Remove any data from hex edit and data interpreter
this->p_hex_edit->setData(QByteArray());
this->p_hex_edit_status_bar->setText("");
this->p_data_interpreter->ClearValues();
// Close hive
- hivex_close(this->hhive);
+ this->p_hive->Close();
this->is_hive_open=false;
this->ui->action_Close_hive->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::SlotNodeTreeClicked(QModelIndex index) {
- QStringList nodes;
+ QString node_path;
//Built node path
- nodes.clear();
- nodes.append(this->p_reg_node_tree_model->
- data(index,Qt::DisplayRole).toString());
+ node_path.clear();
+ node_path=this->p_reg_node_tree_model->data(index,Qt::DisplayRole)
+ .toString().prepend("\\");
while(this->p_reg_node_tree_model->parent(index)!=QModelIndex()) {
// Prepend all parent nodes
index=this->p_reg_node_tree_model->parent(index);
- nodes.prepend(this->p_reg_node_tree_model->
- data(index,Qt::DisplayRole).toString());
- }
-
- // Get hive_node handle for current node
- hive_node_h hive_node=hivex_root(this->hhive);
- QString cur_node;
- for(QStringList::iterator it=nodes.begin();it!=nodes.end();++it) {
- cur_node=*it;
- hive_node=hivex_node_get_child(this->hhive,
- hive_node,
- cur_node.toAscii().constData());
+ node_path.prepend(this->p_reg_node_tree_model->data(index,Qt::DisplayRole)
+ .toString().prepend("\\"));
}
// Create table model and attach it to the table view
if(this->p_reg_key_table_model!=NULL) delete this->p_reg_key_table_model;
- this->p_reg_key_table_model=new RegistryKeyTableModel(this->hhive,
- hive_node);
+ this->p_reg_key_table_model=new RegistryKeyTableModel(this->p_hive,node_path);
this->p_key_table->setModel(this->p_reg_key_table_model);
// Resize table rows / columns to fit data
this->p_key_table->resizeColumnsToContents();
this->p_key_table->horizontalHeader()->stretchLastSection();
}
void MainWindow::SlotKeyTableDoubleClicked(QModelIndex 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();
key_index=this->p_reg_key_table_model->index(index.row(),2);
key_value=this->p_reg_key_table_model->data(key_index,
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
// Get current node
node_index=this->p_node_tree->currentIndex();
//Built node path
nodes.clear();
nodes.append(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
while(this->p_reg_node_tree_model->parent(node_index)!=QModelIndex()) {
// Prepend all parent nodes
node_index=this->p_reg_node_tree_model->parent(node_index);
nodes.prepend(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
}
DlgKeyDetails dlg_key_details(this);
dlg_key_details.SetValues(nodes,key_name,key_type,key_value);
dlg_key_details.exec();
+ */
}
void MainWindow::SlotKeyTableClicked(QModelIndex index) {
if(!index.isValid()) return;
this->selected_key_value=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),2),
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
this->p_hex_edit->setData(this->selected_key_value);
}
void MainWindow::SlotHexEditAddressChanged(int hex_offset) {
// Update hex edit status bar
this->p_hex_edit_status_bar->
setText(QString().sprintf("Byte offset: 0x%04X (%u)",hex_offset,hex_offset));
// Update data interpreter
this->UpdateDataInterpreter(hex_offset);
}
void MainWindow::SlotReportClicked() {
// Get report category and name from sender and it's parent
QString category=((QMenu*)((QAction*)QObject::sender())->parent())->title();
QString report=((QAction*)QObject::sender())->text();
- QString report_content=this->p_data_reporter->GenerateReport(this->hhive,
+ QString report_content=this->p_data_reporter->GenerateReport(this->p_hive,
category,
report);
- QMessageBox::information(this,report,report_content);
-
+ DlgReportViewer dlg_report_view(report_content,this);
+ dlg_report_view.exec();
}
void MainWindow::UpdateWindowTitle(QString filename) {
if(filename=="") {
this->setWindowTitle(QString().sprintf("%s v%s",APP_TITLE,APP_VERSION));
} else {
this->setWindowTitle(QString().sprintf("%s v%s - %s",
APP_TITLE,
APP_VERSION,
filename.toLocal8Bit().constData()));
}
}
void MainWindow::UpdateDataInterpreter(int hex_offset) {
QDateTime date_time;
const char *p_data;
int remaining_data_len;
// Remove all old values from data interpreter
this->p_data_interpreter->ClearValues();
// Calculate how many bytes are remainig after current offset
remaining_data_len=this->selected_key_value.size()-hex_offset;
if(!remaining_data_len>0) {
// Nothing to show
return;
}
// Get pointer to data at current offset
p_data=this->selected_key_value.constData();
p_data+=hex_offset;
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
//#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
#define rotl64(x,n) (((x) << n) | ((x) >> (64 - n)))
//#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n)))
if(remaining_data_len>=1) {
this->p_data_interpreter->AddValue("int8:",
QString().sprintf("%d",
*(int8_t*)p_data));
this->p_data_interpreter->AddValue("uint8:",
QString().sprintf("%u",
*(uint8_t*)p_data));
}
if(remaining_data_len>=2) {
this->p_data_interpreter->AddValue("int16:",
QString().sprintf("%d",
*(int16_t*)p_data));
this->p_data_interpreter->AddValue("uint16:",
QString().sprintf("%u",
*(uint16_t*)p_data));
}
if(remaining_data_len>=4) {
this->p_data_interpreter->AddValue("int32:",
QString().sprintf("%d",
*(int32_t*)p_data));
this->p_data_interpreter->AddValue("uint32:",
QString().sprintf("%d",
*(uint32_t*)p_data));
date_time.setTime_t(*(uint32_t*)p_data);
this->p_data_interpreter->AddValue("Unixtime:",
date_time.
toString("yyyy/MM/dd hh:mm:ss"));
}
if(remaining_data_len>=8) {
this->p_data_interpreter->AddValue("int64:",
QString().sprintf("%d",
*(int64_t*)p_data));
this->p_data_interpreter->AddValue("uint64:",
QString().sprintf("%d",
*(uint64_t*)p_data));
date_time.setTime_t((*(uint64_t*)p_data-116444736000000000)/10000000);
this->p_data_interpreter->AddValue("Win64time:",
date_time.
toString("yyyy/MM/dd hh:mm:ss"));
}
#undef rotl32
#undef rotl64
}
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::LoadReportTemplates() {
- //#include <QtXml/QXmlSimpleReader>
-
- QString report_template="";
- QXmlSimpleReader xml_parser;
-
- qDebug("Loading report templates...");
-
- QDir report_dir("../trunk/report_templates/");
- QStringList report_templates=report_dir.entryList(QStringList()<<"*.fred");
- int i=0;
-
- for(i=0;i<report_templates.count();i++) {
- report_template=report_dir.path();
- report_template.append(QDir::separator());
- report_template.append(report_templates.value(i));
-
- qDebug("%s",report_template.toAscii().constData());
-
- QFile *p_report_template_file=new QFile(report_template);
- QXmlInputSource *p_xml_file=new QXmlInputSource(p_report_template_file);
- ReportTemplateXmlHandler *p_report_handler=new ReportTemplateXmlHandler();
-
- xml_parser.setContentHandler(p_report_handler);
- xml_parser.parse(p_xml_file);
-
- delete p_report_handler;
- delete p_xml_file;
- delete p_report_template_file;
- }
-}
-*/
diff --git a/trunk/mainwindow.h b/trunk/mainwindow.h
index d05d171..2304058 100644
--- a/trunk/mainwindow.h
+++ b/trunk/mainwindow.h
@@ -1,100 +1,101 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 <hivex.h>
+#include "registryhive.h"
#include "registrynodetreemodel.h"
#include "registrykeytablemodel.h"
#include "qhexedit/qhexedit.h"
#include "datainterpreter.h"
#include "datareporter.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~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 SlotNodeTreeClicked(QModelIndex index);
void SlotKeyTableClicked(QModelIndex index);
void SlotKeyTableDoubleClicked(QModelIndex index);
void SlotHexEditAddressChanged(int hex_offset);
void SlotReportClicked();
private:
Ui::MainWindow *ui;
QString last_open_location;
- hive_h *hhive;
+ RegistryHive *p_hive;
bool is_hive_open;
RegistryNodeTreeModel *p_reg_node_tree_model;
RegistryKeyTableModel *p_reg_key_table_model;
QByteArray selected_key_value;
// Widgets etc...
QTreeView *p_node_tree;
QTableView *p_key_table;
QWidget *p_hex_edit_widget;
QHexEdit *p_hex_edit;
QLabel *p_hex_edit_status_bar;
DataInterpreter *p_data_interpreter;
QVBoxLayout *p_hex_edit_layout;
QSplitter *p_horizontal_splitter;
QSplitter *p_horizontal_splitter2;
QSplitter *p_vertical_splitter;
DataReporter *p_data_reporter;
/*
* UpdateWindowTitle
*
* Updates the window title
*/
void UpdateWindowTitle(QString filename="");
/*
* UpdateDataInterpreter
*
* Update data interpreter
*/
void UpdateDataInterpreter(int hex_offset);
/*
* UpdateDataReporterMenu
*
*/
void UpdateDataReporterMenu();
};
#endif // MAINWINDOW_H
diff --git a/trunk/qhexedit/qhexedit_p.cpp b/trunk/qhexedit/qhexedit_p.cpp
index 23a6f80..3988385 100644
--- a/trunk/qhexedit/qhexedit_p.cpp
+++ b/trunk/qhexedit/qhexedit_p.cpp
@@ -1,454 +1,455 @@
/*******************************************************************************
* qhexedit Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Simple hex editor widget for Qt. *
* *
* Derived from code by Simon Winfried under a compatible license: *
* Copyright (c) 2010 by Simon Winfried *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include <QtGui>
#include "qhexedit_p.h"
const int HEXCHARS_IN_LINE = 47;
const int GAP_ADR_HEX = 10;
const int GAP_HEX_ASCII = 16;
const int BYTES_PER_LINE = 16;
QHexEditPrivate::QHexEditPrivate(QScrollArea *parent) : QWidget(parent)
{
_scrollArea = parent;
setAddressWidth(4);
setAddressOffset(0);
setAddressArea(true);
setAsciiArea(true);
setHighlighting(true);
setOverwriteMode(true);
setAddressAreaColor(QColor(Qt::lightGray).lighter(110));
setHighlightingColor(QColor(Qt::yellow).lighter(160));
this->setReadOnly(true);
setFont(QFont("Mono", 10));
connect(&_cursorTimer, SIGNAL(timeout()), this, SLOT(updateCursor()));
_cursorTimer.setInterval(500);
- _cursorTimer.start();
setFocusPolicy(Qt::StrongFocus);
_size = -1;
}
void QHexEditPrivate::setAddressOffset(int offset)
{
_addressOffset = offset;
adjust();
}
int QHexEditPrivate::addressOffset()
{
return _addressOffset;
}
void QHexEditPrivate::setData(const QByteArray &data)
{
- _data = data;
- _originalData = data;
- adjust();
- setCursorPos(0);
- setFocus();
+ if(!data.isNull() && !data.isEmpty()) this->_cursorTimer.start();
+ else this->_cursorTimer.stop();
+ this->_data = data;
+ this->_originalData = data;
+ this->adjust();
+ this->setCursorPos(0);
+ this->setFocus();
}
QByteArray QHexEditPrivate::data()
{
return _data;
}
void QHexEditPrivate::setAddressAreaColor(const QColor &color)
{
_addressAreaColor = color;
update();
}
QColor QHexEditPrivate::addressAreaColor()
{
return _addressAreaColor;
}
void QHexEditPrivate::setHighlightingColor(const QColor &color)
{
_highlightingColor = color;
update();
}
QColor QHexEditPrivate::highlightingColor()
{
return _highlightingColor;
}
void QHexEditPrivate::setOverwriteMode(bool overwriteMode)
{
if (overwriteMode != _overwriteMode)
{
emit overwriteModeChanged(overwriteMode);
_overwriteMode = overwriteMode;
adjust();
}
}
bool QHexEditPrivate::overwriteMode()
{
return _overwriteMode;
}
void QHexEditPrivate::setReadOnly(bool read_only) {
this->_readOnly=read_only;
}
bool QHexEditPrivate::readOnly() {
return this->_readOnly;
}
void QHexEditPrivate::insert(int i, const QByteArray & ba)
{
_data.insert(i, ba);
_originalData.insert(i, ba);
}
void QHexEditPrivate::insert(int i, char ch)
{
_data.insert(i, ch);
_originalData.insert(i, ch);
}
void QHexEditPrivate::remove(int index, int len)
{
_data.remove(index, len);
_originalData.remove(index, len);
}
void QHexEditPrivate::setAddressArea(bool addressArea)
{
_addressArea = addressArea;
adjust();
setCursorPos(_cursorPosition);
}
void QHexEditPrivate::setAddressWidth(int addressWidth)
{
if ((addressWidth >= 0) and (addressWidth<=6))
{
_addressNumbers = addressWidth;
adjust();
setCursorPos(_cursorPosition);
}
}
void QHexEditPrivate::setAsciiArea(bool asciiArea)
{
_asciiArea = asciiArea;
adjust();
}
void QHexEditPrivate::setFont(const QFont &font)
{
QWidget::setFont(font);
adjust();
}
void QHexEditPrivate::setHighlighting(bool mode)
{
_highlighting = mode;
update();
}
void QHexEditPrivate::keyPressEvent(QKeyEvent *event)
{
bool down = false;
int charX = (_cursorX - _xPosHex) / _charWidth;
int posX = (charX / 3) * 2 + (charX % 3);
int posBa = (_cursorY / _charHeight) * BYTES_PER_LINE + posX / 2;
int key = int(event->text()[0].toAscii());
if (!this->_readOnly &&
((key>='0' && key<='9') || (key>='a' && key <= 'f')))
{
// insert char
if (_overwriteMode == false)
if ((charX % 3) == 0)
{
insert(posBa, char(0));
adjust();
}
if (_data.size() > 0)
{
QByteArray hexValue = _data.mid(posBa, 1).toHex();
if ((charX % 3) == 0)
hexValue[0] = key;
else
hexValue[1] = key;
_data.replace(posBa, 1, QByteArray().fromHex(hexValue));
emit dataChanged();
setCursorPos(_cursorPosition + 1);
down = true;
}
}
// delete char
if (!this->_readOnly && event->matches(QKeySequence::Delete)) {
remove(posBa);
}
if (!this->_readOnly && event->key() == Qt::Key_Backspace) {
remove(posBa - 1);
setCursorPos(_cursorPosition - 2);
}
// handle other function keys
if(!this->_readOnly && event->key() == Qt::Key_Insert) {
setOverwriteMode(!_overwriteMode);
setCursorPos(_cursorPosition);
}
if (event->matches(QKeySequence::MoveToNextChar))
{
setCursorPos(_cursorPosition + 1);
down = true;
}
if (event->matches(QKeySequence::MoveToPreviousChar))
setCursorPos(_cursorPosition - 1);
if (event->matches(QKeySequence::MoveToStartOfLine))
setCursorPos(_cursorPosition - (_cursorPosition % (2 * BYTES_PER_LINE)));
if (event->matches(QKeySequence::MoveToEndOfLine))
setCursorPos(_cursorPosition | (2 * BYTES_PER_LINE -1));
if (event->matches(QKeySequence::MoveToPreviousLine))
setCursorPos(_cursorPosition - (2 * BYTES_PER_LINE));
if (event->matches(QKeySequence::MoveToPreviousPage))
setCursorPos(_cursorPosition - (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE));
if (event->matches(QKeySequence::MoveToStartOfDocument))
setCursorPos(0);
if (event->matches(QKeySequence::MoveToNextLine))
{
setCursorPos(_cursorPosition + (2 * BYTES_PER_LINE));
down = true;
}
if (event->matches(QKeySequence::MoveToEndOfDocument))
{
setCursorPos(_data.size() * 2);
down = true;
}
if (event->matches(QKeySequence::MoveToNextPage))
{
setCursorPos(_cursorPosition + (((_scrollArea->viewport()->height() / _charHeight) - 1) * 2 * BYTES_PER_LINE));
down = true;
}
// when we move downwards, we have to go a little further
if (down)
_scrollArea->ensureVisible(_cursorX, _cursorY, 3, 3 + _charHeight);
else
_scrollArea->ensureVisible(_cursorX, _cursorY, 3, 3);
update();
}
void QHexEditPrivate::mousePressEvent(QMouseEvent * event)
{
setCursorPos(event->pos());
}
void QHexEditPrivate::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
// draw some patterns if needed
painter.fillRect(event->rect(), this->palette().color(QPalette::Base));
if (_addressArea)
painter.fillRect(QRect(_xPosAdr, event->rect().top(), _xPosHex - GAP_ADR_HEX + 2, height()), _addressAreaColor);
if (_asciiArea)
{
int linePos = _xPosAscii - (GAP_HEX_ASCII / 2);
painter.setPen(Qt::gray);
painter.drawLine(linePos, event->rect().top(), linePos, height());
}
painter.setPen(this->palette().color(QPalette::WindowText));
// calc position
int firstLineIdx = ((event->rect().top()/ _charHeight) - _charHeight) * BYTES_PER_LINE;
if (firstLineIdx < 0)
firstLineIdx = 0;
int lastLineIdx = ((event->rect().bottom() / _charHeight) + _charHeight) * BYTES_PER_LINE;
if (lastLineIdx > _data.size())
lastLineIdx = _data.size();
int yPosStart = ((firstLineIdx) / BYTES_PER_LINE) * _charHeight + _charHeight;
// paint address area
if (_addressArea)
{
for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight)
{
QString address = QString("%1")
.arg(lineIdx + _addressOffset, _realAddressNumbers, 16, QChar('0'));
painter.drawText(_xPosAdr, yPos, address);
}
}
// paint hex area
QByteArray hexBa(_data.mid(firstLineIdx, lastLineIdx - firstLineIdx + 1).toHex());
QBrush highLighted = QBrush(_highlightingColor);
painter.setBackground(highLighted);
painter.setBackgroundMode(Qt::TransparentMode);
for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight)
{
QByteArray hex;
int xPos = _xPosHex;
for (int colIdx = 0; ((lineIdx + colIdx) < _data.size() and (colIdx < BYTES_PER_LINE)); colIdx++)
{
// hilight diff bytes
if (_highlighting)
{
int posBa = lineIdx + colIdx;
if (posBa >= _originalData.size())
painter.setBackgroundMode(Qt::TransparentMode);
else
if (_data[posBa] == _originalData[posBa])
painter.setBackgroundMode(Qt::TransparentMode);
else
painter.setBackgroundMode(Qt::OpaqueMode);
}
// render hex value
if (colIdx == 0)
{
hex = hexBa.mid((lineIdx - firstLineIdx) * 2, 2);
painter.drawText(xPos, yPos, hex);
xPos += 2 * _charWidth;
} else {
hex = hexBa.mid((lineIdx + colIdx - firstLineIdx) * 2, 2).prepend(" ");
painter.drawText(xPos, yPos, hex);
xPos += 3 * _charWidth;
}
}
}
painter.setBackgroundMode(Qt::TransparentMode);
// paint ascii area
if (_asciiArea)
{
for (int lineIdx = firstLineIdx, yPos = yPosStart; lineIdx < lastLineIdx; lineIdx += BYTES_PER_LINE, yPos +=_charHeight)
{
QByteArray ascii = _data.mid(lineIdx, BYTES_PER_LINE);
for (int idx=0; idx < ascii.size(); idx++)
if (((char)ascii[idx] < 0x20) or ((char)ascii[idx] > 0x7e))
ascii[idx] = '.';
painter.drawText(_xPosAscii, yPos, ascii);
}
}
// paint cursor
- if (_blink)
+ if (_blink && !this->_data.isNull() && !this->_data.isEmpty())
{
if (_overwriteMode)
painter.fillRect(_cursorX, _cursorY + _charHeight - 2, _charWidth, 2, this->palette().color(QPalette::WindowText));
else
painter.fillRect(_cursorX, _cursorY, 2, _charHeight, this->palette().color(QPalette::WindowText));
}
if (_size != _data.size())
{
_size = _data.size();
emit currentSizeChanged(_size);
}
}
void QHexEditPrivate::setCursorPos(int position)
{
// delete cursor
_blink = false;
update();
// cursor in range?
if (_overwriteMode)
{
if (position > (_data.size() * 2 - 1))
position = _data.size() * 2 - 1;
} else {
if (position > (_data.size() * 2))
position = _data.size() * 2;
}
if (position < 0)
position = 0;
// calc position
_cursorPosition = position;
_cursorY = (position / (2 * BYTES_PER_LINE)) * _charHeight + 4;
int x = (position % (2 * BYTES_PER_LINE));
_cursorX = (((x / 2) * 3) + (x % 2)) * _charWidth + _xPosHex;
// immiadately draw cursor
_blink = true;
update();
emit currentAddressChanged(_cursorPosition/2);
}
void QHexEditPrivate::setCursorPos(QPoint pos)
{
// find char under cursor
if ((pos.x() >= _xPosHex) and (pos.x() < (_xPosHex + HEXCHARS_IN_LINE * _charWidth)))
{
int x = (pos.x() - _xPosHex) / _charWidth;
if ((x % 3) == 0)
x = (x / 3) * 2;
else
x = ((x / 3) * 2) + 1;
int y = (pos.y() / _charHeight) * 2 * BYTES_PER_LINE;
setCursorPos(x + y);
}
}
void QHexEditPrivate::updateCursor()
{
if (_blink)
_blink = false;
else
_blink = true;
update(_cursorX, _cursorY, _charWidth, _charHeight);
}
void QHexEditPrivate::adjust()
{
_charWidth = fontMetrics().width(QLatin1Char('9'));
_charHeight = fontMetrics().height();
// is addressNumbers wide enought?
QString test = QString("%1")
.arg(_data.size() + _addressOffset, _addressNumbers, 16, QChar('0'));
_realAddressNumbers = test.size();
_xPosAdr = 0;
if (_addressArea)
_xPosHex = _realAddressNumbers *_charWidth + GAP_ADR_HEX;
else
_xPosHex = 0;
_xPosAscii = _xPosHex + HEXCHARS_IN_LINE * _charWidth + GAP_HEX_ASCII;
// tell QAbstractScollbar, how big we are
setMinimumHeight(((_data.size()/16 + 1) * _charHeight) + 3);
setMinimumWidth(_xPosAscii + (BYTES_PER_LINE * _charWidth));
update();
}
diff --git a/trunk/qtscript_types/bytearray.cpp b/trunk/qtscript_types/bytearray.cpp
new file mode 100644
index 0000000..0986ab6
--- /dev/null
+++ b/trunk/qtscript_types/bytearray.cpp
@@ -0,0 +1,179 @@
+/*******************************************************************************
+* Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* *
+* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
+* compatible license: *
+* *
+* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
+* All rights reserved. *
+* *
+* 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 <QtScript/QScriptEngine>
+
+#include "bytearray.h"
+#include "bytearrayiterator.h"
+#include "bytearrayprototype.h"
+
+#include <stdlib.h>
+
+Q_DECLARE_METATYPE(QByteArray*)
+Q_DECLARE_METATYPE(ByteArray*)
+
+static qint32 toArrayIndex(const QString &str) {
+ QByteArray bytes = str.toUtf8();
+ char *eptr;
+
+ quint32 pos = strtoul(bytes.constData(), &eptr, 10);
+ if((eptr == bytes.constData() + bytes.size()) &&
+ (QByteArray::number(pos) == bytes))
+ {
+ return pos;
+ }
+
+ return -1;
+}
+
+ByteArray::ByteArray(QScriptEngine *engine)
+ : QObject(engine), QScriptClass(engine)
+{
+ qScriptRegisterMetaType<QByteArray>(engine,
+ this->toScriptValue,
+ this->fromScriptValue);
+
+ length=engine->toStringHandle(QLatin1String("length"));
+
+ this->proto=engine->newQObject(new ByteArrayPrototype(this),
+ QScriptEngine::QtOwnership,
+ QScriptEngine::SkipMethodsInEnumeration |
+ QScriptEngine::ExcludeSuperClassMethods |
+ QScriptEngine::ExcludeSuperClassProperties);
+ QScriptValue global=engine->globalObject();
+ this->proto.setPrototype(global.property("Object").property("prototype"));
+
+ this->ctor=engine->newFunction(construct);
+ this->ctor.setData(qScriptValueFromValue(engine,this));
+}
+
+ByteArray::~ByteArray() {}
+
+QScriptClass::QueryFlags ByteArray::queryProperty(const QScriptValue &object,
+ const QScriptString &name,
+ QueryFlags flags,
+ uint *id)
+{
+ QByteArray *ba=qscriptvalue_cast<QByteArray*>(object.data());
+
+ if(!ba) return 0;
+ if(name!=length) {
+ qint32 pos=toArrayIndex(name);
+ if(pos==-1) return 0;
+ *id=pos;
+ if((flags & HandlesReadAccess) && (pos>=ba->size()))
+ flags &= ~HandlesReadAccess;
+ }
+
+ return flags;
+}
+
+QScriptValue ByteArray::property(const QScriptValue &object,
+ const QScriptString &name,
+ uint id)
+{
+ QByteArray *ba=qscriptvalue_cast<QByteArray*>(object.data());
+ if(!ba) return QScriptValue();
+ if(name==length) return ba->length();
+ else {
+ qint32 pos=id;
+ if((pos < 0) || (pos >= ba->size())) return QScriptValue();
+ return uint(ba->at(pos)) & 255;
+ }
+
+ return QScriptValue();
+}
+
+void ByteArray::setProperty(QScriptValue &object,
+ const QScriptString &name,
+ uint id,
+ const QScriptValue &value)
+{
+ QByteArray *ba=qscriptvalue_cast<QByteArray*>(object.data());
+ if(!ba) return;
+ if(name==length) ba->resize(value.toInt32());
+ else {
+ qint32 pos=id;
+ if(pos<0) return;
+ if(ba->size()<=pos) ba->resize(pos + 1);
+ (*ba)[pos]=char(value.toInt32());
+ }
+}
+
+QScriptValue::PropertyFlags ByteArray::propertyFlags(const QScriptValue &object,
+ const QScriptString &name,
+ uint id)
+{
+ Q_UNUSED(object);
+ Q_UNUSED(id);
+
+ if(name==length) {
+ return QScriptValue::Undeletable | QScriptValue::SkipInEnumeration;
+ }
+ return QScriptValue::Undeletable;
+}
+
+QScriptClassPropertyIterator *ByteArray::newIterator(const QScriptValue &object)
+{
+ return new ByteArrayIterator(object);
+}
+
+QString ByteArray::name() const {
+ return QLatin1String("ByteArray");
+}
+
+QScriptValue ByteArray::prototype() const {
+ return this->proto;
+}
+
+QScriptValue ByteArray::constructor() {
+ return this->ctor;
+}
+
+QScriptValue ByteArray::newInstance(int size) {
+ return newInstance(QByteArray(size,0));
+}
+
+QScriptValue ByteArray::newInstance(const QByteArray &ba) {
+ QScriptValue data=engine()->newVariant(qVariantFromValue(ba));
+ return engine()->newObject(this,data);
+}
+
+QScriptValue ByteArray::construct(QScriptContext *ctx, QScriptEngine *) {
+ ByteArray *cls=qscriptvalue_cast<ByteArray*>(ctx->callee().data());
+ if(!cls) return QScriptValue();
+ int size=ctx->argument(0).toInt32();
+ return cls->newInstance(size);
+}
+
+QScriptValue ByteArray::toScriptValue(QScriptEngine *eng, const QByteArray &ba)
+{
+ QScriptValue ctor=eng->globalObject().property("ByteArray");
+ ByteArray *cls=qscriptvalue_cast<ByteArray*>(ctor.data());
+ if(!cls) return eng->newVariant(qVariantFromValue(ba));
+ return cls->newInstance(ba);
+}
+
+void ByteArray::fromScriptValue(const QScriptValue &obj, QByteArray &ba) {
+ ba=qscriptvalue_cast<QByteArray>(obj.data());
+}
diff --git a/trunk/qtscript_types/bytearray.h b/trunk/qtscript_types/bytearray.h
new file mode 100644
index 0000000..56f859c
--- /dev/null
+++ b/trunk/qtscript_types/bytearray.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+* Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* *
+* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
+* compatible license: *
+* *
+* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
+* All rights reserved. *
+* *
+* 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/>. *
+*******************************************************************************/
+
+// Description: http://cs.karelia.ru/~aborod/doc/qt/script-customclass.html
+
+#ifndef BYTEARRAY_H
+#define BYTEARRAY_H
+
+#include <QObject>
+#include <QtScript/QScriptClass>
+#include <QtScript/QScriptString>
+
+class ByteArray : public QObject, public QScriptClass {
+ public:
+ ByteArray(QScriptEngine *engine);
+ ~ByteArray();
+
+ QScriptValue constructor();
+
+ QScriptValue newInstance(int size = 0);
+ QScriptValue newInstance(const QByteArray &ba);
+
+ QueryFlags queryProperty(const QScriptValue &object,
+ const QScriptString &name,
+ QueryFlags flags,
+ uint *id);
+ QScriptValue property(const QScriptValue &object,
+ const QScriptString &name,
+ uint id);
+ void setProperty(QScriptValue &object,
+ const QScriptString &name,
+ uint id,
+ const QScriptValue &value);
+ QScriptValue::PropertyFlags propertyFlags(const QScriptValue &object,
+ const QScriptString &name,
+ uint id);
+ QScriptClassPropertyIterator *newIterator(const QScriptValue &object);
+
+ QString name() const;
+
+ QScriptValue prototype() const;
+
+ private:
+ static QScriptValue construct(QScriptContext *ctx, QScriptEngine *eng);
+
+ static QScriptValue toScriptValue(QScriptEngine *eng, const QByteArray &ba);
+ static void fromScriptValue(const QScriptValue &obj, QByteArray &ba);
+
+ QScriptString length;
+ QScriptValue proto;
+ QScriptValue ctor;
+};
+
+#endif // BYTEARRAY_H
diff --git a/trunk/qtscript_types/bytearrayiterator.cpp b/trunk/qtscript_types/bytearrayiterator.cpp
new file mode 100644
index 0000000..8ef3069
--- /dev/null
+++ b/trunk/qtscript_types/bytearrayiterator.cpp
@@ -0,0 +1,74 @@
+/*******************************************************************************
+* Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* *
+* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
+* compatible license: *
+* *
+* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
+* All rights reserved. *
+* *
+* 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 "bytearrayiterator.h"
+
+#include <QtScript/QScriptEngine>
+
+Q_DECLARE_METATYPE(QByteArray*)
+
+ByteArrayIterator::ByteArrayIterator(const QScriptValue &object)
+ : QScriptClassPropertyIterator(object)
+{
+ toFront();
+}
+
+ByteArrayIterator::~ByteArrayIterator() {}
+
+bool ByteArrayIterator::hasNext() const {
+ QByteArray *ba=qscriptvalue_cast<QByteArray*>(object().data());
+ return m_index<ba->size();
+}
+
+void ByteArrayIterator::next() {
+ m_last=m_index;
+ ++m_index;
+}
+
+bool ByteArrayIterator::hasPrevious() const {
+ return(m_index>0);
+}
+
+void ByteArrayIterator::previous() {
+ --m_index;
+ m_last=m_index;
+}
+
+void ByteArrayIterator::toFront() {
+ m_index=0;
+ m_last=-1;
+}
+
+void ByteArrayIterator::toBack() {
+ QByteArray *ba=qscriptvalue_cast<QByteArray*>(object().data());
+ m_index=ba->size();
+ m_last=-1;
+}
+
+QScriptString ByteArrayIterator::name() const {
+ return QScriptString();
+}
+
+uint ByteArrayIterator::id() const {
+ return m_last;
+}
diff --git a/trunk/datareporter.h b/trunk/qtscript_types/bytearrayiterator.h
similarity index 58%
copy from trunk/datareporter.h
copy to trunk/qtscript_types/bytearrayiterator.h
index 92f06c2..3574ea8 100644
--- a/trunk/datareporter.h
+++ b/trunk/qtscript_types/bytearrayiterator.h
@@ -1,47 +1,51 @@
/*******************************************************************************
-* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* Copyright (c) 2011 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. *
+* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
+* compatible license: *
+* *
+* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
+* All rights reserved. *
* *
* 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 DATAREPORTER_H
-#define DATAREPORTER_H
+#ifndef BYTEARRAYITERATOR_H
+#define BYTEARRAYITERATOR_H
-#include <QList>
+#include <QtScript/QScriptClassPropertyIterator>
-#include <hivex.h>
+class ByteArrayIterator : public QScriptClassPropertyIterator {
+ public:
+ ByteArrayIterator(const QScriptValue &object);
+ ~ByteArrayIterator();
-#include "reporttemplate.h"
+ bool hasNext() const;
+ void next();
-class DataReporter {
- public:
- DataReporter();
- ~DataReporter();
+ bool hasPrevious() const;
+ void previous();
- void LoadReportTemplates();
- QStringList GetAvailableReportCategories();
- QStringList GetAvailableReports(QString category);
+ void toFront();
+ void toBack();
- QString GenerateReport(hive_h *hhive,
- QString report_category,
- QString report_name);
+ QScriptString name() const;
+ uint id() const;
private:
- QList<ReportTemplate*> report_templates;
+ int m_index;
+ int m_last;
};
-#endif // DATAREPORTER_H
+#endif // BYTEARRAYITERATOR_H
diff --git a/trunk/qtscript_types/bytearrayprototype.cpp b/trunk/qtscript_types/bytearrayprototype.cpp
new file mode 100644
index 0000000..dca2279
--- /dev/null
+++ b/trunk/qtscript_types/bytearrayprototype.cpp
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* *
+* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
+* compatible license: *
+* *
+* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
+* All rights reserved. *
+* *
+* 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 "bytearrayprototype.h"
+#include <QtScript/QScriptEngine>
+
+Q_DECLARE_METATYPE(QByteArray*)
+
+ByteArrayPrototype::ByteArrayPrototype(QObject *p_parent) : QObject(p_parent) {}
+
+ByteArrayPrototype::~ByteArrayPrototype() {}
+
+QByteArray *ByteArrayPrototype::thisByteArray() const {
+ return qscriptvalue_cast<QByteArray*>(thisObject().data());
+}
+
+void ByteArrayPrototype::chop(int n) {
+ thisByteArray()->chop(n);
+}
+
+bool ByteArrayPrototype::equals(const QByteArray &other) {
+ return *thisByteArray()==other;
+}
+
+QByteArray ByteArrayPrototype::left(int len) const {
+ return thisByteArray()->left(len);
+}
+
+QByteArray ByteArrayPrototype::mid(int pos, int len) const {
+ return thisByteArray()->mid(pos,len);
+}
+
+QScriptValue ByteArrayPrototype::remove(int pos, int len) {
+ thisByteArray()->remove(pos,len);
+ return thisObject();
+}
+
+QByteArray ByteArrayPrototype::right(int len) const {
+ return thisByteArray()->right(len);
+}
+
+QByteArray ByteArrayPrototype::simplified() const {
+ return thisByteArray()->simplified();
+}
+
+QByteArray ByteArrayPrototype::toBase64() const {
+ return thisByteArray()->toBase64();
+}
+
+QByteArray ByteArrayPrototype::toLower() const {
+ return thisByteArray()->toLower();
+}
+
+QByteArray ByteArrayPrototype::toUpper() const {
+ return thisByteArray()->toUpper();
+}
+
+QByteArray ByteArrayPrototype::trimmed() const {
+ return thisByteArray()->trimmed();
+}
+
+void ByteArrayPrototype::truncate(int pos) {
+ thisByteArray()->truncate(pos);
+}
+
+QString ByteArrayPrototype::toLatin1String() const {
+ return QString::fromLatin1(*thisByteArray());
+}
+
+QScriptValue ByteArrayPrototype::valueOf() const {
+ return thisObject().data();
+}
+
diff --git a/trunk/qtscript_types/bytearrayprototype.h b/trunk/qtscript_types/bytearrayprototype.h
new file mode 100644
index 0000000..adc2a5e
--- /dev/null
+++ b/trunk/qtscript_types/bytearrayprototype.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
+* *
+* Derived from code by Nokia Corporation and/or its subsidiary(-ies) under a *
+* compatible license: *
+* *
+* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). *
+* All rights reserved. *
+* *
+* 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 BYTEARRAYPROTOTYPE_H
+#define BYTEARRAYPROTOTYPE_H
+
+#include <QByteArray>
+#include <QObject>
+#include <QtScript/QScriptable>
+#include <QtScript/QScriptValue>
+
+class ByteArrayPrototype : public QObject, public QScriptable {
+ Q_OBJECT
+
+ public:
+ ByteArrayPrototype(QObject *p_parent=0);
+ ~ByteArrayPrototype();
+
+ public slots:
+ void chop(int n);
+ bool equals(const QByteArray &other);
+ QByteArray left(int len) const;
+ QByteArray mid(int pos, int len = -1) const;
+ QScriptValue remove(int pos, int len);
+ QByteArray right(int len) const;
+ QByteArray simplified() const;
+ QByteArray toBase64() const;
+ QByteArray toLower() const;
+ QByteArray toUpper() const;
+ QByteArray trimmed() const;
+ void truncate(int pos);
+ QString toLatin1String() const;
+ QScriptValue valueOf() const;
+
+ private:
+ QByteArray *thisByteArray() const;
+};
+
+#endif // BYTEARRAYPROTOTYPE_H
+
diff --git a/trunk/registryhive.cpp b/trunk/registryhive.cpp
index 9bdc439..b50b46f 100644
--- a/trunk/registryhive.cpp
+++ b/trunk/registryhive.cpp
@@ -1,7 +1,459 @@
+/*******************************************************************************
+* fred Copyright (c) 2011 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"
-RegistryHive::RegistryHive(QObject *p_parent)
- : QObject(p_parent)
+#include <QStringList>
+
+#include <stdlib.h>
+
+/*
+ * 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;
+}
+
+/*
+ * 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);
+}
+
+/*
+ * 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());
+ //ret=QString().sprintf("0x%08X",value.toUInt());
+ break;
+ case hive_t_REG_DWORD_BIG_ENDIAN:
+ // DWORD (32 bit integer), big endian
+ ret=QString().sprintf("0x%08X",*(uint32_t*)value.constData());
+ //ret=QString().sprintf("0x%08X",value.toUInt());
+ 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().sprintf("0x%016X",*(uint64_t*)value.constData());
+ //ret=QString().sprintf("0x%08X",value.toULongLong());
+ break;
+ default:
+ ToHexStr();
+ }
+
+ #undef ToHexStr
+
+ 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;
+}
+
+/*
+ * 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++) {
+ *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;
+}
+
+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;
}
diff --git a/trunk/registryhive.h b/trunk/registryhive.h
index 6209422..dde94a5 100644
--- a/trunk/registryhive.h
+++ b/trunk/registryhive.h
@@ -1,20 +1,73 @@
+/*******************************************************************************
+* fred Copyright (c) 2011 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:
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);
+
+ 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);
+ static QString KeyValueToString(QByteArray &value, int value_type);
+ static QString KeyTypeToString(int value_type);
- signals:
+ private:
+ QString erro_msg;
+ bool is_error;
+ QString hive_file;
+ hive_h *p_hive;
+ bool is_hive_open;
- public slots:
+ 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);
};
#endif // REGISTRYHIVE_H
diff --git a/trunk/registrykeytablemodel.cpp b/trunk/registrykeytablemodel.cpp
index ba591fe..107af1e 100644
--- a/trunk/registrykeytablemodel.cpp
+++ b/trunk/registrykeytablemodel.cpp
@@ -1,310 +1,293 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 "registrykeytablemodel.h"
#include <stdlib.h>
-RegistryKeyTableModel::RegistryKeyTableModel(hive_h *hhive,
- hive_node_h hive_node,
+RegistryKeyTableModel::RegistryKeyTableModel(RegistryHive *p_hive,
+ QString node_path,
QObject *p_parent)
: QAbstractTableModel(p_parent)
{
// Create the "root" key. It's values will be used for as header values.
this->p_keys=new RegistryKey(QList<QVariant>()<<
tr("Key")<<tr("Type")<<tr("Value"));
// Build key list
- this->SetupModelData(hhive,hive_node);
+ this->SetupModelData(p_hive,node_path);
}
RegistryKeyTableModel::~RegistryKeyTableModel() {
delete this->p_keys;
}
QVariant RegistryKeyTableModel::data(const QModelIndex &index, int role) const {
bool ok;
if(!index.isValid()) return QVariant();
RegistryKey *p_key=static_cast<RegistryKey*>(index.internalPointer());
switch(role) {
case Qt::DisplayRole: {
switch(index.column()) {
case RegistryKeyTableModel::ColumnContent_KeyName: {
return p_key->Data(index.column());
break;
}
case RegistryKeyTableModel::ColumnContent_KeyType: {
int value_type=p_key->Data(index.column()).toInt(&ok);
if(!ok) return QVariant();
return this->TypeToString(value_type);
break;
}
case RegistryKeyTableModel::ColumnContent_KeyValue: {
// Get index to value type
QModelIndex type_index=this->index(index.row(),
RegistryKeyTableModel::
ColumnContent_KeyType);
// Get value type
int value_type=this->data(type_index,
RegistryKeyTableModel::
AdditionalRoles_GetRawData).toInt(&ok);
if(!ok) return QVariant();
// Return value converted to human readeable string
QByteArray value_array=p_key->Data(index.column()).toByteArray();
return this->ValueToString(value_array,value_type);
break;
}
default:
return QVariant();
}
break;
}
case RegistryKeyTableModel::AdditionalRoles_GetRawData: {
return p_key->Data(index.column());
break;
}
default:
return QVariant();
}
-
- /*
- if(role!=Qt::DisplayRole) return QVariant();
-
- RegistryKey *p_key=static_cast<RegistryKey*>(index.internalPointer());
-
- return p_key->Data(index.column());
- */
}
Qt::ItemFlags RegistryKeyTableModel::flags(const QModelIndex &index) const {
if(!index.isValid()) return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant RegistryKeyTableModel::headerData(int section,
Qt::Orientation orientation,
int role) const
{
// Only horizontal header is supported
if(orientation!=Qt::Horizontal) return QVariant();
switch(role) {
case Qt::TextAlignmentRole:
// Handle text alignment
if(section==2) return Qt::AlignLeft;
else return Qt::AlignCenter;
break;
case Qt::DisplayRole:
// Header text
return this->p_keys->Data(section);
break;
default:
return QVariant();
}
}
QModelIndex RegistryKeyTableModel::index(int row,
int column,
const QModelIndex &parent) const
{
if(!this->hasIndex(row,column,parent)) return QModelIndex();
RegistryKey *p_key=this->p_keys->Key(row);
return this->createIndex(row,column,p_key);
}
int RegistryKeyTableModel::rowCount(const QModelIndex &parent) const {
// According to Qt doc, when parent in TableModel is valid, we should return 0
if(parent.isValid()) return 0;
// Get and return row count from the keys list
return this->p_keys->RowCount();
}
int RegistryKeyTableModel::columnCount(const QModelIndex &parent) const {
// According to Qt doc, when parent in TableModel is valid, we should return 0
if(parent.isValid()) return 0;
// There are always 3 columns
return 3;
}
-void RegistryKeyTableModel::SetupModelData(hive_h *hhive,
- hive_node_h hive_node)
+void RegistryKeyTableModel::SetupModelData(RegistryHive *p_hive,
+ QString &node_path)
{
- int i=0;
+ QMap<QString,int> node_keys;
RegistryKey *p_key;
- char *p_key_name;
- char *key_value;
+ QByteArray key_value;
int key_value_type;
size_t key_value_len;
- // Get all (key,value) pairs for current node
- hive_value_h *node_keys=hivex_node_values(hhive,hive_node);
- if(node_keys==NULL) return;
-
- // Add all (key,value) pairs to the key list
- while(node_keys[i]) {
- // Get key name
- p_key_name=hivex_value_key(hhive,node_keys[i]);
- if(p_key_name==NULL) continue;
- // Get key value and type
- key_value=hivex_value_value(hhive,
- node_keys[i],
- (hive_type*)&key_value_type,
- &key_value_len);
- if(key_value==NULL) continue;
-
- // Add infos to key list
+ // Get all keys for current node
+ node_keys=p_hive->GetKeys(node_path);
+ if(node_keys.isEmpty()) return;
+
+ // Add all keys to list
+ QMapIterator<QString,int> i(node_keys);
+ while(i.hasNext()) {
+ i.next();
+ key_value=p_hive->GetKeyValue(i.value(),
+ &key_value_type,
+ &key_value_len);
+ if(p_hive->GetErrorMsg()!="") continue;
p_key=new RegistryKey(QList<QVariant>()<<
- QString(strlen(p_key_name) ?
- p_key_name : "(default)")<<
+ QString(i.key().length() ? i.key() : "(default)")<<
QVariant(key_value_type)<<
- QByteArray(key_value,key_value_len));
+ key_value);
this->p_keys->Append(p_key);
- i++;
}
- free(node_keys);
}
QString RegistryKeyTableModel::ValueToString(QByteArray &value,
int value_type) const
{
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());
//ret=QString().sprintf("0x%08X",value.toUInt());
break;
case hive_t_REG_DWORD_BIG_ENDIAN:
// DWORD (32 bit integer), big endian
ret=QString().sprintf("0x%08X",*(uint32_t*)value.constData());
//ret=QString().sprintf("0x%08X",value.toUInt());
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().sprintf("0x%016X",*(uint64_t*)value.constData());
//ret=QString().sprintf("0x%08X",value.toULongLong());
break;
default:
ToHexStr();
}
#undef ToHexStr
return ret;
}
QString RegistryKeyTableModel::TypeToString(int value_type) const {
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;
}
diff --git a/trunk/registrykeytablemodel.h b/trunk/registrykeytablemodel.h
index f1db258..9945162 100644
--- a/trunk/registrykeytablemodel.h
+++ b/trunk/registrykeytablemodel.h
@@ -1,68 +1,67 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 REGISTRYKEYTABLEMODEL_H
#define REGISTRYKEYTABLEMODEL_H
#include <QAbstractTableModel>
#include "registrykey.h"
-
-#include <hivex.h>
+#include "registryhive.h"
class RegistryKeyTableModel : public QAbstractTableModel {
Q_OBJECT
public:
enum AdditionalRoles {
AdditionalRoles_GetRawData=Qt::UserRole
};
- RegistryKeyTableModel(hive_h *hhive,
- hive_node_h hive_node,
+ RegistryKeyTableModel(RegistryHive *p_hive,
+ QString node_path,
QObject *p_parent=0);
~RegistryKeyTableModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section,
Qt::Orientation orientation,
int role=Qt::DisplayRole) const;
QModelIndex index(int row,
int column,
const QModelIndex &parent=QModelIndex()) const;
int rowCount(const QModelIndex &parent=QModelIndex()) const;
int columnCount(const QModelIndex &parent=QModelIndex()) const;
private:
enum ColumnContent {
ColumnContent_KeyName=0,
ColumnContent_KeyType,
ColumnContent_KeyValue
};
RegistryKey *p_keys;
- void SetupModelData(hive_h *hhive, hive_node_h hive_node);
+ void SetupModelData(RegistryHive *p_hive, QString &node_path);
QString ValueToString(QByteArray &value, int value_type) const;
QString TypeToString(int value_type) const;
};
#endif // REGISTRYKEYTABLEMODEL_H
diff --git a/trunk/registrynodetreemodel.cpp b/trunk/registrynodetreemodel.cpp
index 5b76508..078d5ac 100644
--- a/trunk/registrynodetreemodel.cpp
+++ b/trunk/registrynodetreemodel.cpp
@@ -1,140 +1,138 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 "registrynodetreemodel.h"
#include <stdlib.h>
-RegistryNodeTreeModel::RegistryNodeTreeModel(hive_h *hhive,
- hive_node_h hive_root_node,
+RegistryNodeTreeModel::RegistryNodeTreeModel(RegistryHive *p_hive,
QObject *p_parent)
: QAbstractItemModel(p_parent)
{
- Q_UNUSED(p_parent);
+ // Create root node
this->p_root_node=new RegistryNode("ROOT");
- this->SetupModelData(hhive,
- hive_root_node,
- this->p_root_node);
+ // Build node list
+ this->SetupModelData(p_hive,this->p_root_node);
}
RegistryNodeTreeModel::~RegistryNodeTreeModel() {
delete this->p_root_node;
}
QVariant RegistryNodeTreeModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid()) return QVariant();
if(role!=Qt::DisplayRole) return QVariant();
RegistryNode *p_node=static_cast<RegistryNode*>(index.internalPointer());
return p_node->data();
}
Qt::ItemFlags RegistryNodeTreeModel::flags(const QModelIndex &index) const {
if(!index.isValid()) return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant RegistryNodeTreeModel::headerData(int section,
Qt::Orientation orientation,
int role) const
{
Q_UNUSED(section);
if(orientation==Qt::Horizontal && role==Qt::DisplayRole) {
return QVariant("Registry key folders");
} else {
return QVariant();
}
}
QModelIndex RegistryNodeTreeModel::index(int row,
int column,
const QModelIndex &parent) const
{
if(!this->hasIndex(row,column,parent)) return QModelIndex();
RegistryNode *p_parent_node;
if(!parent.isValid()) {
p_parent_node=this->p_root_node;
} else {
p_parent_node=static_cast<RegistryNode*>(parent.internalPointer());
}
RegistryNode *p_child_node=p_parent_node->child(row);
if(p_child_node) {
return this->createIndex(row,column,p_child_node);
} else {
return QModelIndex();
}
}
QModelIndex RegistryNodeTreeModel::parent(const QModelIndex &index) const {
if(!index.isValid()) return QModelIndex();
RegistryNode *p_child_node=
static_cast<RegistryNode*>(index.internalPointer());
RegistryNode *p_parent_node=p_child_node->parent();
if(p_parent_node==this->p_root_node) {
return QModelIndex();
} else {
return this->createIndex(p_parent_node->row(),0,p_parent_node);
}
}
int RegistryNodeTreeModel::rowCount(const QModelIndex &parent) const {
if(parent.column()>0) return 0;
RegistryNode *p_parent_node;
if(!parent.isValid()) {
p_parent_node=this->p_root_node;
} else {
p_parent_node=static_cast<RegistryNode*>(parent.internalPointer());
}
return p_parent_node->childCount();
}
int RegistryNodeTreeModel::columnCount(const QModelIndex &parent) const {
Q_UNUSED(parent);
return 1;
}
-void RegistryNodeTreeModel::SetupModelData(hive_h *hhive,
- hive_node_h hive_node,
- RegistryNode *p_parent)
+void RegistryNodeTreeModel::SetupModelData(RegistryHive *p_hive,
+ RegistryNode *p_parent,
+ int hive_node)
{
- int i=0;
+ QMap<QString,int> hive_children;
RegistryNode *p_node;
// Get all sub nodes of current hive node
- hive_node_h *p_hive_children=hivex_node_children(hhive,hive_node);
- if(p_hive_children==NULL) return;
+ if(hive_node) hive_children=p_hive->GetNodes(hive_node);
+ else hive_children=p_hive->GetNodes("\\");
+ if(hive_children.isEmpty()) return;
// Recursivly iterate over all sub nodes
- while(p_hive_children[i]) {
- p_node=new RegistryNode(QString(hivex_node_name(hhive,p_hive_children[i])),
- p_parent);
+ QMapIterator<QString, int> i(hive_children);
+ while(i.hasNext()) {
+ i.next();
+ p_node=new RegistryNode(i.key(),p_parent);
p_parent->AppendChild(p_node);
- this->SetupModelData(hhive,p_hive_children[i],p_node);
- i++;
+ this->SetupModelData(p_hive,p_node,i.value());
}
- free(p_hive_children);
}
diff --git a/trunk/registrynodetreemodel.h b/trunk/registrynodetreemodel.h
index 63fa1b6..941407f 100644
--- a/trunk/registrynodetreemodel.h
+++ b/trunk/registrynodetreemodel.h
@@ -1,58 +1,56 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 REGISTRYNODETREEMODEL_H
#define REGISTRYNODETREEMODEL_H
#include <QAbstractItemModel>
#include "registrynode.h"
-
-#include <hivex.h>
+#include "registryhive.h"
class RegistryNodeTreeModel : public QAbstractItemModel {
Q_OBJECT
public:
- RegistryNodeTreeModel(hive_h *hhive,
- hive_node_h hive_root_node,
- QObject *p_parent=0);
+ RegistryNodeTreeModel(RegistryHive *p_hive, QObject *p_parent=0);
~RegistryNodeTreeModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section,
Qt::Orientation orientation,
int role=Qt::DisplayRole) const;
QModelIndex index(int row,
int column,
const QModelIndex &parent=QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent=QModelIndex()) const;
int columnCount(const QModelIndex &parent=QModelIndex()) const;
private:
- void SetupModelData(hive_h *hhive,
- hive_node_h hive_node,
- RegistryNode *p_parent);
RegistryNode *p_root_node;
+
+ void SetupModelData(RegistryHive *p_hive,
+ RegistryNode *p_parent,
+ int hive_node=0);
};
#endif // REGISTRYNODETREEMODEL_H
diff --git a/trunk/report_templates/SAM_UserAccounts.fred b/trunk/report_templates/SAM_UserAccounts.fred
deleted file mode 100644
index 101db46..0000000
--- a/trunk/report_templates/SAM_UserAccounts.fred
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<report category="SAM" name="User accounts">
- <foreach path="SAM/Domains/Account/Users/Names/*" vars="(default),type">
- <paragraph title="[var::0]" type="string">
- <value name="Last login" key="SAM/Domains/Account/Users/[var::1]/F" type="win64time" offset="8" />
- </paragraph>
- </foreach>
-</report>
-
diff --git a/trunk/report_templates/SOFTWARE_WindowsVersion.js b/trunk/report_templates/SOFTWARE_WindowsVersion.js
new file mode 100644
index 0000000..b27cc88
--- /dev/null
+++ b/trunk/report_templates/SOFTWARE_WindowsVersion.js
@@ -0,0 +1,19 @@
+println("<html>");
+println(" <head><title>Windows version info</title></head>");
+println(" <body>");
+println(" <h2>Windows version info</h2>");
+println(" <p>");
+
+var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","ProductName");
+var value_len=val.length;
+print("ProductVersion: ");
+println(RegistryKeyValueToString(val.value,val.type));
+
+
+//for(var i=0;i<(val.length-1);i+=2) {
+// print(String.fromCharCode(val.value[i]));
+//}
+
+println(" </p>");
+println("</html>");
+
diff --git a/trunk/reporttemplatexmlhandler.cpp b/trunk/reporttemplatexmlhandler.cpp
deleted file mode 100644
index 8137f7d..0000000
--- a/trunk/reporttemplatexmlhandler.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/*******************************************************************************
-* fred Copyright (c) 2011 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 <stdlib.h>
-
-#include "reporttemplatexmlhandler.h"
-
-ReportTemplateXmlHandler::ReportTemplateXmlHandler(hive_h *hive_handle,
- bool only_get_info)
- : QXmlDefaultHandler()
-{
- this->hhive=hive_handle;
- this->get_info=only_get_info;
-}
-
-ReportTemplateXmlHandler::~ReportTemplateXmlHandler() {
- qDeleteAll(this->report_data);
-}
-
-bool ReportTemplateXmlHandler::startDocument() {
- this->report_category="";
- this->report_name="";
- this->report_content="";
- this->report_data.clear();
- return true;
-}
-
-bool ReportTemplateXmlHandler::startElement(const QString &namespaceURI,
- const QString &localName,
- const QString &qName,
- const QXmlAttributes &atts)
-{
- Q_UNUSED(namespaceURI);
- Q_UNUSED(localName);
- int i=0;
- bool ok;
-
- // If we should only extract report info...
- if(this->get_info) {
- if(qName=="report") {
- this->report_category=atts.value(QString("category"));
- this->report_name=atts.value(QString("name"));
- }
- return true;
- }
-
- // Check element
- if(qName=="foreach") {
- ok=this->ProcessForEach(atts.value(QString("path")),
- atts.value(QString("vars")),
- hivex_root(this->hhive));
- if(!ok) return false;
- } else if (qName=="paragraph") {
-
- } else if (qName=="value") {
-
- }
-
- /*
- qDebug("%s",QString("--> %3").arg(qName).toAscii().constData());
- for(i=0;i<atts.count();i++) {
- qDebug("%s",QString("----> Name: '%1'', Value: '%2'").arg(atts.qName(i),atts.value(i)).toAscii().constData());
- }
- */
-
- return true;
-}
-
-bool ReportTemplateXmlHandler::endElement(const QString &namespaceURI,
- const QString &localName,
- const QString &qName)
-{
- Q_UNUSED(namespaceURI);
- Q_UNUSED(localName);
- if(this->get_info) return true;
-
- if(qName=="foreach") {
-
- } else if (qName=="paragraph") {
-
- } else if (qName=="value") {
-
- }
-
- return true;
-}
-
-bool ReportTemplateXmlHandler::error(const QXmlParseException &exception) {
- qDebug("error: %u: %s",exception.lineNumber(),exception.message().toAscii().constData());
- return false;
-}
-
-bool ReportTemplateXmlHandler::fatalError(const QXmlParseException &exception) {
- qDebug("fatalerror: %u: %s",exception.lineNumber(),exception.message().toAscii().constData());
- return false;
-}
-
-QString ReportTemplateXmlHandler::GetReportCategory() {
- return this->report_category;
-}
-
-QString ReportTemplateXmlHandler::GetReportName() {
- return this->report_name;
-}
-
-QString ReportTemplateXmlHandler::ReportData() {
- return QString();
-}
-
-bool ReportTemplateXmlHandler::ProcessForEach(QString path,
- QString vars,
- hive_node_h cur_hive_node,
- bool iterate) {
- int i=0,ii=0;
- bool ok;
-
- if(!iterate) {
- QStringList nodes=path.split('/');
- if(cur_hive_node==0) return false;
-
- for(i=0;i<nodes.count();i++) {
- if(nodes.value(i)!="*") {
- cur_hive_node=hivex_node_get_child(this->hhive,
- cur_hive_node,
- nodes.value(i).toAscii().
- constData());
- if(cur_hive_node==0) return false;
- } else {
- QString new_path="";
- for(ii=i+1;ii<nodes.count();ii++) {
- new_path.append(nodes.value(ii)).append("/");
- }
- new_path.chop(1);
- ok=this->ProcessForEach(new_path,vars,cur_hive_node,true);
- if(!ok) return false;
- }
- }
- } else {
- hive_node_h *p_child_nodes=hivex_node_children(this->hhive,cur_hive_node);
- i=0;
- while(p_child_nodes[i]) {
- // Save iterator node
- ReportTemplateData *p_data;
- char *p_node_name=hivex_node_name(this->hhive,p_child_nodes[i]);
- // TODO: Check for NULL value
- p_data->vars.append(p_node_name);
- // TODO: Add custom vars
- QStringList var_pairs=vars.split(';');
- for(ii=0;ii<var_pairs.count();ii++) {
- QString var_name=var_pairs.value(ii).split(',').value(0);
- QString var_type=var_pairs.value(ii).split(',').value(1);
- QVariant var_content="";
-
- if(var_name=="(default)") var_name="";
-
- int type=0;
- size_t len=0;
-
- hive_value_h hive_key=hivex_node_get_value(this->hhive,
- cur_hive_node,
- var_name.toAscii().constData());
-
- if(var_type=="type") {
- char *data=hivex_value_value(this->hhive,hive_key,(hive_type*)&type,&len);
- var_content=QString().sprintf("%08u",type);
-
- qDebug("Save var '%s' with content '%08u'",var_name.toAscii().constData(),type);
-
- free(data);
- } else if(var_type=="value") {
- char *data=hivex_value_value(this->hhive,hive_key,(hive_type*)&type,&len);
- var_content=QByteArray(data);
- }
- }
-
-
- this->report_data.append(p_data);
- i++;
- }
- free(p_child_nodes);
- }
-
- return true;
-}
-
-bool ReportTemplateXmlHandler::ProcessParagraph() {
- return true;
-}
-
-bool ReportTemplateXmlHandler::ProcessValue() {
- return true;
-}
diff --git a/trunk/reporttemplatexmlhandler.h b/trunk/reporttemplatexmlhandler.h
deleted file mode 100644
index 17b9b00..0000000
--- a/trunk/reporttemplatexmlhandler.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*******************************************************************************
-* fred Copyright (c) 2011 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 REPORTTEMPLATEXMLHANDLER_H
-#define REPORTTEMPLATEXMLHANDLER_H
-
-#include <QtXml/QXmlDefaultHandler>
-#include <QVariant>
-
-#include <hivex.h>
-
-class ReportTemplateData {
- public:
- ReportTemplateData() {
- this->vars.clear();
- this->data.clear();
- }
- ~ReportTemplateData() {
- qDeleteAll(this->data);
- }
-
- QList<QVariant> vars;
- QList<ReportTemplateData*> data;
-};
-
-class ReportTemplateXmlHandler : public QXmlDefaultHandler {
-
- public:
- explicit ReportTemplateXmlHandler(hive_h *hive_handle=NULL,
- bool only_get_info=true);
- ~ReportTemplateXmlHandler();
-
- bool startDocument();
- bool startElement(const QString &namespaceURI,
- const QString &localName,
- const QString &qName,
- const QXmlAttributes &atts);
- bool endElement(const QString &namespaceURI,
- const QString &localName,
- const QString &qName);
- bool error(const QXmlParseException &exception);
- bool fatalError(const QXmlParseException &exception);
-
- QString GetReportCategory();
- QString GetReportName();
- QString ReportData();
-
- private:
- hive_h *hhive;
- bool get_info;
- QString report_category;
- QString report_name;
- QString report_content;
- QList<ReportTemplateData*> report_data;
-
- bool ProcessForEach(QString path,
- QString vars,
- hive_node_h cur_hive_node,
- bool iterate=false);
- bool ProcessParagraph();
- bool ProcessValue();
-};
-
-#endif // REPORTTEMPLATEXMLHANDLER_H

File Metadata

Mime Type
text/x-diff
Expires
Tue, Sep 16, 5:45 PM (1 d, 3 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1319320
Default Alt Text
(144 KB)

Event Timeline