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 *
* *
* 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 . *
*******************************************************************************/
#include "datareporter.h"
#include
#include
#include
#include
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_.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;iireport_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;ireport_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;ireport_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;ireport_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 *
* *
* 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 . *
*******************************************************************************/
#include "datareporterengine.h"
#include
#include
#include
#include
+#include
#include
DataReporterEngine::DataReporterEngine(RegistryHive *p_hive) : QScriptEngine() {
// Init vars
this->p_registry_hive=p_hive;
this->report_content="";
// Add our types to engine
qScriptRegisterMetaType(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;iargumentCount();++i) {
//if(i>0) content.append(" ");
content.append(context->argument(i).toString());
}
//QScriptValue calleeData=context->callee().data();
//DataReporterEngine *engine=
// qobject_cast(calleeData.toQObject());
qobject_cast(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;iargumentCount();++i) {
//if(i>0) content.append(" ");
content.append(context->argument(i).toString());
}
qobject_cast(engine)->
report_content.append(content).append("\n");
return engine->undefinedValue();
}
/*
* GetRegistryNodes
*/
QScriptValue DataReporterEngine::GetRegistryNodes(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QMap 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(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 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 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(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 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(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(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(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(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(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 *
* *
* 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 . *
*******************************************************************************/
#ifndef DATAREPORTERENGINE_H
#define DATAREPORTERENGINE_H
#include
#include
#include
#include
#include
#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 *
* *
* 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 . *
*******************************************************************************/
#include "registryhive.h"
#include
#include
#include
#include
// 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 RegistryHive::GetNodes(QString path) {
hive_node_h parent_node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QMap();
// Get and return nodes
return this->GetNodesHelper(parent_node);
}
/*
* GetNodes
*/
QMap RegistryHive::GetNodes(int parent_node) {
if(parent_node==0) {
this->SetError(tr("Invalid parent node handle specified!"));
return QMap();
}
// Get and return nodes
return this->GetNodesHelper(parent_node);
}
/*
* GetKeys
*/
QMap RegistryHive::GetKeys(QString path) {
hive_node_h parent_node;
// Get handle to last node in path
if(!this->GetNodeHandle(path,&parent_node)) return QMap();
// Get and return keys
return this->GetKeysHelper(parent_node);
}
/*
* GetKeys
*/
QMap RegistryHive::GetKeys(int parent_node) {
if(parent_node==0) {
this->SetError(tr("Invalid parent node handle specified!"));
return QMap();
}
// 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;i0) {
// 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;ip_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 RegistryHive::GetNodesHelper(hive_node_h parent_node) {
QMap 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();
}
// 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();
}
keys.insert(QString(p_name),(int)child_nodes[i]);
free(p_name);
i++;
}
free(child_nodes);
return keys;
}
/*
* GetKeysHelper
*/
QMap RegistryHive::GetKeysHelper(hive_node_h parent_node) {
QMap 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();
}
// 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();
}
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 *
* *
* 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 . *
*******************************************************************************/
#ifndef REGISTRYHIVE_H
#define REGISTRYHIVE_H
#include
#include
#include
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 GetNodes(QString path="\\");
QMap GetNodes(int parent_node=0);
QMap GetKeys(QString path="\\");
QMap 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 GetNodesHelper(hive_node_h parent_node);
QMap 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 *
* *
* 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 . *
*******************************************************************************/
#include "registrykeytable.h"
#include
#include
#include
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;imodel()->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 *
* *
* 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 . *
*******************************************************************************/
#include "registrynodetree.h"
#include "registrynodetreemodel.h"
#include
#include
#include
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("");
println(" Recent Documents");
println(" ");
println(" Recent documents
");
-println(" ");
-println("
");
// Get list of recent docs
var recent_docs=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs","MRUListEx");
+if(IsValid(recent_docs)) {
+ println(" ");
+ println("
");
+ println(" Document | Last modified |
");
+
+ // 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(" ",RegistryKeyValueToVariant(entry.value,"utf16",0)," | ",mod_time," |
");
+ 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(" ",RegistryKeyValueToVariant(entry.value,"utf16",0)," |
");
- i+=4;
- runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i);
+ println("
");
+ println(" ");
+} else {
+ println(" ");
+ println(" This registry hive does not contain a list of recent documents!");
+ println("
");
}
-println("
");
-println("
");
println("");
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("");
println(" Typed Urls");
println(" ");
println(" Typed urls
");
-println(" ");
-println("
");
// Iterate over all typed urls
var typed_urls=GetRegistryKeys("\\Software\\Microsoft\\Internet Explorer\\TypedURLs");
-for(var i=0;i",RegistryKeyValueToString(val.value,val.type)," | ");
+if(IsValid(typed_urls)) {
+ println(" ");
+ println("
");
+ println(" Url | Last modified |
");
+
+ for(var i=0;i",RegistryKeyValueToString(val.value,val.type)," | ",mod_time," | ");
+ }
+
+ println("
");
+ println(" ");
+} else {
+ println(" ");
+ println(" This registry hive does not contain a list of typed urls!");
+ println("
");
}
-println("
");
-println(" ");
println("");
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("");
println(" Windows Live Accounts");
println(" ");
println(" Windows live accounts
");
-println(" ");
-println("
");
// Iterate over all contacts
var accounts=GetRegistryKeys("\\Software\\Microsoft\\Windows Live Contacts\\Database");
-for(var i=0;i",accounts[i]," | ",RegistryKeyValueToString(val.value,val.type)," | ");
-}
-accounts=GetRegistryKeys("\\Software\\Microsoft\\Windows Live Contacts\\Me");
-for(var i=0;i",accounts[i]," | ",RegistryKeyValueToString(val.value,val.type)," | ");
+if(IsValid(accounts)) {
+ println(" ");
+ println("
");
+
+ for(var i=0;i",accounts[i]," | ",RegistryKeyValueToString(val.value,val.type)," | ");
+ }
+ accounts=GetRegistryKeys("\\Software\\Microsoft\\Windows Live Contacts\\Me");
+ for(var i=0;i",accounts[i]," | ",RegistryKeyValueToString(val.value,val.type)," | ");
+ }
+
+ println("
");
+ println(" ");
+} else {
+ println(" ");
+ println(" This registry hive does not contain a list of Windows Live Accounts!");
+ println("
");
}
-println("
");
-println(" ");
println("");
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(" ",cell01," | ",cell02," |
");
}
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("");
println(" User Accounts");
println(" ");
println(" User accounts
");
// Iterate over all user names
var user_names=GetRegistryNodes("\\SAM\\Domains\\Account\\Users\\Names");
-for(var i=0;i");
+if(IsValid(user_names)) {
+ for(var i=0;i");
- // Print user name
- println(" ",user_names[i],"
");
+ // Print user name
+ println(" ",user_names[i],"
");
- println(" ");
+ println(" ");
- // 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(" RID: | ",Number(user_rid).toString(10)," (",user_rid,")"," |
");
+ // 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(" RID: | ",Number(user_rid).toString(10)," (",user_rid,")"," |
");
- // 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(" Account flags: | ");
- 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(" |
");
+ // 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(" Account flags: | ");
+ 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(" |
");
- // 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("
");
- println(" ");
+ println("
");
+ println(" ");
+ }
+} else {
+ println(" ");
+ println(" Unable to enumerate users!
");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println("
");
}
println("");
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(" ",cell01," | ",cell02," |
");
}
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("");
println(" Windows version info");
println(" ");
println(" Windows version info
");
-println(" ");
-println("
");
// Windows version sp and build info
var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","ProductName");
-print(" Windows version: | ",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(" |
");
-// 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(" ");
+ println("
");
-// 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(" Windows version: | ",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(" |
");
+ // 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("
");
+ println(" ");
+} else {
+ println(" ");
+ println(" Unable to get product name!
");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println("
");
+}
-println("
");
-println(" ");
println("");
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(" ",cell01," | ",cell02," |
");
}
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("");
println(" Current Network Settings (Tcp/Ip)");
println(" ");
println(" Current network settings (Tcp/Ip)
");
-println(" ");
-println("
");
-
-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("
");
-println("
");
-// Iterate over all available network adapters
-var adapters=GetRegistryNodes(cur_controlset+"\\Services\\Tcpip\\Parameters\\Adapters");
-for(var i=0;i");
println(" ");
+ 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("
");
println("
");
+
+ // Iterate over all available network adapters
+ var adapters=GetRegistryNodes(cur_controlset+"\\Services\\Tcpip\\Parameters\\Adapters");
+ for(var i=0;i");
+
+ // 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(" ");
+ println("
");
+ }
+ println(" ");
+} else {
+ println(" ");
+ println(" Unable to determine current control set!
");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println("
");
}
-println(" ");
println("");
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(" ",cell01," | ",cell02," |
");
}
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("");
println(" System Time Info");
println(" ");
println(" System time info (",cur_controlset,")
");
-println(" ");
-println(" Time zone info");
-println("
");
-// 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(" ");
+ println(" Time zone info");
+ println("
");
-// 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("
");
-println("
");
-println(" W32Time service info");
-println(" ");
+ // 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(" Startup method: | ");
- 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(" |
");
- // 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("
");
+ println("
");
+ println(" W32Time service info");
+ println(" ");
+
+ // Get W32Time service settings
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\W32Time","Start");
+ if(IsValid(val)) {
+ print(" Startup method: | ");
+ 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(" |
");
+ // 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("
");
+ println(" ");
+} else {
+ println(" ");
+ println(" Unable to determine current control set!
");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println("
");
+}
-println("
");
-println(" ");
println("");
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(" ",cell01," | ",cell02," |
");
}
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("");
+println(" USB Storage Devices");
+println(" ");
+println(" USB storage devices
");
+
// 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");
-println(" USB Storage Devices");
-println(" ");
-println(" USB storage devices
");
-println(" ");
+ println("
");
+ println(" Settings
");
+ println("
");
-var storage_roots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR");
-for(var i=0;i",storage_roots[i],"
");
- var storage_subroots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]);
- for(ii=0;ii");
- // 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(" Mount point(s): | ");
- var br=0;
- for(var iii=0;iii");
- else br=1;
- print(mnt_keys[iii]);
- }
- }
- if(br==0) print("n/a");
- println(" |
");
- } else {
- // Since Vista, Unique ID is used
- // Find mount point(s)
- print(" Mount point(s): | ");
- var br=0;
- for(var iii=0;iii");
- else br=1;
- print(mnt_keys[iii]);
+ println(" |
");
+ println(" ");
+ println(" ");
+ println(" Devices
");
+
+ var storage_roots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR");
+ if(IsValid(storage_roots)) {
+ for(var i=0;i",storage_roots[i],"
");
+ var storage_subroots=GetRegistryNodes(cur_controlset+"\\Enum\\USBSTOR\\"+storage_roots[i]);
+ for(ii=0;ii");
+ // 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(" Mount point(s): | ");
+ var br=0;
+ for(var iii=0;iii");
+ else br=1;
+ print(mnt_keys[iii]);
+ }
+ }
+ if(br==0) print("n/a");
+ println(" |
");
+ } else {
+ // Since Vista, Unique IDs are used
+ // Find mount point(s)
+ print(" Mount point(s): | ");
+ var br=0;
+ for(var iii=0;iii");
+ else br=1;
+ print(mnt_keys[iii]);
+ }
+ }
+ if(br==0) print("n/a");
+ println(" |
");
}
+ println(" ");
+ println("
");
}
- if(br==0) print("n/a");
- println("");
}
- println(" ");
- println("
");
+ } else {
+ println(" This registry hive does not contain a list of attached USB storage devices!");
}
+ println("
");
+} else {
+ println(" ");
+ println(" Unable to determine current control set!
");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println("
");
}
-println(" ");
println("");