diff --git a/trunk/datainterpreter.cpp b/trunk/datainterpreter.cpp
index 6cf0e84..6d6bd74 100644
--- a/trunk/datainterpreter.cpp
+++ b/trunk/datainterpreter.cpp
@@ -1,72 +1,76 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 "datainterpreter.h"
#include
#include
DataInterpreter::DataInterpreter(QWidget *p_parent)
: QTableWidget(p_parent)
{
this->setColumnCount(2);
this->setTextElideMode(Qt::ElideNone);
this->horizontalHeader()->setHidden(true);
this->verticalHeader()->setHidden(true);
+ this->setSelectionBehavior(QAbstractItemView::SelectRows);
+ this->setSelectionMode(QAbstractItemView::SingleSelection);
}
DataInterpreter::~DataInterpreter() {
// Free table widget items
this->ClearValues();
}
void DataInterpreter::AddValue(QString name, QString value) {
QTableWidgetItem *p_name_item=new QTableWidgetItem(name);
+ p_name_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
QTableWidgetItem *p_value_item=new QTableWidgetItem(value);
+ p_value_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
this->setRowCount(this->rowCount()+1);
this->setItem(this->rowCount()-1,0,p_name_item);
this->setItem(this->rowCount()-1,1,p_value_item);
this->resizeColumnsToContents();
this->resizeRowsToContents();
}
void DataInterpreter::ClearValues() {
// Free all items
while(this->rowCount()>0) {
delete this->item(0,0);
delete this->item(0,1);
this->setRowCount(this->rowCount()-1);
}
}
int DataInterpreter::sizeHintForColumn(int column) const {
int size_hint=0;
int i=0;
int item_width=0;
QFontMetrics fm(this->fontMetrics());
// Find string that needs the most amount of space
for(i=0;irowCount();i++) {
item_width=fm.width(this->item(i,column)->text())+10;
if(item_width>size_hint) size_hint=item_width;
}
return size_hint;
}
diff --git a/trunk/datareporter.cpp b/trunk/datareporter.cpp
index 10072dc..8a80086 100644
--- a/trunk/datareporter.cpp
+++ b/trunk/datareporter.cpp
@@ -1,152 +1,171 @@
/*******************************************************************************
* fred Copyright (c) 2011 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("."));
- // Add report to list
- p_report=new ReportTemplate(report_category,
- report_name,
- report_template);
- this->report_templates.append(p_report);
+ // 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;
DataReporterEngine engine(p_hive);
QString report_code;
//ReportData report_data;
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;
}
QScriptValue hive_value=engine.newQObject(p_hive);
engine.globalObject().setProperty("RegistryHive",hive_value);
//QScriptValue return_value=engine.newQObject(&report_data);
//engine.globalObject().setProperty("ReportData",return_value);
// Open report template
QFile template_file(p_report->File());
if(!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug("Couldn't open file '%s'",p_report->File().toAscii().constData());
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();
QScriptValue report_result=engine.evaluate(report_code,p_report->File());
if (report_result.isError() || engine.hasUncaughtException()) {
QMessageBox::critical(0,
"Hello Script",
QString::fromLatin1("%0:%1: %2")
.arg(p_report->File())
.arg(report_result.property("lineNumber").toInt32())
.arg(report_result.toString()));
return QString();
}
return engine.report_content;
}
return QString();
}
diff --git a/trunk/fred.pro b/trunk/fred.pro
index 934bb59..ac6f55a 100644
--- a/trunk/fred.pro
+++ b/trunk/fred.pro
@@ -1,80 +1,84 @@
#*******************************************************************************
# fred Copyright (c) 2011 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 . *
#******************************************************************************/
system(bash compileinfo.sh > compileinfo.h)
QT += core \
gui \
xml \
script \
webkit
TARGET = fred
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
registrynode.cpp \
registrynodetreemodel.cpp \
registrykey.cpp \
registrykeytablemodel.cpp \
dlgabout.cpp \
dlgkeydetails.cpp \
qhexedit/qhexedit_p.cpp \
qhexedit/qhexedit.cpp \
datainterpreter.cpp \
reporttemplate.cpp \
datareporter.cpp \
datareporterengine.cpp \
registryhive.cpp \
qtscript_types/bytearray.cpp \
qtscript_types/bytearrayprototype.cpp \
qtscript_types/bytearrayiterator.cpp \
- dlgreportviewer.cpp
+ dlgreportviewer.cpp \
+ registrykeytable.cpp \
+ registrynodetree.cpp
HEADERS += mainwindow.h \
registrynode.h \
registrynodetreemodel.h \
registrykey.h \
registrykeytablemodel.h \
dlgabout.h \
dlgkeydetails.h \
qhexedit/qhexedit_p.h \
qhexedit/qhexedit.h \
datainterpreter.h \
reporttemplate.h \
datareporter.h \
datareporterengine.h \
registryhive.h \
qtscript_types/bytearray.h \
qtscript_types/bytearrayprototype.h \
qtscript_types/bytearrayiterator.h \
- dlgreportviewer.h
+ dlgreportviewer.h \
+ registrykeytable.h \
+ registrynodetree.h
FORMS += mainwindow.ui \
dlgabout.ui \
dlgkeydetails.ui \
dlgreportviewer.ui
LIBS += -lhivex
RESOURCES += fred.qrc
diff --git a/trunk/mainwindow.cpp b/trunk/mainwindow.cpp
index a9dd55f..ab19b99 100644
--- a/trunk/mainwindow.cpp
+++ b/trunk/mainwindow.cpp
@@ -1,541 +1,538 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 FRED_REPORT_TEMPLATE_DIR
#define FRED_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates/"
#endif
#include
#include
#include
#include
#include
#include
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dlgabout.h"
#include "dlgkeydetails.h"
#include "dlgreportviewer.h"
#include "compileinfo.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// Initialize private vars
this->p_hive=new RegistryHive(this);
this->is_hive_open=false;
this->p_reg_node_tree_model=NULL;
this->p_reg_key_table_model=NULL;
// Check for ~/.fred config dir
this->CheckUserConfigDir();
// Set main window size
int cur_screen=QApplication::desktop()->screenNumber(this);
int window_width=
QApplication::desktop()->availableGeometry(cur_screen).width()*0.5;
int window_height=
QApplication::desktop()->availableGeometry(cur_screen).height()*0.5;
int window_x=
(QApplication::desktop()->availableGeometry(cur_screen).width()/2)-
(window_width/2);
int window_y=
(QApplication::desktop()->availableGeometry(cur_screen).height()/2)-
(window_height/2);
this->setGeometry(window_x,
window_y,
window_width,
window_height);
// Create widgets
this->p_horizontal_splitter=new QSplitter();
this->p_horizontal_splitter->setOrientation(Qt::Horizontal);
- this->p_node_tree=new QTreeView(this->p_horizontal_splitter);
+ this->p_node_tree=new RegistryNodeTree(this->p_horizontal_splitter);
this->p_node_tree->setHeaderHidden(true);
this->p_vertical_splitter=new QSplitter(this->p_horizontal_splitter);
this->p_vertical_splitter->setOrientation(Qt::Vertical);
- this->p_key_table=new QTableView(this->p_vertical_splitter);
- this->p_key_table->setSelectionBehavior(QAbstractItemView::SelectRows);
+ this->p_key_table=new RegistryKeyTable(this->p_vertical_splitter);
this->p_horizontal_splitter2=new QSplitter(this->p_vertical_splitter);
this->p_horizontal_splitter2->setOrientation(Qt::Horizontal);
this->p_hex_edit_widget=new QWidget(this->p_horizontal_splitter2);
this->p_hex_edit_layout=new QVBoxLayout(this->p_hex_edit_widget);
this->p_hex_edit_layout->setContentsMargins(0,0,0,0);
this->p_hex_edit=new QHexEdit();
this->p_hex_edit->setReadOnly(true);
this->p_hex_edit_status_bar=new QLabel();
this->p_data_interpreter=new DataInterpreter(this->p_horizontal_splitter2);
// Make sure hex viewer font is monospaced.
QFont mono_font("Monospace");
mono_font.setStyleHint(QFont::TypeWriter);
this->p_hex_edit->setFont(mono_font);
// Lay out widgets
this->p_hex_edit_layout->addWidget(this->p_hex_edit);
this->p_hex_edit_layout->addWidget(this->p_hex_edit_status_bar);
this->p_horizontal_splitter2->addWidget(this->p_hex_edit_widget);
this->p_horizontal_splitter2->addWidget(this->p_data_interpreter);
this->p_vertical_splitter->addWidget(this->p_key_table);
this->p_vertical_splitter->addWidget(this->p_horizontal_splitter2);
this->p_horizontal_splitter->addWidget(this->p_node_tree);
this->p_horizontal_splitter->addWidget(this->p_vertical_splitter);
// Set stretch factors
QSizePolicy node_tree_policy=this->p_node_tree->sizePolicy();
node_tree_policy.setHorizontalStretch(1);
node_tree_policy.setVerticalStretch(100);
this->p_node_tree->setSizePolicy(node_tree_policy);
QSizePolicy vertical_splitter_policy=this->p_vertical_splitter->sizePolicy();
vertical_splitter_policy.setHorizontalStretch(4);
vertical_splitter_policy.setVerticalStretch(100);
this->p_vertical_splitter->setSizePolicy(vertical_splitter_policy);
QSizePolicy key_table_policy=this->p_key_table->sizePolicy();
key_table_policy.setVerticalStretch(5);
key_table_policy.setHorizontalStretch(100);
this->p_key_table->setSizePolicy(key_table_policy);
QSizePolicy hex_edit_widget_policy=this->p_hex_edit_widget->sizePolicy();
hex_edit_widget_policy.setVerticalStretch(2);
hex_edit_widget_policy.setHorizontalStretch(200);
this->p_hex_edit_widget->setSizePolicy(hex_edit_widget_policy);
QSizePolicy data_interpreter_policy=this->p_data_interpreter->sizePolicy();
data_interpreter_policy.setVerticalStretch(2);
data_interpreter_policy.setHorizontalStretch(0);
this->p_data_interpreter->setSizePolicy(data_interpreter_policy);
// Connect signals
this->connect(this->p_node_tree,
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_node_tree,
SIGNAL(activated(QModelIndex)),
this,
SLOT(SlotNodeTreeClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(clicked(QModelIndex)),
this,
SLOT(SlotKeyTableClicked(QModelIndex)));
this->connect(this->p_key_table,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotKeyTableDoubleClicked(QModelIndex)));
this->connect(this->p_hex_edit,
SIGNAL(currentAddressChanged(int)),
this,
SLOT(SlotHexEditAddressChanged(int)));
// Add central widget
this->setContentsMargins(4,4,4,0);
this->setCentralWidget(this->p_horizontal_splitter);
// Set window title
this->UpdateWindowTitle();
// Set last open location to home dir
this->last_open_location=QDir::homePath();
// Load report templates and update menu
this->p_data_reporter=new DataReporter();
// Load reports from system wide include dir
this->p_data_reporter->LoadReportTemplates(FRED_REPORT_TEMPLATE_DIR);
// Load user's report templates
this->p_data_reporter->LoadReportTemplates(QDir::homePath()
.append(QDir::separator())
.append(".fred")
.append(QDir::separator())
.append("report_templates"));
this->UpdateDataReporterMenu();
// Finally, parse command line arguments
this->ParseCommandLineArgs();
}
MainWindow::~MainWindow() {
if(this->is_hive_open) {
this->p_hive->Close();
}
delete ui;
}
void MainWindow::on_action_Quit_triggered() {
qApp->exit();
}
void MainWindow::on_action_Open_hive_triggered() {
QString hive_file="";
hive_file=QFileDialog::getOpenFileName(this,
tr("Open registry hive"),
this->last_open_location,
tr("All files (*)"));
if(hive_file=="") return;
this->OpenHive(hive_file);
}
void MainWindow::on_action_Close_hive_triggered() {
if(this->is_hive_open) {
// Delete models
if(this->p_reg_node_tree_model!=NULL) {
+ this->p_node_tree->setModel(NULL);
delete this->p_reg_node_tree_model;
this->p_reg_node_tree_model=NULL;
}
if(this->p_reg_key_table_model!=NULL) {
+ this->p_key_table->setModel(NULL);
delete this->p_reg_key_table_model;
this->p_reg_key_table_model=NULL;
}
// Remove any data from hex edit and data interpreter
this->p_hex_edit->setData(QByteArray());
this->p_hex_edit_status_bar->setText("");
this->p_data_interpreter->ClearValues();
// Close hive
this->p_hive->Close();
this->is_hive_open=false;
this->ui->action_Close_hive->setEnabled(false);
this->ui->MenuReports->setEnabled(false);
this->UpdateWindowTitle();
}
}
void MainWindow::on_actionAbout_Qt_triggered() {
QMessageBox::aboutQt(this,tr("About Qt"));
}
void MainWindow::on_actionAbout_fred_triggered() {
DlgAbout dlg_about(this);
dlg_about.exec();
}
void MainWindow::SlotNodeTreeClicked(QModelIndex index) {
QString node_path;
if(!index.isValid()) return;
//Built node path
node_path.clear();
node_path=this->p_reg_node_tree_model->data(index,Qt::DisplayRole)
.toString().prepend("\\");
while(this->p_reg_node_tree_model->parent(index)!=QModelIndex()) {
// Prepend all parent nodes
index=this->p_reg_node_tree_model->parent(index);
node_path.prepend(this->p_reg_node_tree_model->data(index,Qt::DisplayRole)
.toString().prepend("\\"));
}
// Create table model and attach it to the table view
if(this->p_reg_key_table_model!=NULL) {
+ this->p_key_table->setModel(NULL);
delete this->p_reg_key_table_model;
this->p_hex_edit->setData(QByteArray());
this->p_hex_edit_status_bar->setText("");
this->p_data_interpreter->ClearValues();
}
this->p_reg_key_table_model=new RegistryKeyTableModel(this->p_hive,node_path);
this->p_key_table->setModel(this->p_reg_key_table_model);
-
- // Resize table rows / columns to fit data
- this->p_key_table->resizeColumnsToContents();
- this->p_key_table->horizontalHeader()->stretchLastSection();
}
void MainWindow::SlotKeyTableDoubleClicked(QModelIndex index) {
Q_UNUSED(index);
/*
QModelIndex key_index;
QModelIndex node_index;
QStringList nodes;
QString key_name;
QString key_type;
QByteArray key_value;
if(!index.isValid()) return;
// Get key name, type and value
key_index=this->p_reg_key_table_model->index(index.row(),0);
key_name=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();
key_index=this->p_reg_key_table_model->index(index.row(),1);
key_type=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();
key_index=this->p_reg_key_table_model->index(index.row(),2);
key_value=this->p_reg_key_table_model->data(key_index,
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
// Get current node
node_index=this->p_node_tree->currentIndex();
//Built node path
nodes.clear();
nodes.append(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
while(this->p_reg_node_tree_model->parent(node_index)!=QModelIndex()) {
// Prepend all parent nodes
node_index=this->p_reg_node_tree_model->parent(node_index);
nodes.prepend(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
}
DlgKeyDetails dlg_key_details(this);
dlg_key_details.SetValues(nodes,key_name,key_type,key_value);
dlg_key_details.exec();
*/
}
void MainWindow::SlotKeyTableClicked(QModelIndex index) {
if(!index.isValid()) return;
this->selected_key_value=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),2),
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
this->p_hex_edit->setData(this->selected_key_value);
}
void MainWindow::SlotHexEditAddressChanged(int hex_offset) {
+ if(!this->is_hive_open || this->selected_key_value.isEmpty()) return;
+
// Update hex edit status bar
this->p_hex_edit_status_bar->
setText(QString().sprintf("Byte offset: 0x%04X (%u)",hex_offset,hex_offset));
// Update data interpreter
this->UpdateDataInterpreter(hex_offset);
}
void MainWindow::SlotReportClicked() {
// Get report category and name from sender and it's parent
QString category=((QMenu*)((QAction*)QObject::sender())->parent())->title();
QString report=((QAction*)QObject::sender())->text();
// Generate report
QString report_content=this->p_data_reporter->GenerateReport(this->p_hive,
category,
report);
// Show result in report viewer
if(report_content!=QString()) {
DlgReportViewer *p_dlg_report_view=new DlgReportViewer(report_content,this);
p_dlg_report_view->exec();
delete p_dlg_report_view;
} else {
// TODO: Something went wrong!
}
}
void MainWindow::CheckUserConfigDir() {
QString user_config_dir=QDir::homePath()
.append(QDir::separator())
.append(".fred");
if(!QDir(user_config_dir).exists()) {
// User config dir does not exists, try to create it
if(!QDir().mkpath(user_config_dir)) {
// TODO: Maybe warn user
return;
}
user_config_dir.append(QDir::separator()).append("report_templates");
if(!QDir().mkpath(user_config_dir)) {
// TODO: Maybe warn user
return;
}
}
}
void MainWindow::UpdateWindowTitle(QString filename) {
if(filename=="") {
this->setWindowTitle(QString().sprintf("%s v%s",APP_TITLE,APP_VERSION));
} else {
this->setWindowTitle(QString().sprintf("%s v%s - %s",
APP_TITLE,
APP_VERSION,
filename.toLocal8Bit().constData()));
}
}
void MainWindow::UpdateDataInterpreter(int hex_offset) {
QDateTime date_time;
const char *p_data;
int remaining_data_len;
// Remove all old values from data interpreter
this->p_data_interpreter->ClearValues();
// Calculate how many bytes are remainig after current offset
remaining_data_len=this->selected_key_value.size()-hex_offset;
if(!remaining_data_len>0) {
// Nothing to show
return;
}
// Get pointer to data at current offset
p_data=this->selected_key_value.constData();
p_data+=hex_offset;
//#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
//#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
//#define rotl64(x,n) (((x) << n) | ((x) >> (64 - n)))
//#define rotr64(x,n) (((x) >> n) | ((x) << (64 - n)))
if(remaining_data_len>=1) {
this->p_data_interpreter->AddValue("int8:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"int8",
hex_offset));
this->p_data_interpreter->AddValue("uint8:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"uint8",
hex_offset));
}
if(remaining_data_len>=2) {
this->p_data_interpreter->AddValue("int16:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"int16",
hex_offset));
this->p_data_interpreter->AddValue("uint16:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"uint16",
hex_offset));
}
if(remaining_data_len>=4) {
this->p_data_interpreter->AddValue("int32:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"int32",
hex_offset));
this->p_data_interpreter->AddValue("uint32:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"uint32",
hex_offset));
- this->p_data_interpreter->AddValue("Unixtime:",
+ this->p_data_interpreter->AddValue("unixtime:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"unixtime",
hex_offset));
}
if(remaining_data_len>=8) {
this->p_data_interpreter->AddValue("int64:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"int64",
hex_offset));
this->p_data_interpreter->AddValue("uint64:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"uint64",
hex_offset));
- this->p_data_interpreter->AddValue("Filetime:",
+ this->p_data_interpreter->AddValue("filetime64:",
RegistryHive::KeyValueToString(
this->selected_key_value,
"filetime",
hex_offset));
}
//#undef rotl32
//#undef rotl64
}
void MainWindow::UpdateDataReporterMenu() {
int i=0,ii=0;
QMenu *p_category_entry;
QAction *p_report_entry;
QStringList categories=this->p_data_reporter->GetAvailableReportCategories();
QStringList reports;
for(i=0;iui->MenuReports->addMenu(categories.value(i));
// Now add category reports
reports=this->p_data_reporter->GetAvailableReports(categories.value(i));
for(ii=0;iiaddAction(p_report_entry);
this->connect(p_report_entry,
SIGNAL(triggered()),
this,
SLOT(SlotReportClicked()));
}
}
}
void MainWindow::OpenHive(QString hive_file) {
// Update last open location
this->last_open_location=hive_file.left(hive_file.
lastIndexOf(QDir::separator()));
// If another hive is currently open, close it
if(this->is_hive_open) this->on_action_Close_hive_triggered();
// Try to open hive
if(!this->p_hive->Open(hive_file)) {
QMessageBox::critical(this,
tr("Error opening hive file"),
tr("Unable to open file '%1'").arg(hive_file));
return;
}
// Create tree model
this->p_reg_node_tree_model=
new RegistryNodeTreeModel(this->p_hive);
this->p_node_tree->setModel(this->p_reg_node_tree_model);
this->is_hive_open=true;
this->ui->action_Close_hive->setEnabled(true);
this->ui->MenuReports->setEnabled(true);
this->UpdateWindowTitle(hive_file);
}
void MainWindow::ParseCommandLineArgs() {
QStringList args=qApp->arguments();
- // Return if no args were specified
- if(args.count()==1) return;
-
+ // If exactly 1 argument was specified, it should be a hive to open
if(args.count()==2) {
- // Try to open specified hive file
this->OpenHive(args.at(1));
}
}
diff --git a/trunk/mainwindow.h b/trunk/mainwindow.h
index 68d4b6e..f2b0c4b 100644
--- a/trunk/mainwindow.h
+++ b/trunk/mainwindow.h
@@ -1,119 +1,121 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include "registryhive.h"
+#include "registrynodetree.h"
#include "registrynodetreemodel.h"
+#include "registrykeytable.h"
#include "registrykeytablemodel.h"
#include "qhexedit/qhexedit.h"
#include "datainterpreter.h"
#include "datareporter.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_action_Quit_triggered();
void on_action_Open_hive_triggered();
void on_action_Close_hive_triggered();
void on_actionAbout_Qt_triggered();
void on_actionAbout_fred_triggered();
void SlotNodeTreeClicked(QModelIndex index);
void SlotKeyTableClicked(QModelIndex index);
void SlotKeyTableDoubleClicked(QModelIndex index);
void SlotHexEditAddressChanged(int hex_offset);
void SlotReportClicked();
private:
Ui::MainWindow *ui;
QString last_open_location;
RegistryHive *p_hive;
bool is_hive_open;
RegistryNodeTreeModel *p_reg_node_tree_model;
RegistryKeyTableModel *p_reg_key_table_model;
QByteArray selected_key_value;
// Widgets etc...
- QTreeView *p_node_tree;
- QTableView *p_key_table;
+ RegistryNodeTree *p_node_tree;
+ RegistryKeyTable *p_key_table;
QWidget *p_hex_edit_widget;
QHexEdit *p_hex_edit;
QLabel *p_hex_edit_status_bar;
DataInterpreter *p_data_interpreter;
QVBoxLayout *p_hex_edit_layout;
QSplitter *p_horizontal_splitter;
QSplitter *p_horizontal_splitter2;
QSplitter *p_vertical_splitter;
DataReporter *p_data_reporter;
/*
* CheckUserConfigDir
*
* Checks for and possibly creates the ~/.fred directory
*/
void CheckUserConfigDir();
/*
* UpdateWindowTitle
*
* Updates the window title
*/
void UpdateWindowTitle(QString filename="");
/*
* UpdateDataInterpreter
*
* Update data interpreter
*/
void UpdateDataInterpreter(int hex_offset);
/*
* UpdateDataReporterMenu
*
*/
void UpdateDataReporterMenu();
/*
* OpenHive
*
* Open a registry hive
*/
void OpenHive(QString hive_file);
/*
* ParseCommandLineArgs
*
* Parse command line arguments
*/
void ParseCommandLineArgs();
};
#endif // MAINWINDOW_H
diff --git a/trunk/registrykeytable.cpp b/trunk/registrykeytable.cpp
new file mode 100644
index 0000000..6fc383a
--- /dev/null
+++ b/trunk/registrykeytable.cpp
@@ -0,0 +1,37 @@
+#include "registrykeytable.h"
+
+#include
+
+RegistryKeyTable::RegistryKeyTable(QWidget *p_parent) : QTableView(p_parent) {
+ // Configure widget
+ this->setSelectionMode(QAbstractItemView::SingleSelection);
+ this->setSelectionBehavior(QAbstractItemView::SelectRows);
+ this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
+}
+
+void RegistryKeyTable::setModel(QAbstractItemModel *p_model) {
+ QTableView::setModel(p_model);
+ // Resize table rows / columns to fit data
+ this->resizeColumnsToContents();
+ this->horizontalHeader()->stretchLastSection();
+}
+
+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;
+}
diff --git a/trunk/registrykeytable.h b/trunk/registrykeytable.h
new file mode 100644
index 0000000..b565a7a
--- /dev/null
+++ b/trunk/registrykeytable.h
@@ -0,0 +1,18 @@
+#ifndef REGISTRYKEYTABLE_H
+#define REGISTRYKEYTABLE_H
+
+#include
+
+class RegistryKeyTable : public QTableView {
+ Q_OBJECT
+
+ public:
+ RegistryKeyTable(QWidget *p_parent=0);
+
+ void setModel(QAbstractItemModel *p_model);
+
+ protected:
+ int sizeHintForColumn(int column) const;
+};
+
+#endif // REGISTRYKEYTABLE_H
diff --git a/trunk/registrynodetree.cpp b/trunk/registrynodetree.cpp
new file mode 100644
index 0000000..f9ba344
--- /dev/null
+++ b/trunk/registrynodetree.cpp
@@ -0,0 +1,16 @@
+#include "registrynodetree.h"
+
+#include
+
+RegistryNodeTree::RegistryNodeTree(QWidget *p_parent) : QTreeView(p_parent) {
+ // Configure widget
+ this->setTextElideMode(Qt::ElideNone);
+}
+
+void RegistryNodeTree::setModel(QAbstractItemModel *p_model) {
+ QTreeView::setModel(p_model);
+ this->header()->setResizeMode(0,QHeaderView::ResizeToContents);
+ this->header()->setStretchLastSection(false);
+}
+
+//int RegistryNodeTree::sizeHintForColumn(int column) const {}
diff --git a/trunk/registrynodetree.h b/trunk/registrynodetree.h
new file mode 100644
index 0000000..93326a4
--- /dev/null
+++ b/trunk/registrynodetree.h
@@ -0,0 +1,19 @@
+#ifndef REGISTRYNODETREE_H
+#define REGISTRYNODETREE_H
+
+#include
+#include
+
+class RegistryNodeTree : public QTreeView {
+ Q_OBJECT
+
+ public:
+ RegistryNodeTree(QWidget *p_parent=0);
+
+ void setModel(QAbstractItemModel *p_model);
+
+ //protected:
+ // int sizeHintForColumn(int column) const;
+};
+
+#endif // REGISTRYNODETREE_H
diff --git a/trunk/report_templates/SAM_UserAccounts.qs b/trunk/report_templates/SAM_UserAccounts.qs
index 7ab402c..94a9616 100644
--- a/trunk/report_templates/SAM_UserAccounts.qs
+++ b/trunk/report_templates/SAM_UserAccounts.qs
@@ -1,81 +1,81 @@
// See http://windowsir.blogspot.com/2006/08/getting-user-info-from-image.html
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");
+ println(" ");
// Print user name
println(" ",user_names[i],"
");
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,")"," |
");
// 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 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 ");
println(" |
");
// Get password hint if available
var hint=GetRegistryKeyValue(String().concat("\\SAM\\Domains\\Account\\Users\\",user_rid),"UserPasswordHint");
if(typeof hint !== 'undefined') {
print_table_row("Password hint:",RegistryKeyValueToVariant(hint.value,"utf16",0));
}
// TODO: User group membership
println("
");
println("
");
}
println("");
diff --git a/trunk/report_templates/SOFTWARE_WindowsVersion.qs b/trunk/report_templates/SOFTWARE_WindowsVersion.qs
index 5c301c8..0b28e64 100644
--- a/trunk/report_templates/SOFTWARE_WindowsVersion.qs
+++ b/trunk/report_templates/SOFTWARE_WindowsVersion.qs
@@ -1,82 +1,82 @@
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("
");
+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");
// Install date
var val=GetRegistryKeyValue("\\Microsoft\\Windows NT\\CurrentVersion","InstallDate");
print_table_row("Install date:",(typeof val !== 'undefined') ? 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");
// 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");
// 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");
println("
");
println(" ");
println("");
diff --git a/trunk/report_templates/SYSTEM_CurrentNetworkSettings.qs b/trunk/report_templates/SYSTEM_CurrentNetworkSettings.qs
index 583fc63..7bfb9b2 100644
--- a/trunk/report_templates/SYSTEM_CurrentNetworkSettings.qs
+++ b/trunk/report_templates/SYSTEM_CurrentNetworkSettings.qs
@@ -1,91 +1,91 @@
function print_table_row(cell01,cell02) {
println(" ",cell01," | ",cell02," |
");
}
// 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 only with the last 3 digits.
cur_controlset="ControlSet"+String(cur_controlset).substr(7,3);
println("");
println(" Current Network Settings (Tcp/Ip)");
println(" ");
println(" Current network settings (Tcp/Ip)
");
-println(" ");
-println("
");
+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(" ");
// 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) : "");
}
println("
");
println("
");
}
println(" ");
println("");
diff --git a/trunk/report_templates/SYSTEM_SystemTimeInfo.qs b/trunk/report_templates/SYSTEM_SystemTimeInfo.qs
index 17af169..1063b7c 100644
--- a/trunk/report_templates/SYSTEM_SystemTimeInfo.qs
+++ b/trunk/report_templates/SYSTEM_SystemTimeInfo.qs
@@ -1,90 +1,90 @@
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);
}
}
// 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 only with the last 3 digits.
cur_controlset="ControlSet"+String(cur_controlset).substr(7,3);
println("");
println(" System Time Info");
println(" ");
println(" System time info (",cur_controlset,")
");
-println(" ");
+println("
");
println(" Time zone info");
-println("
");
+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");
// 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");
// 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");
println("
");
println("
");
println(" W32Time service info");
-println(" ");
+println(" ");
// 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");
println("
");
println(" ");
println("");
diff --git a/trunk/report_templates/SYSTEM_UsbStorageDevices.qs b/trunk/report_templates/SYSTEM_UsbStorageDevices.qs
index 65b6e5b..ac0e109 100644
--- a/trunk/report_templates/SYSTEM_UsbStorageDevices.qs
+++ b/trunk/report_templates/SYSTEM_UsbStorageDevices.qs
@@ -1,68 +1,86 @@
// TODO: There is more here. Check http://www.forensicswiki.org/wiki/USB_History_Viewing
function print_table_row(cell01,cell02) {
println(" ",cell01," | ",cell02," |
");
}
// Global vars
var val;
// 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("
");
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");
+ println(" ");
// 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:",(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 print_table_row("Parent ID prefix:","n/a");
+ } 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]);
+ }
+ }
+ if(br==0) print("n/a");
+ println(" |
");
+ }
+ println("
");
+ println("
");
}
}
println("
");
println("");
diff --git a/trunk/reporttemplate.cpp b/trunk/reporttemplate.cpp
index 8f6ee11..eceb427 100644
--- a/trunk/reporttemplate.cpp
+++ b/trunk/reporttemplate.cpp
@@ -1,42 +1,54 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 "reporttemplate.h"
ReportTemplate::ReportTemplate(QString report_category,
QString report_name,
QString report_template_file)
{
this->category=report_category;
this->name=report_name;
this->template_file=report_template_file;
}
+void ReportTemplate::SetCategory(QString new_category) {
+ this->category=new_category;
+}
+
+void ReportTemplate::SetName(QString new_name) {
+ this->name=new_name;
+}
+
+void ReportTemplate::SetFile(QString new_file) {
+ this->template_file=new_file;
+}
+
QString ReportTemplate::ReportTemplate::Category() {
return this->category;
}
QString ReportTemplate::ReportTemplate::Name() {
return this->name;
}
QString ReportTemplate::ReportTemplate::File() {
return this->template_file;
}
diff --git a/trunk/reporttemplate.h b/trunk/reporttemplate.h
index 5acebeb..86624af 100644
--- a/trunk/reporttemplate.h
+++ b/trunk/reporttemplate.h
@@ -1,42 +1,46 @@
/*******************************************************************************
* fred Copyright (c) 2011 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 REPORTTEMPLATE_H
#define REPORTTEMPLATE_H
#include
class ReportTemplate {
public:
ReportTemplate(QString report_category,
QString report_name,
QString report_template_file);
+ void SetCategory(QString new_category);
+ void SetName(QString new_name);
+ void SetFile(QString new_file);
+
QString Category();
QString Name();
QString File();
private:
QString category;
QString name;
QString template_file;
};
#endif // REPORTTEMPLATE_H