Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F4324590
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
41 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/trunk/mainwindow.cpp b/trunk/mainwindow.cpp
index c3cff68..5cf6223 100644
--- a/trunk/mainwindow.cpp
+++ b/trunk/mainwindow.cpp
@@ -1,612 +1,640 @@
/*******************************************************************************
* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef FRED_REPORT_TEMPLATE_DIR
#define FRED_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates/"
#endif
#include <QFileDialog>
#include <QMessageBox>
#include <QStringList>
#include <QDesktopWidget>
#include <QDir>
#include <QSplitter>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dlgabout.h"
#include "dlgkeydetails.h"
#include "dlgreportviewer.h"
#include "dlgsearch.h"
-#include "searchresultwidget.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;
this->p_search_thread=NULL;
+ this->search_result_widgets.clear();
// Check for ~/.fred config dir
this->CheckUserConfigDir();
// Set main window size
int cur_screen=QApplication::desktop()->screenNumber(this);
int window_width=
QApplication::desktop()->availableGeometry(cur_screen).width()*0.5;
int window_height=
QApplication::desktop()->availableGeometry(cur_screen).height()*0.5;
int window_x=
(QApplication::desktop()->availableGeometry(cur_screen).width()/2)-
(window_width/2);
int window_y=
(QApplication::desktop()->availableGeometry(cur_screen).height()/2)-
(window_height/2);
this->setGeometry(window_x,
window_y,
window_width,
window_height);
// Create widgets
this->p_horizontal_splitter=new QSplitter();
this->p_horizontal_splitter->setOrientation(Qt::Horizontal);
this->p_node_tree=new RegistryNodeTree(this->p_horizontal_splitter);
this->p_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 RegistryKeyTable(this->p_vertical_splitter);
this->p_tab_widget=new QTabWidget(this->p_vertical_splitter);
this->p_horizontal_splitter2=new QSplitter();
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);
// Add hexedit page to tab_widget
this->p_tab_widget->insertTab(0,
this->p_horizontal_splitter2,
tr("Hex viewer"));
// 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_tab_widget);
this->p_horizontal_splitter->addWidget(this->p_node_tree);
this->p_horizontal_splitter->addWidget(this->p_vertical_splitter);
// Set stretch factors
QSizePolicy node_tree_policy=this->p_node_tree->sizePolicy();
node_tree_policy.setHorizontalStretch(1);
node_tree_policy.setVerticalStretch(100);
this->p_node_tree->setSizePolicy(node_tree_policy);
QSizePolicy vertical_splitter_policy=this->p_vertical_splitter->sizePolicy();
vertical_splitter_policy.setHorizontalStretch(4);
vertical_splitter_policy.setVerticalStretch(100);
this->p_vertical_splitter->setSizePolicy(vertical_splitter_policy);
QSizePolicy key_table_policy=this->p_key_table->sizePolicy();
key_table_policy.setVerticalStretch(5);
key_table_policy.setHorizontalStretch(100);
this->p_key_table->setSizePolicy(key_table_policy);
QSizePolicy tab_widget_policy=this->p_tab_widget->sizePolicy();
tab_widget_policy.setVerticalStretch(2);
tab_widget_policy.setHorizontalStretch(200);
this->p_tab_widget->setSizePolicy(tab_widget_policy);
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->ActionSearch->setEnabled(false);
this->ui->MenuReports->setEnabled(false);
this->UpdateWindowTitle();
}
}
void MainWindow::on_actionAbout_Qt_triggered() {
QMessageBox::aboutQt(this,tr("About Qt"));
}
void MainWindow::on_actionAbout_fred_triggered() {
DlgAbout dlg_about(this);
dlg_about.exec();
}
void MainWindow::on_ActionSearch_triggered() {
DlgSearch dlg_search(this);
if(dlg_search.exec()==QDialog::Accepted) {
// Create search thread and connect needed signals/slots
this->p_search_thread=new ThreadSearch(this);
QList<QByteArray> keywords;
keywords.append(QByteArray(QString("Windows").toAscii()));
- // Add new search widget to tabwidget
+ // Add new search widget to tabwidget and to internal widget list
SearchResultWidget *p_search_widget=
new SearchResultWidget(this->p_tab_widget);
+ //this->search_result_widgets.append(p_search_widget);
this->connect(p_search_widget,
SIGNAL(doubleClicked(QModelIndex)),
this,
SLOT(SlotSearchResultWidgetDoubleClicked(QModelIndex)));
this->p_tab_widget->addTab(p_search_widget,tr("Search results"));
this->p_tab_widget->setCurrentIndex(this->p_tab_widget->count()-1);
// Connect search thread to result widget
this->connect(this->p_search_thread,
SIGNAL(SignalFoundMatch(ThreadSearch::eMatchType,
QString,QString,QString)),
p_search_widget,
SLOT(SlotFoundMatch(ThreadSearch::eMatchType,
QString,QString,QString)));
this->connect(this->p_search_thread,
SIGNAL(finished()),
this,
SLOT(SlotSearchFinished()));
this->connect(this->p_search_thread,
SIGNAL(finished()),
p_search_widget,
SLOT(SlotSearchFinished()));
// Start searching
this->ui->ActionSearch->setEnabled(false);
p_search_thread->Search(this->p_hive->Filename(),
dlg_search.Keywords(),
dlg_search.SearchNodeNames(),
dlg_search.SearchKeyNames(),
dlg_search.SearchKeyValues());
}
}
void MainWindow::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);
}
void MainWindow::SlotKeyTableDoubleClicked(QModelIndex index) {
Q_UNUSED(index);
/*
QModelIndex key_index;
QModelIndex node_index;
QStringList nodes;
QString key_name;
QString key_type;
QByteArray key_value;
if(!index.isValid()) return;
// Get key name, type and value
key_index=this->p_reg_key_table_model->index(index.row(),0);
key_name=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();
key_index=this->p_reg_key_table_model->index(index.row(),1);
key_type=this->p_reg_key_table_model->data(key_index,Qt::DisplayRole)
.toString();ThreadSearch
key_index=this->p_reg_key_table_model->index(index.row(),2);
key_value=this->p_reg_key_table_model->data(key_index,
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
// Get current node
node_index=this->p_node_tree->currentIndex();
//Built node path
nodes.clear();
nodes.append(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
while(this->p_reg_node_tree_model->parent(node_index)!=QModelIndex()) {
// Prepend all parent nodes
node_index=this->p_reg_node_tree_model->parent(node_index);
nodes.prepend(this->p_reg_node_tree_model->
data(node_index,Qt::DisplayRole).toString());
}
DlgKeyDetails dlg_key_details(this);
dlg_key_details.SetValues(nodes,key_name,key_type,key_value);
dlg_key_details.exec();
*/
}
void MainWindow::SlotKeyTableClicked(QModelIndex index) {
if(!index.isValid()) return;
this->selected_key_value=
this->p_reg_key_table_model->data(this->p_reg_key_table_model->
index(index.row(),2),
RegistryKeyTableModel::
AdditionalRoles_GetRawData)
.toByteArray();
this->p_hex_edit->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::SlotSearchFinished() {
delete this->p_search_thread;
this->p_search_thread=NULL;
this->ui->ActionSearch->setEnabled(true);
}
void MainWindow::SlotSearchResultWidgetDoubleClicked(QModelIndex index) {
+ SearchResultWidget *p_sender;
+ QString path;
+ QString match_type;
+ QString key;
+ int i;
+
if(!index.isValid()) return;
- qDebug("Clicked on %u",index.row());
+ // Get pointer to sender
+ p_sender=(SearchResultWidget*)QObject::sender();
+
+ // Get path and matchtype
+ path=p_sender->item(index.row(),0)->text();
+ match_type=p_sender->item(index.row(),1)->text();
+
+ qDebug("Clicked on '%s' of type '%s'",path.toAscii().constData(),match_type.toAscii().constData());
+
+ if(match_type==tr("Node name")) {
+ // Search matched on node name, just expand treeview to correct node
+ QList<QModelIndex> indexes=
+ this->p_reg_node_tree_model->GetIndexListOf(path);
+ for(i=0;i<indexes.count();i++) {
+ this->p_node_tree->expand(indexes.at(i));
+ }
+ } else if(match_type==tr("Key name")) {
+
+ } else if(match_type==tr("Key value")) {
+
+ }
+
}
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:",
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("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;i<categories.count();i++) {
// First create category submenu
p_category_entry=this->ui->MenuReports->addMenu(categories.value(i));
// Now add category reports
reports=this->p_data_reporter->GetAvailableReports(categories.value(i));
for(ii=0;ii<reports.count();ii++) {
p_report_entry=new QAction(reports.value(ii),p_category_entry);
p_category_entry->addAction(p_report_entry);
this->connect(p_report_entry,
SIGNAL(triggered()),
this,
SLOT(SlotReportClicked()));
}
}
}
void MainWindow::OpenHive(QString hive_file) {
// Update last open location
this->last_open_location=hive_file.left(hive_file.
lastIndexOf(QDir::separator()));
// If another hive is currently open, close it
if(this->is_hive_open) this->on_action_Close_hive_triggered();
// Try to open hive
if(!this->p_hive->Open(hive_file)) {
QMessageBox::critical(this,
tr("Error opening hive file"),
tr("Unable to open file '%1'").arg(hive_file));
return;
}
// Create tree model
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->ActionSearch->setEnabled(true);
this->ui->MenuReports->setEnabled(true);
this->UpdateWindowTitle(hive_file);
}
void MainWindow::ParseCommandLineArgs() {
QStringList args=qApp->arguments();
// If exactly 1 argument was specified, it should be a hive to open
if(args.count()==2) {
this->OpenHive(args.at(1));
}
}
diff --git a/trunk/mainwindow.h b/trunk/mainwindow.h
index 4adb923..a2d94e8 100644
--- a/trunk/mainwindow.h
+++ b/trunk/mainwindow.h
@@ -1,134 +1,136 @@
/*******************************************************************************
* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QLabel>
#include <QTabWidget>
#include <QVBoxLayout>
#include <QSplitter>
#include <QString>
#include <QByteArray>
#include <hivex.h>
#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"
#include "threadsearch.h"
+#include "searchresultwidget.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 on_ActionSearch_triggered();
void SlotNodeTreeClicked(QModelIndex index);
void SlotKeyTableClicked(QModelIndex index);
void SlotKeyTableDoubleClicked(QModelIndex index);
void SlotHexEditAddressChanged(int hex_offset);
void SlotReportClicked();
void SlotSearchFinished();
void SlotSearchResultWidgetDoubleClicked(QModelIndex index);
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;
+ QList<SearchResultWidget*> search_result_widgets;
// Widgets etc...
RegistryNodeTree *p_node_tree;
RegistryKeyTable *p_key_table;
QTabWidget *p_tab_widget;
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;
ThreadSearch *p_search_thread;
/*
* 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/registrynodetreemodel.cpp b/trunk/registrynodetreemodel.cpp
index 078d5ac..e46e61f 100644
--- a/trunk/registrynodetreemodel.cpp
+++ b/trunk/registrynodetreemodel.cpp
@@ -1,138 +1,165 @@
/*******************************************************************************
* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "registrynodetreemodel.h"
+#include <QStringList>
+
#include <stdlib.h>
RegistryNodeTreeModel::RegistryNodeTreeModel(RegistryHive *p_hive,
QObject *p_parent)
: QAbstractItemModel(p_parent)
{
// Create root node
this->p_root_node=new RegistryNode("ROOT");
// Build node list
this->SetupModelData(p_hive,this->p_root_node);
}
RegistryNodeTreeModel::~RegistryNodeTreeModel() {
delete this->p_root_node;
}
QVariant RegistryNodeTreeModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid()) return QVariant();
if(role!=Qt::DisplayRole) return QVariant();
RegistryNode *p_node=static_cast<RegistryNode*>(index.internalPointer());
return p_node->data();
}
Qt::ItemFlags RegistryNodeTreeModel::flags(const QModelIndex &index) const {
if(!index.isValid()) return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant RegistryNodeTreeModel::headerData(int section,
Qt::Orientation orientation,
int role) const
{
Q_UNUSED(section);
if(orientation==Qt::Horizontal && role==Qt::DisplayRole) {
return QVariant("Registry key folders");
} else {
return QVariant();
}
}
QModelIndex RegistryNodeTreeModel::index(int row,
int column,
const QModelIndex &parent) const
{
if(!this->hasIndex(row,column,parent)) return QModelIndex();
RegistryNode *p_parent_node;
if(!parent.isValid()) {
p_parent_node=this->p_root_node;
} else {
p_parent_node=static_cast<RegistryNode*>(parent.internalPointer());
}
RegistryNode *p_child_node=p_parent_node->child(row);
if(p_child_node) {
return this->createIndex(row,column,p_child_node);
} else {
return QModelIndex();
}
}
QModelIndex RegistryNodeTreeModel::parent(const QModelIndex &index) const {
if(!index.isValid()) return QModelIndex();
RegistryNode *p_child_node=
static_cast<RegistryNode*>(index.internalPointer());
RegistryNode *p_parent_node=p_child_node->parent();
if(p_parent_node==this->p_root_node) {
return QModelIndex();
} else {
return this->createIndex(p_parent_node->row(),0,p_parent_node);
}
}
int RegistryNodeTreeModel::rowCount(const QModelIndex &parent) const {
if(parent.column()>0) return 0;
RegistryNode *p_parent_node;
if(!parent.isValid()) {
p_parent_node=this->p_root_node;
} else {
p_parent_node=static_cast<RegistryNode*>(parent.internalPointer());
}
return p_parent_node->childCount();
}
int RegistryNodeTreeModel::columnCount(const QModelIndex &parent) const {
Q_UNUSED(parent);
return 1;
}
+QList<QModelIndex> RegistryNodeTreeModel::GetIndexListOf(QString &path) const {
+ RegistryNode *p_parent_node=this->p_root_node;
+ QList<QModelIndex> ret;
+ QStringList nodes=path.split("\\",QString::SkipEmptyParts);
+ int i,ii;
+ bool found=false;
+
+ // Create a list of all index's that form the supplied path
+ ret.clear();
+ for(i=0;i<nodes.count();i++) {
+ found=false;
+ for(ii=0;ii<p_parent_node->childCount();ii++) {
+ if(p_parent_node->child(ii)->data()==nodes.at(i)) {
+ ret.append(this->createIndex(ii,0,p_parent_node));
+ p_parent_node==p_parent_node->child(ii);
+ found=true;
+ break;
+ }
+ }
+ if(!found) return QList<QModelIndex>();
+ }
+
+ return ret;
+}
+
void RegistryNodeTreeModel::SetupModelData(RegistryHive *p_hive,
RegistryNode *p_parent,
int hive_node)
{
QMap<QString,int> hive_children;
RegistryNode *p_node;
// Get all sub nodes of current hive node
if(hive_node) hive_children=p_hive->GetNodes(hive_node);
else hive_children=p_hive->GetNodes("\\");
if(hive_children.isEmpty()) return;
// Recursivly iterate over all sub nodes
QMapIterator<QString, int> i(hive_children);
while(i.hasNext()) {
i.next();
p_node=new RegistryNode(i.key(),p_parent);
p_parent->AppendChild(p_node);
this->SetupModelData(p_hive,p_node,i.value());
}
}
diff --git a/trunk/registrynodetreemodel.h b/trunk/registrynodetreemodel.h
index 941407f..d5df416 100644
--- a/trunk/registrynodetreemodel.h
+++ b/trunk/registrynodetreemodel.h
@@ -1,56 +1,60 @@
/*******************************************************************************
* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef REGISTRYNODETREEMODEL_H
#define REGISTRYNODETREEMODEL_H
#include <QAbstractItemModel>
+#include <QList>
+#include <QString>
#include "registrynode.h"
#include "registryhive.h"
class RegistryNodeTreeModel : public QAbstractItemModel {
Q_OBJECT
public:
RegistryNodeTreeModel(RegistryHive *p_hive, QObject *p_parent=0);
~RegistryNodeTreeModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section,
Qt::Orientation orientation,
int role=Qt::DisplayRole) const;
QModelIndex index(int row,
int column,
const QModelIndex &parent=QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent=QModelIndex()) const;
int columnCount(const QModelIndex &parent=QModelIndex()) const;
+ QList<QModelIndex> GetIndexListOf(QString &path) const;
+
private:
RegistryNode *p_root_node;
void SetupModelData(RegistryHive *p_hive,
RegistryNode *p_parent,
int hive_node=0);
};
#endif // REGISTRYNODETREEMODEL_H
diff --git a/trunk/searchresultwidget.cpp b/trunk/searchresultwidget.cpp
index 67d1886..a48ce9a 100644
--- a/trunk/searchresultwidget.cpp
+++ b/trunk/searchresultwidget.cpp
@@ -1,104 +1,104 @@
/*******************************************************************************
* fred Copyright (c) 2011 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor *
* with special feautures useful during forensic analysis. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#include "searchresultwidget.h"
#include <QHeaderView>
#include <QAbstractItemView>
#include <QStringList>
#include <QTableWidgetItem>
#include <QFontMetrics>
SearchResultWidget::SearchResultWidget(QWidget *p_parent)
: QTableWidget(p_parent)
{
this->setColumnCount(3);
this->setRowCount(0);
this->setTextElideMode(Qt::ElideNone);
this->verticalHeader()->setHidden(true);
this->setSelectionBehavior(QAbstractItemView::SelectRows);
this->setSelectionMode(QAbstractItemView::SingleSelection);
this->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
this->setHorizontalHeaderLabels(QStringList()<<tr("Path")
<<tr("Match type")
<<tr("Match text"));
}
void SearchResultWidget::SlotFoundMatch(ThreadSearch::eMatchType match_type,
QString path,
QString key,
QString value)
{
QTableWidgetItem *p_item;
QString full_path;
QString type;
QString match;
switch(match_type) {
case ThreadSearch::eMatchType_NodeName:
- type="Node name";
+ type=tr("Node name");
full_path=path;
match=key;
break;
case ThreadSearch::eMatchType_KeyName:
- type="Key node";
+ type=tr("Key node");
full_path=path;
match=key;
break;
case ThreadSearch::eMatchType_KeyValue:
- type="Key value";
+ type=tr("Key value");
full_path=path.append("\\").append(key);
match=value;
break;
}
int rows=this->rowCount();
this->setRowCount(rows+1);
p_item=new QTableWidgetItem(full_path=="" ? "\\" : full_path);
p_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
this->setItem(rows,0,p_item);
p_item=new QTableWidgetItem(type);
p_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
this->setItem(rows,1,p_item);
p_item=new QTableWidgetItem(match);
p_item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
this->setItem(rows,2,p_item);
}
int SearchResultWidget::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;i<this->rowCount();i++) {
item_width=fm.width(this->item(i,column)->text())+10;
if(item_width>size_hint) size_hint=item_width;
}
return size_hint;
}
void SearchResultWidget::SlotSearchFinished() {
this->resizeColumnsToContents();
this->resizeRowsToContents();
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Dec 24, 3:09 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1176823
Default Alt Text
(41 KB)
Attached To
Mode
rFRED fred
Attached
Detach File
Event Timeline
Log In to Comment