Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F6265618
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
105 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/trunk/datareporter.cpp b/trunk/datareporter.cpp
index a37fe85..73013bc 100644
--- a/trunk/datareporter.cpp
+++ b/trunk/datareporter.cpp
@@ -1,200 +1,200 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "datareporter.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 dir) {
QString report_template="";
int i=0;
int ii=0;
bool found=false;
QString report_category="";
QString report_name="";
ReportTemplate *p_report;
// Get all template files in report_templates directory
QDir report_dir(dir);
QStringList found_report_templates=report_dir.
entryList(QStringList()<<"*.qs");
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));
// Extract report category and name from file name (<category>_<name>.qs)
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("."));
// Check if a report with the same category/name was already added
found=false;
for(ii=0;ii<this->report_templates.count();ii++) {
if(this->report_templates.at(ii)->Category()==report_category &&
this->report_templates.at(ii)->Name()==report_name)
{
found=true;
break;
}
}
if(!found) {
// Add report to list
p_report=new ReportTemplate(report_category,
report_name,
report_template);
this->report_templates.append(p_report);
} else {
// Update report entry
p_report=this->report_templates.at(ii);
p_report->SetFile(report_template);
}
}
}
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(RegistryHive *p_hive,
QString report_category,
QString report_name)
{
int i=0;
ReportTemplate *p_report;
// Search report template
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;
}
// Report template was found, now generate report and return result
return this->GenerateReport(p_hive,p_report->File());
}
// Report template couldn't be found
QMessageBox::critical(0,
"Report engine error",
QString("Unable to find report with name '%1' in category '%2'!")
.arg(report_name)
.arg(report_category));
return QString();
}
QString DataReporter::GenerateReport(RegistryHive *p_hive,
QString report_template,
bool console_mode)
{
QString report_code;
// Init data reporter engine
DataReporterEngine engine(p_hive);
QScriptValue hive_value=engine.newQObject(p_hive);
engine.globalObject().setProperty("RegistryHive",hive_value);
// Open report template
QFile template_file(report_template);
if(!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
if(!console_mode) {
QMessageBox::critical(0,
"Report engine error",
QString("Couldn't open report template file '%1'!")
.arg(report_template));
} else {
printf("ERROR: Couldn't open report template file '%s'!\n",
report_template.toAscii().constData());
}
return QString();
}
// Read template file
QTextStream in(&template_file);
while(!in.atEnd()) report_code.append(in.readLine()).append("\n");
// Close report template file
template_file.close();
// Execute report template script
QScriptValue report_result=engine.evaluate(report_code,report_template);
if (report_result.isError() || engine.hasUncaughtException()) {
if(!console_mode) {
QMessageBox::critical(0,
"Report engine error",
- QString::fromLatin1("%0:%1: %2")
+ QString::fromLatin1("File: %0\n Line: %1\nError: %2")
.arg(report_template)
.arg(report_result.property("lineNumber")
.toInt32())
.arg(report_result.toString()));
} else {
printf("ERROR: %s:%u: %s\n",
report_template.toAscii().constData(),
report_result.property("lineNumber").toInt32(),
report_result.toString().toAscii().constData());
}
return QString();
}
return engine.report_content;
}
diff --git a/trunk/datareporterengine.cpp b/trunk/datareporterengine.cpp
index 128a962..15697fe 100644
--- a/trunk/datareporterengine.cpp
+++ b/trunk/datareporterengine.cpp
@@ -1,325 +1,361 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "datareporterengine.h"
#include <QString>
#include <QMap>
#include <QMapIterator>
#include <QStringList>
+#include <QDateTime>
#include <stdio.h>
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);
// GetRegistryNodes
QScriptValue func_get_nodes=this->newFunction(this->GetRegistryNodes,1);
func_get_nodes.setData(this->newQObject(this->p_registry_hive));
this->globalObject().setProperty("GetRegistryNodes",func_get_nodes);
// GetRegistryKeys
QScriptValue func_get_keys=this->newFunction(this->GetRegistryKeys,1);
func_get_keys.setData(this->newQObject(this->p_registry_hive));
this->globalObject().setProperty("GetRegistryKeys",func_get_keys);
// GetRegistryKeyValue
QScriptValue func_get_key_value=this->newFunction(this->GetRegistryKeyValue,
2);
func_get_key_value.setData(this->newQObject(this->p_registry_hive));
this->globalObject().setProperty("GetRegistryKeyValue",func_get_key_value);
+ // GetRegistryKeyModTime
+ QScriptValue func_get_key_modt=this->newFunction(this->GetRegistryKeyModTime,
+ 2);
+ func_get_key_modt.setData(this->newQObject(this->p_registry_hive));
+ this->globalObject().setProperty("GetRegistryKeyModTime",func_get_key_modt);
// RegistryKeyValueToString
QScriptValue func_value_to_string=
this->newFunction(this->RegistryKeyValueToString,2);
this->globalObject().setProperty("RegistryKeyValueToString",
func_value_to_string);
// RegistryKeyValueToVariant
QScriptValue func_value_to_variant=
this->newFunction(this->RegistryKeyValueToVariant);
this->globalObject().setProperty("RegistryKeyValueToVariant",
func_value_to_variant);
// RegistryKeyTypeToString
QScriptValue func_type_to_string=
this->newFunction(this->RegistryKeyTypeToString,1);
this->globalObject().setProperty("RegistryKeyTypeToString",
func_type_to_string);
}
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();
}
/*
* GetRegistryNodes
*/
QScriptValue DataReporterEngine::GetRegistryNodes(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QMap<QString,int> nodes;
QScriptValue ret_nodes;
int ii=0;
// This function needs one argument, parent node path
if(context->argumentCount()!=1) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
// Get nodes
nodes=p_hive->GetNodes(context->argument(0).toString());
if(p_hive->Error()) {
// Clear error state
p_hive->GetErrorMsg();
return engine->undefinedValue();
}
// Build script array
ret_nodes=engine->newArray(nodes.count());
QMapIterator<QString,int> i(nodes);
while(i.hasNext()) {
i.next();
ret_nodes.setProperty(ii++,QScriptValue(i.key()));
}
return ret_nodes;
}
/*
* GetRegistryKeys
*/
QScriptValue DataReporterEngine::GetRegistryKeys(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QMap<QString,int> keys;
QScriptValue ret_keys;
int ii=0;
// This function needs one argument, parent node path
if(context->argumentCount()!=1) return engine->undefinedValue();
// Get calle data (Pointer to RegistryHive class)
calleeData=context->callee().data();
p_hive=qobject_cast<RegistryHive*>(calleeData.toQObject());
// Get keys
keys=p_hive->GetKeys(context->argument(0).toString());
if(p_hive->Error()) {
// Clear error state
p_hive->GetErrorMsg();
return engine->undefinedValue();
}
// Build script array
ret_keys=engine->newArray(keys.count());
QMapIterator<QString,int> i(keys);
while(i.hasNext()) {
i.next();
ret_keys.setProperty(ii++,QScriptValue(i.key()));
}
return ret_keys;
}
/*
* RegistryKeyValueToScript
*/
QScriptValue 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, but it probably does ;)
s.value=qvariant_cast<QByteArray>(obj.property("value").data().toVariant());
}
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()) {
// Get error message to clear error state
p_hive->GetErrorMsg();
// printf("\nError: %s\n",p_hive->GetErrorMsg().toAscii().constData());
return engine->undefinedValue();
}
// Save key value to s_RegistryKeyValue struct
script_key_value.type=key_type;
script_key_value.length=key_length;
script_key_value.value=key_value;
return 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();
// Cast ByteArray argument to QByteArray and convert
key_value=qvariant_cast<QByteArray>(context->argument(0).data().toVariant());
ret=RegistryHive::KeyValueToString(key_value,
context->argument(1).toInt32());
return engine->newVariant(ret);
}
QScriptValue DataReporterEngine::RegistryKeyValueToVariant(
QScriptContext *context,
QScriptEngine *engine)
{
int offset=0;
int length=-1;
QByteArray key_value;
QString format="";
QString ret="";
// This function needs at least two arguments, key value and variant type,
// and may have two optional arguments, offset and length
if(context->argumentCount()<2 || context->argumentCount()>4) {
return engine->undefinedValue();
}
if(context->argumentCount()==3) {
offset=context->argument(2).toInt32();
}
if(context->argumentCount()==4) {
offset=context->argument(2).toInt32();
length=context->argument(3).toInt32();
}
// Cast ByteArray argument to QByteArray
key_value=qvariant_cast<QByteArray>(context->argument(0).data().toVariant());
format=context->argument(1).toString();
ret=RegistryHive::KeyValueToString(key_value,format,offset,length);
return engine->newVariant(ret);
}
QScriptValue DataReporterEngine::RegistryKeyTypeToString(
QScriptContext *context,
QScriptEngine *engine)
{
QString ret="";
// This function needs one arguments, key type
if(context->argumentCount()!=1) return engine->undefinedValue();
ret=RegistryHive::KeyTypeToString(context->argument(0).toInt32());
return engine->newVariant(ret);
}
+
+QScriptValue DataReporterEngine::GetRegistryKeyModTime(
+ QScriptContext *context,
+ QScriptEngine *engine)
+{
+ QScriptValue calleeData;
+ RegistryHive *p_hive;
+ int64_t mod_time=0;
+
+ // This function needs two argument, 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());
+
+ mod_time=p_hive->GetKeyModTime(context->argument(0).toString(),
+ context->argument(1).toString());
+ if(p_hive->Error()) {
+ // Get error message to clear error state
+ p_hive->GetErrorMsg();
+ return engine->undefinedValue();
+ }
+
+ QDateTime date_time;
+ date_time.setTimeSpec(Qt::UTC);
+ date_time.setTime_t(RegistryHive::FiletimeToUnixtime(mod_time));
+
+ return engine->newVariant(date_time.toString("yyyy/MM/dd hh:mm:ss"));
+}
diff --git a/trunk/datareporterengine.h b/trunk/datareporterengine.h
index 321a84f..3891185 100644
--- a/trunk/datareporterengine.h
+++ b/trunk/datareporterengine.h
@@ -1,74 +1,76 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef 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:
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 GetRegistryNodes(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue GetRegistryKeys(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToScript(QScriptEngine *engine,
const s_RegistryKeyValue &s);
static void RegistryKeyValueFromScript(const QScriptValue &obj,
s_RegistryKeyValue &s);
static QScriptValue GetRegistryKeyValue(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToString(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyValueToVariant(QScriptContext *context,
QScriptEngine *engine);
static QScriptValue RegistryKeyTypeToString(QScriptContext *context,
QScriptEngine *engine);
+ static QScriptValue GetRegistryKeyModTime(QScriptContext *context,
+ QScriptEngine *engine);
};
Q_DECLARE_METATYPE(DataReporterEngine::s_RegistryKeyValue)
#endif // DATAREPORTERENGINE_H
diff --git a/trunk/registryhive.cpp b/trunk/registryhive.cpp
index 843b5a8..c92e269 100644
--- a/trunk/registryhive.cpp
+++ b/trunk/registryhive.cpp
@@ -1,612 +1,638 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registryhive.h"
#include <QStringList>
#include <QDateTime>
#include <stdlib.h>
#include <stdio.h>
// TODO: __WORDSIZE is not defined under mingw and I currently have no idea how
// to identify a 64bit windows
#ifndef __WORDSIZE
#define __WORDSIZE 32
#endif
#if __WORDSIZE == 64
#define EPOCH_DIFF 0x19DB1DED53E8000
#else
#define EPOCH_DIFF 0x19DB1DED53E8000LL
#endif
/*
* RegistryHive
*/
RegistryHive::RegistryHive(QObject *p_parent) : QObject(p_parent) {
this->erro_msg="";
this->is_error=false;
this->hive_file="";
this->p_hive=NULL;
this->is_hive_open=false;
}
/*
* ~RegistryHive
*/
RegistryHive::~RegistryHive() {
if(this->is_hive_open) this->Close();
}
/*
* Error
*/
bool RegistryHive::Error() {
return this->is_error;
}
/*
* GetErrorMsg
*/
QString RegistryHive::GetErrorMsg() {
QString msg=this->erro_msg;
this->erro_msg="";
this->is_error=false;
return msg;
}
/*
* Open
*/
bool RegistryHive::Open(QString file, bool read_only) {
if(this->is_hive_open) return false;
// Open hive file
this->p_hive=hivex_open(file.toAscii().constData(),
read_only ? 0 : HIVEX_OPEN_WRITE);
if(this->p_hive==NULL) return false;
// Set local vars
this->hive_file=file;
this->is_hive_open=true;
return true;
}
/*
* Close
*/
bool RegistryHive::Close(bool commit_changes) {
if(this->is_hive_open) {
if(commit_changes) {
// Commit changes before closing hive.
// TODO: Maybe it would be more secure to commit changes to a new file and
// then move it over the original one.
hivex_commit(this->p_hive,NULL,0);
}
// As hivex_close will _ALWAYS_ free the handle, we don't need the following
// values anymore
this->hive_file="";
this->is_hive_open=false;
// Close hive
if(hivex_close(this->p_hive)!=0) return false;
}
return true;
}
QString RegistryHive::Filename() {
if(this->is_hive_open) return this->hive_file;
return QString();
}
/*
* GetNodes
*/
QMap<QString,int> RegistryHive::GetNodes(QString path) {
hive_node_h parent_node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QMap<QString,int>();
// Get and return nodes
return this->GetNodesHelper(parent_node);
}
/*
* GetNodes
*/
QMap<QString,int> RegistryHive::GetNodes(int parent_node) {
if(parent_node==0) {
this->SetError(tr("Invalid parent node handle specified!"));
return QMap<QString,int>();
}
// Get and return nodes
return this->GetNodesHelper(parent_node);
}
/*
* GetKeys
*/
QMap<QString,int> RegistryHive::GetKeys(QString path) {
hive_node_h parent_node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QMap<QString,int>();
// Get and return keys
return this->GetKeysHelper(parent_node);
}
/*
* GetKeys
*/
QMap<QString,int> RegistryHive::GetKeys(int parent_node) {
if(parent_node==0) {
this->SetError(tr("Invalid parent node handle specified!"));
return QMap<QString,int>();
}
// Get and return keys
return this->GetKeysHelper(parent_node);
}
/*
* GetKeyValue
*/
QByteArray RegistryHive::GetKeyValue(QString path,
QString key,
int *p_value_type,
size_t *p_value_len)
{
hive_node_h parent_node;
hive_value_h hive_key;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QByteArray();
// Get key handle
hive_key=hivex_node_get_value(this->p_hive,
parent_node,key.toAscii().constData());
if(hive_key==0) {
this->SetError(tr("Unable to get key handle!"));
*p_value_len=-1;
return QByteArray();
}
// Get and return key value
return this->GetKeyValueHelper(hive_key,p_value_type,p_value_len);
}
/*
* GetKeyValue
*/
QByteArray RegistryHive::GetKeyValue(int hive_key,
int *p_value_type,
size_t *p_value_len)
{
if(hive_key==0) {
this->SetError(tr("Invalid key handle specified!"));
*p_value_type=-1;
return QByteArray();
}
// Get and return key value
return this->GetKeyValueHelper(hive_key,p_value_type,p_value_len);
}
+/*
+ * GetKeyModTime
+ */
+int64_t RegistryHive::GetKeyModTime(QString path,QString key) {
+ hive_node_h parent_node;
+ hive_value_h hive_key;
+
+ // Get handle to last node in path
+ if(!this->GetNodeHandle(path,&parent_node)) {
+ this->SetError(tr("Unable to get node handle!"));
+ return 0;
+ }
+
+ // 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!"));
+ return 0;
+ }
+
+ // Get and return key's last modification timestamp
+ return this->GetKeyModTime(hive_key);
+}
+
/*
* GetKeyModTime
*/
int64_t RegistryHive::GetKeyModTime(int hive_key) {
- if(hive_key==0) {
- this->SetError(tr("Invalid key handle specified!"));
- return 0;
- }
+ if(hive_key==0) {
+ this->SetError(tr("Invalid key handle specified!"));
+ return 0;
+ }
- // Get and return key last modification timestamp
- return hivex_node_timestamp(this->p_hive,hive_key);
+ // Get and return key's last modification timestamp
+ return hivex_node_timestamp(this->p_hive,hive_key);
}
/*
* KeyValueToString
*/
QString RegistryHive::KeyValueToString(QByteArray value, int value_type) {
QString ret="";
int i=0;
#define ToHexStr() { \
for(i=0;i<value.size();i++) { \
ret.append(QString().sprintf("%02X ",(uint8_t)(value.constData()[i]))); \
} \
ret.chop(1); \
}
switch(value_type) {
case hive_t_REG_NONE:
// Just a key without a value, but to be certain...
ToHexStr();
break;
case hive_t_REG_SZ:
// A Windows string (encoding is unknown, but often UTF16-LE)
// TODO: What happens if encoding is not UTF16-LE ??? Thx Billy!!!
ret=value.size() ? QString().fromUtf16((ushort*)(value.constData())) : "";
break;
case hive_t_REG_EXPAND_SZ:
// A Windows string that contains %env% (environment variable expansion)
ret=value.size() ? QString().fromUtf16((ushort*)(value.constData())) : "";
break;
case hive_t_REG_BINARY:
// A blob of binary
ToHexStr();
break;
case hive_t_REG_DWORD:
// DWORD (32 bit integer), little endian
ret=QString().sprintf("0x%08X",*(uint32_t*)value.constData());
break;
case hive_t_REG_DWORD_BIG_ENDIAN:
// DWORD (32 bit integer), big endian
ret=QString().sprintf("0x%08X",*(uint32_t*)value.constData());
break;
case hive_t_REG_LINK:
// Symbolic link to another part of the registry tree
ToHexStr();
break;
case hive_t_REG_MULTI_SZ:
// Multiple Windows strings.
// See http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx
ToHexStr();
break;
case hive_t_REG_RESOURCE_LIST:
// Resource list
ToHexStr();
break;
case hive_t_REG_FULL_RESOURCE_DESCRIPTOR:
// Resource descriptor
ToHexStr();
break;
case hive_t_REG_RESOURCE_REQUIREMENTS_LIST:
// Resouce requirements list
ToHexStr();
break;
case hive_t_REG_QWORD:
// QWORD (64 bit integer). Usually little endian.
ret=
QString("0x%1").arg((quint64)(*(uint64_t*)value.constData()),16,16,QChar('0'));
break;
default:
ToHexStr();
}
#undef ToHexStr
return ret;
}
/*
* KeyValueToString
*/
QString RegistryHive::KeyValueToString(QByteArray key_value,
QString format,
int offset,
int length,
bool little_endian)
{
int remaining_data_len;
const char *p_data;
QString ret="";
// Calculate how many bytes are remainig after specified offset
remaining_data_len=key_value.size()-offset;
if(!remaining_data_len>0) {
// Nothing to show
return QString();
}
// Get pointer to data at specified offset
p_data=key_value.constData();
p_data+=offset;
// TODO: This will fail on platforms with different endianness!
#define bswap_16(value) ((((value) & 0xff) << 8) | ((value) >> 8))
#define bswap_32(value) \
(((uint32_t)bswap_16((uint16_t)((value) & 0xffff)) << 16) | \
(uint32_t)bswap_16((uint16_t)((value) >> 16)))
#define bswap_64(value) \
(((uint64_t)bswap_32((uint32_t)((value) & 0xffffffff)) << 32) | \
(uint64_t)bswap_32((uint32_t)((value) >> 32))) \
// ConvertFull name
if(format=="int8" && remaining_data_len>=1) {
ret=QString().sprintf("%d",*(int8_t*)p_data);
} else if(format=="uint8" && remaining_data_len>=1) {
ret=QString().sprintf("%u",*(uint8_t*)p_data);
} else if(format=="int16" && remaining_data_len>=2) {
int16_t val=*(int16_t*)p_data;
if(little_endian) ret=QString().sprintf("%d",val);
else ret=QString().sprintf("%d",bswap_16(val));
} else if(format=="uint16" && remaining_data_len>=2) {
uint16_t val=*(uint16_t*)p_data;
if(little_endian) ret=QString().sprintf("%u",val);
else ret=QString().sprintf("%u",bswap_16(val));
} else if(format=="int32" && remaining_data_len>=4) {
int32_t val=*(int32_t*)p_data;
if(little_endian) ret=QString().sprintf("%d",val);
else ret=QString().sprintf("%d",bswap_32(val));
} else if(format=="uint32" && remaining_data_len>=4) {
uint32_t val=*(uint32_t*)p_data;
if(little_endian) ret=QString().sprintf("%u",val);
else ret=QString().sprintf("%u",bswap_32(val));
} else if(format=="unixtime" && remaining_data_len>=4) {
uint32_t val=*(uint32_t*)p_data;
if(!little_endian) val=bswap_32(val);
if(val==0) {
ret="n/a";
} else {
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(val);
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
} else if(format=="int64" && remaining_data_len>=8) {
int64_t val=*(int64_t*)p_data;
if(little_endian) ret=QString("%1").arg(val);
else ret=QString("%1").arg((int64_t)bswap_64(val));
} else if(format=="uint64" && remaining_data_len>=8) {
uint64_t val=*(uint64_t*)p_data;
if(little_endian) ret=QString("%1").arg(val);
else ret=QString("%1").arg(bswap_64(val));
/*
// TODO: Check how one could implement this
} else if(format=="unixtime64" && remaining_data_len>=8) {
if(*(uint64_t*)p_data==0) {
ret="n/a";
} else {
uint64_t secs=*(uint64_t*)p_data;
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
// Set 32bit part of date/time
date_time.setTime_t(secs&0xFFFFFFFF);
// Now add high 32bit part of date/time
date_time.addSecs(secs>>32);
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
*/
} else if(format=="filetime" && remaining_data_len>=8) {
uint64_t val=*(uint64_t*)p_data;
if(!little_endian) val=bswap_64(val);
if(val==0) {
ret="n/a";
} else {
// TODO: Warn if >32bit
QDateTime date_time;
date_time.setTimeSpec(Qt::UTC);
date_time.setTime_t(RegistryHive::FiletimeToUnixtime(val));
ret=date_time.toString("yyyy/MM/dd hh:mm:ss");
}
} else if(format=="ascii") {
// TODO: This fails bad if the string is not null terminated!! It might be
// wise checking for a null char here
ret=QString().fromAscii((char*)p_data,length);
} else if(format=="utf16" && remaining_data_len>=2) {
ret=QString().fromUtf16((ushort*)p_data,length);
} else {
// Unknown variant type or another error
return QString();
}
return ret;
}
/*
* KeyTypeToString
*/
QString RegistryHive::KeyTypeToString(int value_type) {
QString ret="";
switch(value_type) {
case hive_t_REG_NONE:
ret="REG_NONE";
break;
case hive_t_REG_SZ:
ret="REG_SZ";
break;
case hive_t_REG_EXPAND_SZ:
ret="REG_EXPAND_SZ";
break;
case hive_t_REG_BINARY:
ret="REG_BINARY";
break;
case hive_t_REG_DWORD:
ret="REG_DWORD";
break;
case hive_t_REG_DWORD_BIG_ENDIAN:
ret="REG_DWORD_BIG_ENDIAN";
break;
case hive_t_REG_LINK:
ret="REG_LINK";
break;
case hive_t_REG_MULTI_SZ:
ret="REG_MULTI_SZ";
break;
case hive_t_REG_RESOURCE_LIST:
ret="REG_RESOURCE_LIST";
break;
case hive_t_REG_FULL_RESOURCE_DESCRIPTOR:
ret="REG_FULL_RESOURCE_DESC";
break;
case hive_t_REG_RESOURCE_REQUIREMENTS_LIST:
ret="REG_RESOURCE_REQ_LIST";
break;
case hive_t_REG_QWORD:
ret="REG_QWORD";
break;
default:
ret=QString().sprintf("0x%08X",(uint32_t)value_type);
}
return ret;
}
/*
* FiletimeToUnixtime
*/
uint64_t RegistryHive::FiletimeToUnixtime(int64_t filetime) {
return (unsigned)((filetime-EPOCH_DIFF)/10000000);
}
/*
* SetError
*/
void RegistryHive::SetError(QString msg) {
this->erro_msg=msg;
this->is_error=true;
}
/*
* GetNodeHandle
*/
bool RegistryHive::GetNodeHandle(QString &path, hive_node_h *p_node) {
QStringList nodes;
int i=0;
// Get root node handle
*p_node=hivex_root(this->p_hive);
if(*p_node==0) {
this->SetError(tr("Unable to get root node!"));
return false;
}
if(path!="\\") {
// If we aren't listing the root node, we have to get a handle to the
// last node in the path. Split path into nodes
nodes=path.split('\\',QString::SkipEmptyParts);
// Iterate to the correct parent node
for(i=0;i<nodes.count();i++) {
// printf("Spotting node '%s'\n",nodes.value(i).toAscii().constData());
*p_node=hivex_node_get_child(this->p_hive,
*p_node,
nodes.value(i).toAscii().constData());
if(*p_node==0) {
this->SetError(tr("Unable to find node '%1'!").arg(nodes.value(i)));
return false;
}
}
}
return true;
}
/*
* GetNodesHelper
*/
QMap<QString,int> RegistryHive::GetNodesHelper(hive_node_h parent_node) {
QMap<QString,int> keys;
char *p_name;
int i=0;
// Get child nodes
hive_node_h *child_nodes=hivex_node_children(this->p_hive,parent_node);
if(child_nodes==NULL) {
this->SetError(
tr("Unable to enumerate child nodes!"));
return QMap<QString,int>();
}
// Build result
keys.clear();
i=0;
while(child_nodes[i]) {
p_name=hivex_node_name(this->p_hive,child_nodes[i]);
if(p_name==NULL) {
this->SetError(tr("Unable to get node name!"));
free(child_nodes);
return QMap<QString,int>();
}
keys.insert(QString(p_name),(int)child_nodes[i]);
free(p_name);
i++;
}
free(child_nodes);
return keys;
}
/*
* GetKeysHelper
*/
QMap<QString,int> RegistryHive::GetKeysHelper(hive_node_h parent_node) {
QMap<QString,int> keys;
char *p_name;
int i=0;
// Get child keys
hive_value_h *p_keys=hivex_node_values(this->p_hive,parent_node);
if(p_keys==NULL) {
this->SetError(
tr("Unable to enumerate child keys!"));
return QMap<QString,int>();
}
// Build result list
keys.clear();
i=0;
while(p_keys[i]) {
p_name=hivex_value_key(this->p_hive,p_keys[i]);
if(p_name==NULL) {
this->SetError(tr("Unable to get key name!"));
return QMap<QString,int>();
}
keys.insert(QString(p_name),p_keys[i]);
free(p_name);
i++;
}
free(p_keys);
return keys;
}
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 9686d4c..2c47709 100644
--- a/trunk/registryhive.h
+++ b/trunk/registryhive.h
@@ -1,82 +1,83 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef 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);
QString Filename();
QMap<QString,int> GetNodes(QString path="\\");
QMap<QString,int> GetNodes(int parent_node=0);
QMap<QString,int> GetKeys(QString path="\\");
QMap<QString,int> GetKeys(int parent_node=0);
QByteArray GetKeyValue(QString path,
QString key,
int *p_value_type,
size_t *p_value_len);
QByteArray GetKeyValue(int hive_key,
int *p_value_type,
size_t *p_value_len);
+ int64_t GetKeyModTime(QString path,QString key);
int64_t GetKeyModTime(int hive_key);
static QString KeyValueToString(QByteArray value, int value_type);
static QString KeyValueToString(QByteArray value,
QString format,
int offset=0,
int length=0,
bool little_endian=true);
static QString KeyTypeToString(int value_type);
static uint64_t FiletimeToUnixtime(int64_t filetime);
private:
QString erro_msg;
bool is_error;
QString hive_file;
hive_h *p_hive;
bool is_hive_open;
void SetError(QString msg);
bool GetNodeHandle(QString &path, hive_node_h *p_node);
QMap<QString,int> GetNodesHelper(hive_node_h parent_node);
QMap<QString,int> GetKeysHelper(hive_node_h parent_node);
QByteArray GetKeyValueHelper(hive_value_h hive_key,
int *p_value_type,
size_t *p_value_len);
};
#endif // REGISTRYHIVE_H
diff --git a/trunk/registrykeytable.cpp b/trunk/registrykeytable.cpp
index 6c51b90..a488c3b 100644
--- a/trunk/registrykeytable.cpp
+++ b/trunk/registrykeytable.cpp
@@ -1,145 +1,146 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrykeytable.h"
#include <QHeaderView>
#include <QApplication>
#include <QClipboard>
RegistryKeyTable::RegistryKeyTable(QWidget *p_parent) : QTableView(p_parent) {
// Configure widget
this->setSelectionMode(QAbstractItemView::SingleSelection);
this->setSelectionBehavior(QAbstractItemView::SelectRows);
this->setAutoScroll(false);
this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
this->verticalHeader()->setHidden(true);
this->setTextElideMode(Qt::ElideNone);
// Create context menu
this->p_menu_copy=new QMenu(tr("Copy"),this);
this->p_action_copy_key_name=new QAction(tr("Key name"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_key_name);
this->connect(this->p_action_copy_key_name,
SIGNAL(triggered()),
this,
SLOT(SlotCopyKeyName()));
this->p_action_copy_key_value=new QAction(tr("Key value"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_key_value);
this->connect(this->p_action_copy_key_value,
SIGNAL(triggered()),
this,
SLOT(SlotCopyKeyValue()));
}
RegistryKeyTable::~RegistryKeyTable() {
// Delete context menu
delete this->p_action_copy_key_name;
delete this->p_action_copy_key_value;
delete this->p_menu_copy;
}
void RegistryKeyTable::setModel(QAbstractItemModel *p_model) {
QTableView::setModel(p_model);
// Resize table rows / columns to fit data
this->resizeColumnsToContents();
this->resizeRowsToContents();
this->horizontalHeader()->stretchLastSection();
if(p_model!=NULL && p_model->rowCount()>0) {
// Select first table item
this->selectRow(0);
}
}
/*
void RegistryKeyTable::selectRow(QString key_name) {
int i;
this->clearSelection();
for(i=0;i<this->model()->rowCount();i++) {
if(this->model())
}
}
*/
int RegistryKeyTable::sizeHintForColumn(int column) const {
int size_hint=-1;
int i=0;
int item_width=0;
QFontMetrics fm(this->fontMetrics());
QModelIndex idx;
if(this->model()==NULL) return -1;
// Find string that needs the most amount of space
idx=this->model()->index(i,column);
while(idx.isValid()) {
item_width=fm.width(this->model()->data(idx).toString())+10;
if(item_width>size_hint) size_hint=item_width;
idx=this->model()->index(++i,column);
}
return size_hint;
}
void RegistryKeyTable::contextMenuEvent(QContextMenuEvent *p_event) {
// Only show context menu when a row is selected
- if(this->selectedIndexes().count()!=3) return;
+ if(this->selectedIndexes().count()!=4) return;
// Only show context menu when user clicked on selected row
if(!(this->indexAt(p_event->pos())==this->selectedIndexes().at(0) ||
this->indexAt(p_event->pos())==this->selectedIndexes().at(1) ||
- this->indexAt(p_event->pos())==this->selectedIndexes().at(2)))
+ this->indexAt(p_event->pos())==this->selectedIndexes().at(2) ||
+ this->indexAt(p_event->pos())==this->selectedIndexes().at(3)))
{
return;
}
// Emit a click signal
emit(this->clicked(this->indexAt(p_event->pos())));
// Create context menu and add actions
QMenu context_menu(this);
context_menu.addMenu(this->p_menu_copy);
context_menu.exec(p_event->globalPos());
}
void RegistryKeyTable::currentChanged(const QModelIndex ¤t,
const QModelIndex &previous)
{
// Call parent class's currentChanged first
QTableView::currentChanged(current,previous);
// Now emit our signal
QModelIndex current_item=QModelIndex(current);
emit(RegistryKeyTable::CurrentItemChanged(current_item));
}
void RegistryKeyTable::SlotCopyKeyName() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(0).data().toString(),
QClipboard::Clipboard);
}
void RegistryKeyTable::SlotCopyKeyValue() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(2).data().toString(),
QClipboard::Clipboard);
}
diff --git a/trunk/registrynodetree.cpp b/trunk/registrynodetree.cpp
index e05ced1..0b82d47 100644
--- a/trunk/registrynodetree.cpp
+++ b/trunk/registrynodetree.cpp
@@ -1,129 +1,129 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrynodetree.h"
#include "registrynodetreemodel.h"
#include <QHeaderView>
#include <QApplication>
#include <QClipboard>
RegistryNodeTree::RegistryNodeTree(QWidget *p_parent) : QTreeView(p_parent) {
// Configure widget
this->setTextElideMode(Qt::ElideNone);
// Create context menu
this->p_menu_copy=new QMenu(tr("Copy"),this);
- this->p_action_copy_node_name=new QAction(tr("Copy node name"),
+ this->p_action_copy_node_name=new QAction(tr("Node name"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_node_name);
this->connect(this->p_action_copy_node_name,
SIGNAL(triggered()),
this,
SLOT(SlotCopyNodeName()));
- this->p_action_copy_node_path=new QAction(tr("Copy node path"),
+ this->p_action_copy_node_path=new QAction(tr("Node path"),
this->p_menu_copy);
this->p_menu_copy->addAction(this->p_action_copy_node_path);
this->connect(this->p_action_copy_node_path,
SIGNAL(triggered()),
this,
SLOT(SlotCopyNodePath()));
}
RegistryNodeTree::~RegistryNodeTree() {
// Delete context menu
delete this->p_action_copy_node_name;
delete this->p_action_copy_node_path;
delete this->p_menu_copy;
}
void RegistryNodeTree::setModel(QAbstractItemModel *p_model) {
QTreeView::setModel(p_model);
this->header()->setResizeMode(0,QHeaderView::ResizeToContents);
this->header()->setStretchLastSection(false);
if(p_model!=NULL && p_model->index(0,0).isValid()) {
// Select first tree item
this->setCurrentIndex(p_model->index(0,0));
}
}
//int RegistryNodeTree::sizeHintForColumn(int column) const {}
void RegistryNodeTree::contextMenuEvent(QContextMenuEvent *p_event) {
// Only show context menu when a node is selected
if(this->selectedIndexes().count()!=1) return;
// Only show context menu when user clicked on selected row
if(this->indexAt(p_event->pos())!=this->selectedIndexes().at(0)) return;
// Emit a click signal
emit(this->clicked(this->indexAt(p_event->pos())));
// Create context menu and add actions
QMenu context_menu(this);
context_menu.addMenu(this->p_menu_copy);
context_menu.exec(p_event->globalPos());
}
void RegistryNodeTree::keyPressEvent(QKeyEvent *p_event) {
// Only react if a node is selected and user pressed Key_Left
if(this->selectedIndexes().count()==1 &&
p_event->key()==Qt::Key_Left)
{
QModelIndex cur_index=this->selectedIndexes().at(0);
if(this->model()->hasChildren(cur_index)) {
// Collapse current node
this->collapse(cur_index);
}
if(!cur_index.parent().isValid()) {
// Do no try to collapse anything above root node
return;
}
this->collapse(cur_index.parent());
this->setCurrentIndex(cur_index.parent());
return;
}
// If we didn't handle the key event, let our parent handle it
QTreeView::keyPressEvent(p_event);
}
void RegistryNodeTree::currentChanged(const QModelIndex ¤t,
const QModelIndex &previous)
{
// Call parent class's currentChanged first
QTreeView::currentChanged(current,previous);
// Now emit our signal
QModelIndex current_item=QModelIndex(current);
emit(RegistryNodeTree::CurrentItemChanged(current_item));
}
void RegistryNodeTree::SlotCopyNodeName() {
QApplication::clipboard()->
setText(this->selectedIndexes().at(0).data().toString(),
QClipboard::Clipboard);
}
void RegistryNodeTree::SlotCopyNodePath() {
QString path=((RegistryNodeTreeModel*)(this->model()))->
GetNodePath(this->selectedIndexes().at(0));
QApplication::clipboard()->setText(path,QClipboard::Clipboard);
}
diff --git a/trunk/report_templates/NTUSER_RecentDocs.qs b/trunk/report_templates/NTUSER_RecentDocs.qs
index a0f9127..02c8223 100644
--- a/trunk/report_templates/NTUSER_RecentDocs.qs
+++ b/trunk/report_templates/NTUSER_RecentDocs.qs
@@ -1,23 +1,37 @@
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
println("<html>");
println(" <head><title>Recent Documents</title></head>");
println(" <body style=\"font-size:12\">");
println(" <h2>Recent documents</h2>");
-println(" <p style=\"font-size:12\">");
-println(" <table style=\"margin-left:20px; font-size:12\">");
// Get list of recent docs
var recent_docs=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs","MRUListEx");
+if(IsValid(recent_docs)) {
+ println(" <p style=\"font-size:12\">");
+ println(" <table style=\"margin-left:20px; font-size:12\">");
+ println(" <tr><td><b>Document</b></td><td> <b>Last modified</b></td></tr>");
+
+ // Iterate over all recent docs
+ var i=0;
+ var runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i);
+ while(Number(runlist)!=0xffffffff) {
+ var entry=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs",runlist.toString(10));
+ var mod_time=GetRegistryKeyModTime("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs",runlist.toString(10));
+ println(" <tr><td>",RegistryKeyValueToVariant(entry.value,"utf16",0),"</td><td> ",mod_time,"</td></tr>");
+ i+=4;
+ runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i);
+ }
-// Iterate over all recent docs
-var i=0;
-var runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i);
-while(Number(runlist)!=0xffffffff) {
- var entry=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs",runlist.toString(10));
- println(" <tr><td>",RegistryKeyValueToVariant(entry.value,"utf16",0),"</td></tr>");
- i+=4;
- runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i);
+ println(" </table>");
+ println(" </p>");
+} else {
+ println(" <p><font color='red'>");
+ println(" This registry hive does not contain a list of recent documents!");
+ println(" </font></p>");
}
-println(" </table>");
-println(" </p>");
println("</html>");
diff --git a/trunk/report_templates/NTUSER_TypedUrls.qs b/trunk/report_templates/NTUSER_TypedUrls.qs
index 29ecb94..ec0d2b3 100644
--- a/trunk/report_templates/NTUSER_TypedUrls.qs
+++ b/trunk/report_templates/NTUSER_TypedUrls.qs
@@ -1,17 +1,32 @@
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
println("<html>");
println(" <head><title>Typed Urls</title></head>");
println(" <body style=\"font-size:12\">");
println(" <h2>Typed urls</h2>");
-println(" <p style=\"font-size:12\">");
-println(" <table style=\"margin-left:20px; font-size:12\">");
// Iterate over all typed urls
var typed_urls=GetRegistryKeys("\\Software\\Microsoft\\Internet Explorer\\TypedURLs");
-for(var i=0;i<typed_urls.length;i++) {
- var val=GetRegistryKeyValue("\\Software\\Microsoft\\Internet Explorer\\TypedURLs",typed_urls[i]);
- println(" <tr><td>",RegistryKeyValueToString(val.value,val.type),"</td></tr>");
+if(IsValid(typed_urls)) {
+ println(" <p style=\"font-size:12\">");
+ println(" <table style=\"margin-left:20px; font-size:12\">");
+ println(" <tr><td><b>Url</b></td><td> <b>Last modified</b></td></tr>");
+
+ for(var i=0;i<typed_urls.length;i++) {
+ var val=GetRegistryKeyValue("\\Software\\Microsoft\\Internet Explorer\\TypedURLs",typed_urls[i]);
+ var mod_time=GetRegistryKeyModTime("\\Software\\Microsoft\\Internet Explorer\\TypedURLs",typed_urls[i]);
+ println(" <tr><td>",RegistryKeyValueToString(val.value,val.type),"</td><td> ",mod_time,"</td></tr>");
+ }
+
+ println(" </table>");
+ println(" </p>");
+} else {
+ println(" <p><font color='red'>");
+ println(" This registry hive does not contain a list of typed urls!");
+ println(" </font></p>");
}
-println(" </table>");
-println(" </p>");
println("</html>");
diff --git a/trunk/report_templates/NTUSER_WindowsLiveAccounts.qs b/trunk/report_templates/NTUSER_WindowsLiveAccounts.qs
index 8345c36..0a78998 100644
--- a/trunk/report_templates/NTUSER_WindowsLiveAccounts.qs
+++ b/trunk/report_templates/NTUSER_WindowsLiveAccounts.qs
@@ -1,22 +1,35 @@
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
println("<html>");
println(" <head><title>Windows Live Accounts</title></head>");
println(" <body style=\"font-size:12\">");
println(" <h2>Windows live accounts</h2>");
-println(" <p style=\"font-size:12\">");
-println(" <table style=\"margin-left:20px; font-size:12\">");
// Iterate over all contacts
var accounts=GetRegistryKeys("\\Software\\Microsoft\\Windows Live Contacts\\Database");
-for(var i=0;i<accounts.length;i++) {
- var val=GetRegistryKeyValue("\\Software\\Microsoft\\Windows Live Contacts\\Database",accounts[i]);
- println(" <tr><td>",accounts[i],"</td><td>",RegistryKeyValueToString(val.value,val.type),"</td></tr>");
-}
-accounts=GetRegistryKeys("\\Software\\Microsoft\\Windows Live Contacts\\Me");
-for(var i=0;i<accounts.length;i++) {
- var val=GetRegistryKeyValue("\\Software\\Microsoft\\Windows Live Contacts\\Me",accounts[i]);
- println(" <tr><td>",accounts[i],"</td><td>",RegistryKeyValueToString(val.value,val.type),"</td></tr>");
+if(IsValid(accounts)) {
+ println(" <p style=\"font-size:12\">");
+ println(" <table style=\"margin-left:20px; font-size:12\">");
+
+ for(var i=0;i<accounts.length;i++) {
+ var val=GetRegistryKeyValue("\\Software\\Microsoft\\Windows Live Contacts\\Database",accounts[i]);
+ println(" <tr><td>",accounts[i],"</td><td>",RegistryKeyValueToString(val.value,val.type),"</td></tr>");
+ }
+ accounts=GetRegistryKeys("\\Software\\Microsoft\\Windows Live Contacts\\Me");
+ for(var i=0;i<accounts.length;i++) {
+ var val=GetRegistryKeyValue("\\Software\\Microsoft\\Windows Live Contacts\\Me",accounts[i]);
+ println(" <tr><td>",accounts[i],"</td><td>",RegistryKeyValueToString(val.value,val.type),"</td></tr>");
+ }
+
+ println(" </table>");
+ println(" </p>");
+} else {
+ println(" <p><font color='red'>");
+ println(" This registry hive does not contain a list of Windows Live Accounts!");
+ println(" </font></p>");
}
-println(" </table>");
-println(" </p>");
println("</html>");
diff --git a/trunk/report_templates/SAM_UserAccounts.qs b/trunk/report_templates/SAM_UserAccounts.qs
index 08c8a3a..9ba427f 100644
--- a/trunk/report_templates/SAM_UserAccounts.qs
+++ b/trunk/report_templates/SAM_UserAccounts.qs
@@ -1,85 +1,97 @@
// See http://windowsir.blogspot.com/2006/08/getting-user-info-from-image.html
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
function print_table_row(cell01,cell02) {
println(" <tr><td>",cell01,"</td><td>",cell02,"</td></tr>");
}
function print_v_info(v_key_value,info_name,str_off) {
var offset=Number(RegistryKeyValueToVariant(v_key_value,"uint16",str_off))+0x0cc;
var len=Number(RegistryKeyValueToVariant(v_key_value,"uint16",str_off+4))/2;
if(len>0) print_table_row(info_name,RegistryKeyValueToVariant(v_key_value,"utf16",offset,len));
}
println("<html>");
println(" <head><title>User Accounts</title></head>");
println(" <body style=\"font-size:12\">");
println(" <h2>User accounts</h2>");
// Iterate over all user names
var user_names=GetRegistryNodes("\\SAM\\Domains\\Account\\Users\\Names");
-for(var i=0;i<user_names.length;i++) {
- println(" <p style=\"font-size:12; white-space:nowrap\">");
+if(IsValid(user_names)) {
+ for(var i=0;i<user_names.length;i++) {
+ println(" <p style=\"font-size:12; white-space:nowrap\">");
- // Print user name
- println(" <u>",user_names[i],"</u><br />");
+ // Print user name
+ println(" <u>",user_names[i],"</u><br />");
- println(" <table style=\"margin-left:20px; font-size:12\">");
+ println(" <table style=\"margin-left:20px; font-size:12\">");
- // Get user rid stored in "default" key
- var user_rid=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\Names\\",user_names[i]),"");
- user_rid=RegistryKeyTypeToString(user_rid.type);
- println(" <tr><td>RID:</td><td>",Number(user_rid).toString(10)," (",user_rid,")","</td></tr>");
+ // Get user rid stored in "default" key
+ var user_rid=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\Names\\",user_names[i]),"");
+ user_rid=RegistryKeyTypeToString(user_rid.type);
+ println(" <tr><td>RID:</td><td>",Number(user_rid).toString(10)," (",user_rid,")","</td></tr>");
- // RegistryKeyTypeToString returns the rid prepended with "0x". We have to remove that for further processing
- user_rid=String(user_rid).substr(2);
+ // RegistryKeyTypeToString returns the rid prepended with "0x". We have to remove that for further processing
+ user_rid=String(user_rid).substr(2);
- // Get user's V key and print various infos
- var v_key=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"V");
- print_v_info(v_key.value,"Full name:",0x18);
- print_v_info(v_key.value,"Comment:",0x24);
- print_v_info(v_key.value,"Home directory:",0x48);
- print_v_info(v_key.value,"Home directory drive:",0x54);
- print_v_info(v_key.value,"Logon script path:",0x60);
- print_v_info(v_key.value,"Profile path:",0x6c);
+ // Get user's V key and print various infos
+ var v_key=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"V");
+ print_v_info(v_key.value,"Full name:",0x18);
+ print_v_info(v_key.value,"Comment:",0x24);
+ print_v_info(v_key.value,"Home directory:",0x48);
+ print_v_info(v_key.value,"Home directory drive:",0x54);
+ print_v_info(v_key.value,"Logon script path:",0x60);
+ print_v_info(v_key.value,"Profile path:",0x6c);
- // Get user's F key and print various infos
- var f_key=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"F");
- print_table_row("Last login time:",RegistryKeyValueToVariant(f_key.value,"filetime",8));
- print_table_row("Last pw change:",RegistryKeyValueToVariant(f_key.value,"filetime",24));
- print_table_row("Last failed login:",RegistryKeyValueToVariant(f_key.value,"filetime",40));
- print_table_row("Account expires:",RegistryKeyValueToVariant(f_key.value,"filetime",32));
- print_table_row("Total logins:",RegistryKeyValueToVariant(f_key.value,"uint16",66));
- print_table_row("Failed logins:",RegistryKeyValueToVariant(f_key.value,"uint16",64));
- var acc_flags=Number(RegistryKeyValueToVariant(f_key.value,"uint16",56));
- print(" <tr><td>Account flags:</td><td>");
- if(acc_flags&0x0001) print("Disabled ");
- if(acc_flags&0x0002) print("HomeDirReq ");
- if(acc_flags&0x0004) print("PwNotReq ");
- if(acc_flags&0x0008) print("TempDupAcc ");
- // I don't think this would be useful to show
- //if(acc_flags&0x0010) print("NormUserAcc ");
- if(acc_flags&0x0020) print("MnsAcc ");
- if(acc_flags&0x0040) print("DomTrustAcc ");
- if(acc_flags&0x0080) print("WksTrustAcc ");
- if(acc_flags&0x0100) print("SrvTrustAcc ");
- if(acc_flags&0x0200) print("NoPwExpiry ");
- if(acc_flags&0x0400) print("AccAutoLock ");
- print(" (",acc_flags,")");
- println("</td></tr>");
+ // Get user's F key and print various infos
+ var f_key=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"F");
+ print_table_row("Last login time:",RegistryKeyValueToVariant(f_key.value,"filetime",8));
+ print_table_row("Last pw change:",RegistryKeyValueToVariant(f_key.value,"filetime",24));
+ print_table_row("Last failed login:",RegistryKeyValueToVariant(f_key.value,"filetime",40));
+ print_table_row("Account expires:",RegistryKeyValueToVariant(f_key.value,"filetime",32));
+ print_table_row("Total logins:",RegistryKeyValueToVariant(f_key.value,"uint16",66));
+ print_table_row("Failed logins:",RegistryKeyValueToVariant(f_key.value,"uint16",64));
+ var acc_flags=Number(RegistryKeyValueToVariant(f_key.value,"uint16",56));
+ print(" <tr><td>Account flags:</td><td>");
+ if(acc_flags&0x0001) print("Disabled ");
+ if(acc_flags&0x0002) print("HomeDirReq ");
+ if(acc_flags&0x0004) print("PwNotReq ");
+ if(acc_flags&0x0008) print("TempDupAcc ");
+ // I don't think this would be useful to show
+ //if(acc_flags&0x0010) print("NormUserAcc ");
+ if(acc_flags&0x0020) print("MnsAcc ");
+ if(acc_flags&0x0040) print("DomTrustAcc ");
+ if(acc_flags&0x0080) print("WksTrustAcc ");
+ if(acc_flags&0x0100) print("SrvTrustAcc ");
+ if(acc_flags&0x0200) print("NoPwExpiry ");
+ if(acc_flags&0x0400) print("AccAutoLock ");
+ print(" (",acc_flags,")");
+ println("</td></tr>");
- // Get password hint if available
- var hint=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"UserPasswordHint");
- if(typeof hint !== 'undefined') {
- // Append missing trailing utf16 zero byte
- hint.value.appendByte(0);
- hint.value.appendByte(0);
- print_table_row("Password hint:",RegistryKeyValueToVariant(hint.value,"utf16"));
- }
+ // Get password hint if available
+ var hint=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"UserPasswordHint");
+ if(typeof hint !== 'undefined') {
+ // Append missing trailing utf16 zero byte
+ hint.value.appendByte(0);
+ hint.value.appendByte(0);
+ print_table_row("Password hint:",RegistryKeyValueToVariant(hint.value,"utf16"));
+ }
- // TODO: User group membership
+ // TODO: User group membership
- println(" </table>");
- println(" </p>");
+ println(" </table>");
+ println(" </p>");
+ }
+} else {
+ println(" <p><font color='red'>");
+ println(" Unable to enumerate users!<br />");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println(" </font></p>");
}
println("</html>");
diff --git a/trunk/report_templates/SOFTWARE_WindowsVersion.qs b/trunk/report_templates/SOFTWARE_WindowsVersion.qs
index 0b28e64..8a09d4a 100644
--- a/trunk/report_templates/SOFTWARE_WindowsVersion.qs
+++ b/trunk/report_templates/SOFTWARE_WindowsVersion.qs
@@ -1,82 +1,96 @@
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
function print_table_row(cell01,cell02) {
println(" <tr><td>",cell01,"</td><td>",cell02,"</td></tr>");
}
function DecodeProductKey(arr) {
//ProductKey is base24 encoded
var keychars=new Array("B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","2","3","4","6","7","8","9");
var key=new Array(30);
var ret="";
var ncur;
if(arr.length<66) return ret;
arr=arr.mid(52,15);
for(var ilbyte=24;ilbyte>=0;ilbyte--) {
ncur=0;
for(var ilkeybyte=14;ilkeybyte>=0;ilkeybyte--) {
ncur=ncur*256^arr[ilkeybyte];
arr[ilkeybyte]=ncur/24;
ncur%=24;
}
ret=keychars[ncur]+ret;
if(ilbyte%5==0 && ilbyte!=0) ret="-"+ret;
}
return ret;
}
println("<html>");
println(" <head><title>Windows version info</title></head>");
println(" <body style=\"font-size:12\">");
println(" <h2>Windows version info</h2>");
-println(" <p style=\"font-size:12; white-space:nowrap\">");
-println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
// Windows version sp and build info
var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","ProductName");
-print(" <tr><td>Windows version:</td><td>",RegistryKeyValueToString(val.value,val.type));
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","CSDVersion");
-if(typeof val !== 'undefined') {
- print(" ",RegistryKeyValueToString(val.value,val.type));
-}
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","CurrentBuildNumber");
-if(typeof val !== 'undefined') {
- print(" build ",RegistryKeyValueToString(val.value,val.type));
-}
-println("</td></tr>");
-// Build string
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","BuildLab");
-print_table_row("Build string:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
-// Extended build string
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","BuildLabEx");
-print_table_row("Extended build string:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+if(IsValid(val)) {
+ println(" <p style=\"font-size:12; white-space:nowrap\">");
+ println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
-// Install date
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","InstallDate");
-print_table_row("Install date:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"unixtime") : "n/a");
+ print(" <tr><td>Windows version:</td><td>",RegistryKeyValueToString(val.value,val.type));
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","CSDVersion");
+ if(IsValid(val)) {
+ print(" ",RegistryKeyValueToString(val.value,val.type));
+ }
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","CurrentBuildNumber");
+ if(IsValid(val)) {
+ print(" build ",RegistryKeyValueToString(val.value,val.type));
+ }
+ println("</td></tr>");
+ // Build string
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","BuildLab");
+ print_table_row("Build string:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ // Extended build string
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","BuildLabEx");
+ print_table_row("Extended build string:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+
+ // Install date
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","InstallDate");
+ print_table_row("Install date:",(IsValid(val)) ? RegistryKeyValueToVariant(val.value,"unixtime") : "n/a");
-// Owner and Organization info
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","RegisteredOwner");
-print_table_row("Registered owner:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","RegisteredOrganization");
-print_table_row("Registered organization:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ // Owner and Organization info
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","RegisteredOwner");
+ print_table_row("Registered owner:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","RegisteredOrganization");
+ print_table_row("Registered organization:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
-// Windows ID / Key
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","ProductId");
-print_table_row("Product ID:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","DigitalProductId");
-if(typeof val !== 'undefined') {
- var key=DecodeProductKey(val.value);
- if(key!="BBBBB-BBBBB-BBBBB-BBBBB-BBBBB") print_table_row("Product Key:",key);
- else print_table_row("Product Key:","n/a (Probably a volume license key was used)");
-} else print_table_row("Product Key:","n/a");
+ // Windows ID / Key
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","ProductId");
+ print_table_row("Product ID:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","DigitalProductId");
+ if(IsValid(val)) {
+ var key=DecodeProductKey(val.value);
+ if(key!="BBBBB-BBBBB-BBBBB-BBBBB-BBBBB") print_table_row("Product Key:",key);
+ else print_table_row("Product Key:","n/a (Probably a volume license key was used)");
+ } else print_table_row("Product Key:","n/a");
-// Install directory / Source directory
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","PathName");
-print_table_row("Install path:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
-var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","SourcePath");
-print_table_row("Source path:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ // Install directory / Source directory
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","PathName");
+ print_table_row("Install path:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","SourcePath");
+ print_table_row("Source path:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+
+ println(" </table>");
+ println(" </p>");
+} else {
+ println(" <p><font color='red'>");
+ println(" Unable to get product name!<br />");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println(" </font></p>");
+}
-println(" </table>");
-println(" </p>");
println("</html>");
diff --git a/trunk/report_templates/SYSTEM_CurrentNetworkSettings.qs b/trunk/report_templates/SYSTEM_CurrentNetworkSettings.qs
index 08014c8..d646494 100644
--- a/trunk/report_templates/SYSTEM_CurrentNetworkSettings.qs
+++ b/trunk/report_templates/SYSTEM_CurrentNetworkSettings.qs
@@ -1,97 +1,109 @@
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
function print_table_row(cell01,cell02) {
println(" <tr><td>",cell01,"</td><td>",cell02,"</td></tr>");
}
function ZeroPad(number,padlen) {
var ret=number.toString(10);
if(!padlen || ret.length>=padlen) return ret;
return Math.pow(10,padlen-ret.length).toString().slice(1)+ret;
}
// Global vars
var val;
-// Get current controlset
-var cur_controlset=GetRegistryKeyValue("\\Select","Current");
-cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type);
-// Current holds a DWORD value, thus we get a string like 0x00000000, but
-// control sets are referenced by its decimal representation.
-cur_controlset="ControlSet"+ZeroPad(parseInt(String(cur_controlset).substr(2,8),16),3)
-
println("<html>");
println(" <head><title>Current Network Settings (Tcp/Ip)</title></head>");
println(" <body style=\"font-size:12\">");
println(" <h2>Current network settings (Tcp/Ip)</h2>");
-println(" <p style=\"font-size:12; white-space:nowrap\">");
-println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
-
-print_table_row("Active control set:",cur_controlset);
-
-// Computer name
-val=GetRegistryKeyValue(cur_controlset+"\\Control\\ComputerName\\ComputerName","ComputerName");
-print_table_row("Computer name:",RegistryKeyValueToString(val.value,val.type));
-
-println(" </table>");
-println(" <br />");
-// Iterate over all available network adapters
-var adapters=GetRegistryNodes(cur_controlset+"\\Services\\Tcpip\\Parameters\\Adapters");
-for(var i=0;i<adapters.length;i++) {
- // TODO: Try to get a human readable name
- println(" ",adapters[i]);
- // Get settings node
- var adapter_settings_node=GetRegistryKeyValue(cur_controlset+"\\Services\\Tcpip\\Parameters\\Adapters\\"+adapters[i],"IpConfig");
- adapter_settings_node=RegistryKeyValueToVariant(adapter_settings_node.value,"utf16",0);
+// Get current controlset
+var cur_controlset=GetRegistryKeyValue("\\Select","Current");
+if(IsValid(cur_controlset)) {
+ cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type);
+ // Current holds a DWORD value, thus we get a string like 0x00000000, but
+ // control sets are referenced by its decimal representation.
+ cur_controlset="ControlSet"+ZeroPad(parseInt(String(cur_controlset).substr(2,8),16),3)
+ println(" <p style=\"font-size:12; white-space:nowrap\">");
println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
+ print_table_row("Active control set:",cur_controlset);
- // Get configuration mode
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"EnableDHCP");
- val=Number(RegistryKeyValueToString(val.value,val.type));
- if(val) {
- // DHCP enabled
- print_table_row("Configuration mode:","DHCP");
- // DHCP server
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpServer");
- print_table_row("Last used DHCP server:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "");
- // IP address
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpIPAddress");
- print_table_row("IP address:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "");
- // Subnet mask
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpSubnetMask");
- print_table_row("Subnet mask:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "");
- // Nameserver(s)
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpNameServer");
- print_table_row("Nameserver(s):",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "");
- // Default gw
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpDefaultGateway");
- print_table_row("Default gateway:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
- // Lease obtained
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"LeaseObtainedTime");
- print_table_row("Lease obtained:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"unixtime",0) : "");
- // Lease valid until
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"LeaseTerminatesTime");
- print_table_row("Lease terminates:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"unixtime",0) : "");
- } else {
- print_table_row("Configuration mode:","Manual");
- // IP address
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"IPAddress");
- print_table_row("IP address:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
- // Subnet mask
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"SubnetMask");
- print_table_row("Subnet mask:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
- // Nameserver
- // TODO: Has to be validated
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"NameServer");
- print_table_row("Nameserver:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
- // Default gw
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DefaultGateway");
- print_table_row("Default gateway:",(typeof val !== 'undefined') ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
- }
+ // Computer name
+ val=GetRegistryKeyValue(cur_controlset+"\\Control\\ComputerName\\ComputerName","ComputerName");
+ print_table_row("Computer name:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "");
println(" </table>");
println(" <br />");
+
+ // Iterate over all available network adapters
+ var adapters=GetRegistryNodes(cur_controlset+"\\Services\\Tcpip\\Parameters\\Adapters");
+ for(var i=0;i<adapters.length;i++) {
+ // TODO: Try to get a human readable name
+ println(" ",adapters[i]);
+ // Get settings node
+ var adapter_settings_node=GetRegistryKeyValue(cur_controlset+"\\Services\\Tcpip\\Parameters\\Adapters\\"+adapters[i],"IpConfig");
+ adapter_settings_node=RegistryKeyValueToVariant(adapter_settings_node.value,"utf16",0);
+
+ println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
+
+ // Get configuration mode
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"EnableDHCP");
+ val=Number(RegistryKeyValueToString(val.value,val.type));
+ if(val) {
+ // DHCP enabled
+ print_table_row("Configuration mode:","DHCP");
+ // DHCP server
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpServer");
+ print_table_row("Last used DHCP server:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "");
+ // IP address
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpIPAddress");
+ print_table_row("IP address:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "");
+ // Subnet mask
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpSubnetMask");
+ print_table_row("Subnet mask:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "");
+ // Nameserver(s)
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpNameServer");
+ print_table_row("Nameserver(s):",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "");
+ // Default gw
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DhcpDefaultGateway");
+ print_table_row("Default gateway:",(IsValid(val)) ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
+ // Lease obtained
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"LeaseObtainedTime");
+ print_table_row("Lease obtained:",(IsValid(val)) ? RegistryKeyValueToVariant(val.value,"unixtime",0) : "");
+ // Lease valid until
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"LeaseTerminatesTime");
+ print_table_row("Lease terminates:",(IsValid(val)) ? RegistryKeyValueToVariant(val.value,"unixtime",0) : "");
+ } else {
+ print_table_row("Configuration mode:","Manual");
+ // IP address
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"IPAddress");
+ print_table_row("IP address:",(IsValid(val)) ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
+ // Subnet mask
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"SubnetMask");
+ print_table_row("Subnet mask:",(IsValid(val)) ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
+ // Nameserver
+ // TODO: Has to be validated
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"NameServer");
+ print_table_row("Nameserver:",(IsValid(val)) ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
+ // Default gw
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+adapter_settings_node,"DefaultGateway");
+ print_table_row("Default gateway:",(IsValid(val)) ? RegistryKeyValueToVariant(val.value,"utf16",0) : "");
+ }
+
+ println(" </table>");
+ println(" <br />");
+ }
+ println(" </p>");
+} else {
+ println(" <p><font color='red'>");
+ println(" Unable to determine current control set!<br />");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println(" </font></p>");
}
-println(" </p>");
println("</html>");
diff --git a/trunk/report_templates/SYSTEM_SystemTimeInfo.qs b/trunk/report_templates/SYSTEM_SystemTimeInfo.qs
index 9367040..e1dbd96 100644
--- a/trunk/report_templates/SYSTEM_SystemTimeInfo.qs
+++ b/trunk/report_templates/SYSTEM_SystemTimeInfo.qs
@@ -1,96 +1,110 @@
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
function print_table_row(cell01,cell02) {
println(" <tr><td>",cell01,"</td><td>",cell02,"</td></tr>");
}
function ToUTC(num) {
var retnum=new Number(num);
if(retnum&0x80000000) {
retnum=((0xFFFFFFFF-retnum)+1)/60;
return "UTC+"+Number(retnum).toString(10);
} else {
retnum=retnum/60;
if(retnum!=0) return "UTC-"+Number(retnum).toString(10);
else return "UTC+"+Number(retnum).toString(10);
}
}
function ZeroPad(number,padlen) {
var ret=number.toString(10);
if(!padlen || ret.length>=padlen) return ret;
return Math.pow(10,padlen-ret.length).toString().slice(1)+ret;
}
// Global vars
var val;
-// Get current controlset
-var cur_controlset=GetRegistryKeyValue("\\Select","Current");
-cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type);
-// Current holds a DWORD value, thus we get a string like 0x00000000, but
-// control sets are referenced by its decimal representation.
-cur_controlset="ControlSet"+ZeroPad(parseInt(String(cur_controlset).substr(2,8),16),3)
-
println("<html>");
println(" <head><title>System Time Info</title></head>");
println(" <body style=\"font-size:12\">");
println(" <h2>System time info (",cur_controlset,")</h2>");
-println(" <p style=\"font-size:12; white-space:nowrap\">");
-println(" <u>Time zone info</u>");
-println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
-// Active time bias
-val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","ActiveTimeBias");
-print_table_row("Active time bias:",(typeof val !== 'undefined') ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a");
+// Get current controlset
+var cur_controlset=GetRegistryKeyValue("\\Select","Current");
+if(IsValid(cur_controlset)) {
+ cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type);
+ // Current holds a DWORD value, thus we get a string like 0x00000000, but
+ // control sets are referenced by its decimal representation.
+ cur_controlset="ControlSet"+ZeroPad(parseInt(String(cur_controlset).substr(2,8),16),3)
-// Std. tz name and bias
-val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","StandardName");
-print_table_row("Std. time zone name:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
-val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","StandardBias");
-print_table_row("Std. time bias:",(typeof val !== 'undefined') ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a");
+ println(" <p style=\"font-size:12; white-space:nowrap\">");
+ println(" <u>Time zone info</u>");
+ println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
-// Daylight tz name and bias
-val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","DaylightName");
-print_table_row("Daylight time zone name:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
-val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","DaylightBias");
-print_table_row("Daylight time bias:",(typeof val !== 'undefined') ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a");
+ // Active time bias
+ val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","ActiveTimeBias");
+ print_table_row("Active time bias:",(IsValid(val)) ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a");
-println(" </table>");
-println(" <br />");
-println(" <u>W32Time service info</u>");
-println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
+ // Std. tz name and bias
+ val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","StandardName");
+ print_table_row("Std. time zone name:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","StandardBias");
+ print_table_row("Std. time bias:",(IsValid(val)) ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a");
-// Get W32Time service settings
-val=GetRegistryKeyValue(cur_controlset+"\\Services\\W32Time","Start");
-if(typeof val !== 'undefined') {
- print(" <tr><td>Startup method:</td><td>");
- val=RegistryKeyValueToString(val.value,val.type);
- switch(Number(val)) {
- case 0:
- print("Boot");
- break;
- case 1:
- print("System");
- break;
- case 2:
- print("Automatic");
- break;
- case 3:
- print("Manual");
- break;
- case 4:
- print("Disabled");
- break;
- default:
- print("Unknown");
- }
- println("</td></tr>");
- // If service is enabled, get ntp server
- if(Number(val)<4) {
- val=GetRegistryKeyValue(cur_controlset+"\\Services\\W32Time\\Parameters","NtpServer");
- print_table_row("NTP server(s):",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "n/a");
- }
-} else print_table_row("Startup method:","n/a");
+ // Daylight tz name and bias
+ val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","DaylightName");
+ print_table_row("Daylight time zone name:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ val=GetRegistryKeyValue(cur_controlset+"\\Control\\TimeZoneInformation","DaylightBias");
+ print_table_row("Daylight time bias:",(IsValid(val)) ? ToUTC(RegistryKeyValueToString(val.value,val.type)) : "n/a");
+
+ println(" </table>");
+ println(" <br />");
+ println(" <u>W32Time service info</u>");
+ println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
+
+ // Get W32Time service settings
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\W32Time","Start");
+ if(IsValid(val)) {
+ print(" <tr><td>Startup method:</td><td>");
+ val=RegistryKeyValueToString(val.value,val.type);
+ switch(Number(val)) {
+ case 0:
+ print("Boot");
+ break;
+ case 1:
+ print("System");
+ break;
+ case 2:
+ print("Automatic");
+ break;
+ case 3:
+ print("Manual");
+ break;
+ case 4:
+ print("Disabled");
+ break;
+ default:
+ print("Unknown");
+ }
+ println("</td></tr>");
+ // If service is enabled, get ntp server
+ if(Number(val)<4) {
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\W32Time\\Parameters","NtpServer");
+ print_table_row("NTP server(s):",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "n/a");
+ }
+ } else print_table_row("Startup method:","n/a");
+
+ println(" </table>");
+ println(" </p>");
+} else {
+ println(" <p><font color='red'>");
+ println(" Unable to determine current control set!<br />");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println(" </font></p>");
+}
-println(" </table>");
-println(" </p>");
println("</html>");
diff --git a/trunk/report_templates/SYSTEM_UsbStorageDevices.qs b/trunk/report_templates/SYSTEM_UsbStorageDevices.qs
index 343c8e2..9cd16f3 100644
--- a/trunk/report_templates/SYSTEM_UsbStorageDevices.qs
+++ b/trunk/report_templates/SYSTEM_UsbStorageDevices.qs
@@ -1,92 +1,139 @@
// TODO: There is more here. Check http://www.forensicswiki.org/wiki/USB_History_Viewing
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
function print_table_row(cell01,cell02) {
println(" <tr><td>",cell01,"</td><td>",cell02,"</td></tr>");
}
function ZeroPad(number,padlen) {
var ret=number.toString(10);
if(!padlen || ret.length>=padlen) return ret;
return Math.pow(10,padlen-ret.length).toString().slice(1)+ret;
}
// Global vars
var val;
+println("<html>");
+println(" <head><title>USB Storage Devices</title></head>");
+println(" <body style=\"font-size:12\">");
+println(" <h2>USB storage devices</h2>");
+
// Preload MountedDevices to possibly identify mount points of USB storage devices
var mnt_keys=GetRegistryKeys("\\MountedDevices");
var mnt_values=new Array();
-for(var i=0;i<mnt_keys.length;i++) {
- val=GetRegistryKeyValue("\\MountedDevices",mnt_keys[i]);
- mnt_values[i]=RegistryKeyValueToVariant(val.value,"utf16");
+if(IsValid(mnt_keys)) {
+ for(var i=0;i<mnt_keys.length;i++) {
+ val=GetRegistryKeyValue("\\MountedDevices",mnt_keys[i]);
+ mnt_values[i]=RegistryKeyValueToVariant(val.value,"utf16");
+ }
}
// Get current controlset
var cur_controlset=GetRegistryKeyValue("\\Select","Current");
-cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type);
-// Current holds a DWORD value, thus we get a string like 0x00000000, but
-// control sets are referenced by its decimal representation.
-cur_controlset="ControlSet"+ZeroPad(parseInt(String(cur_controlset).substr(2,8),16),3)
+if(IsValid(cur_controlset)) {
+ cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type);
+ // Current holds a DWORD value, thus we get a string like 0x00000000, but
+ // control sets are referenced by its decimal representation.
+ cur_controlset="ControlSet"+ZeroPad(parseInt(String(cur_controlset).substr(2,8),16),3)
-println("<html>");
-println(" <head><title>USB Storage Devices</title></head>");
-println(" <body style=\"font-size:12\">");
-println(" <h2>USB storage devices</h2>");
-println(" <p style=\"font-size:12; white-space:nowrap\">");
+ println(" <p style=\"font-size:12; white-space:nowrap\">");
+ println(" <u>Settings</u><br />");
+ println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
-var storage_roots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR");
-for(var i=0;i<storage_roots.length;i++) {
- println(" <u>",storage_roots[i],"</u><br />");
- var storage_subroots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]);
- for(ii=0;ii<storage_subroots.length;ii++) {
- println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
- // If the second character of the unique instance ID is a '&', then the ID was
- // generated by the system, as the device did not have a serial number.
- if(String(storage_subroots[ii]).charAt(1)=="&") print_table_row("Unique ID:",storage_subroots[ii]+" (Generated by system)");
- else print_table_row("Unique ID:",storage_subroots[ii]);
+ // Are USB storage devices enabled?
+ // http://www.forensicmag.com/article/windows-7-registry-forensics-part-5
+ // Is this true for WinXP etc.. ???
+ var val=GetRegistryKeyValue(cur_controlset+"\\services\\USBSTOR","Start");
+ if(IsValid(val)) {
+ val=RegistryKeyValueToString(val.value,val.type);
+ val=parseInt(String(val).substr(2,8),10);
+ switch(val) {
+ case 3:
+ print_table_row("Storage driver enabled:","Yes");
+ break;
+ case 4:
+ print_table_row("Storage driver enabled:","No");
+ break;
+ default:
+ print_table_row("Storage driver enabled:","Unknown");
+ }
+ } else {
+ print_table_row("Storage driver enabled:","Unknown");
+ }
- val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"Class");
- print_table_row("Class:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "");
- val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"DeviceDesc");
- print_table_row("Device description:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "");
- val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"FriendlyName");
- print_table_row("Friendly name:",(typeof val !== 'undefined') ? RegistryKeyValueToString(val.value,val.type) : "");
- val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"ParentIdPrefix");
- if(typeof val !== 'undefined') {
- // Windows XP used the ParentId to link to MountedDevices
- var parent_id=RegistryKeyValueToString(val.value,val.type);
- print_table_row("Parent ID prefix:",parent_id);
- // Find mount point(s)
- print(" <tr><td>Mount point(s):</td><td>");
- var br=0;
- for(var iii=0;iii<mnt_keys.length;iii++) {
- if(String(mnt_values[iii]).indexOf("#"+parent_id+"&")!=-1) {
- if(br==1) print("<br />");
- else br=1;
- print(mnt_keys[iii]);
- }
- }
- if(br==0) print("n/a");
- println("</td></tr>");
- } else {
- // Since Vista, Unique ID is used
- // Find mount point(s)
- print(" <tr><td>Mount point(s):</td><td>");
- var br=0;
- for(var iii=0;iii<mnt_keys.length;iii++) {
- if(String(mnt_values[iii]).indexOf("#"+storage_subroots[ii]+"#")!=-1) {
- if(br==1) print("<br />");
- else br=1;
- print(mnt_keys[iii]);
+ println(" </table>");
+ println(" </p>");
+ println(" <p style=\"font-size:12; white-space:nowrap\">");
+ println(" <u>Devices</u><br />");
+
+ var storage_roots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR");
+ if(IsValid(storage_roots)) {
+ for(var i=0;i<storage_roots.length;i++) {
+ println(" <u>",storage_roots[i],"</u><br />");
+ var storage_subroots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]);
+ for(ii=0;ii<storage_subroots.length;ii++) {
+ println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
+ // If the second character of the unique instance ID is a '&', then the ID was
+ // generated by the system, as the device did not have a serial number.
+ if(String(storage_subroots[ii]).charAt(1)=="&") print_table_row("Unique ID:",storage_subroots[ii]+" (Generated by system)");
+ else print_table_row("Unique ID:",storage_subroots[ii]);
+
+ val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"Class");
+ print_table_row("Class:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "");
+ val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"DeviceDesc");
+ print_table_row("Device description:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "");
+ val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"FriendlyName");
+ print_table_row("Friendly name:",(IsValid(val)) ? RegistryKeyValueToString(val.value,val.type) : "");
+ val=GetRegistryKeyValue(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]+"\\"+storage_subroots[ii],"ParentIdPrefix");
+ if(IsValid(val)) {
+ // Windows XP uses the ParentId to link to MountedDevices
+ var parent_id=RegistryKeyValueToString(val.value,val.type);
+ print_table_row("Parent ID prefix:",parent_id);
+ // Find mount point(s)
+ print(" <tr><td>Mount point(s):</td><td>");
+ var br=0;
+ for(var iii=0;iii<mnt_keys.length;iii++) {
+ if(String(mnt_values[iii]).indexOf("#"+parent_id+"&")!=-1) {
+ if(br==1) print("<br />");
+ else br=1;
+ print(mnt_keys[iii]);
+ }
+ }
+ if(br==0) print("n/a");
+ println("</td></tr>");
+ } else {
+ // Since Vista, Unique IDs are used
+ // Find mount point(s)
+ print(" <tr><td>Mount point(s):</td><td>");
+ var br=0;
+ for(var iii=0;iii<mnt_keys.length;iii++) {
+ if(String(mnt_values[iii]).indexOf("#"+storage_subroots[ii]+"#")!=-1) {
+ if(br==1) print("<br />");
+ else br=1;
+ print(mnt_keys[iii]);
+ }
+ }
+ if(br==0) print("n/a");
+ println("</td></tr>");
}
+ println(" </table>");
+ println(" <br />");
}
- if(br==0) print("n/a");
- println("</td></tr>");
}
- println(" </table>");
- println(" <br />");
+ } else {
+ println(" <font color='red'>This registry hive does not contain a list of attached USB storage devices!</font>");
}
+ println(" </p>");
+} else {
+ println(" <p><font color='red'>");
+ println(" Unable to determine current control set!<br />");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println(" </font></p>");
}
-println(" </p>");
println("</html>");
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Aug 24, 10:16 AM (17 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1310165
Default Alt Text
(105 KB)
Attached To
Mode
rFRED fred
Attached
Detach File
Event Timeline
Log In to Comment