diff --git a/tags/fred-0.1.0beta3/dlgreportviewer.cpp b/tags/fred-0.1.0beta3/dlgreportviewer.cpp index 9eaf6f4..21e58d5 100644 --- a/tags/fred-0.1.0beta3/dlgreportviewer.cpp +++ b/tags/fred-0.1.0beta3/dlgreportviewer.cpp @@ -1,88 +1,88 @@ /******************************************************************************* * 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 "dlgreportviewer.h" #include "ui_dlgreportviewer.h" #include #include DlgReportViewer::DlgReportViewer(QString &report_data, QWidget *p_parent) - : QMainWindow(p_parent,Qt::Dialog), ui(new Ui::DlgReportViewer) + : QMainWindow(p_parent,Qt::Dialog | Qt::Popup), ui(new Ui::DlgReportViewer) { // Init local vars ui->setupUi(this); this->p_local_event_loop=NULL; // Set report content this->ui->WebView->setHtml(report_data); // Set dialog title based on report content title QString report_title=this->ui->WebView->title(); if(report_title.isEmpty()) this->setWindowTitle("Report Viewer"); else this->setWindowTitle(report_title.prepend("Report Viewer : ")); } DlgReportViewer::~DlgReportViewer() { delete ui; if(this->p_local_event_loop!=NULL) this->p_local_event_loop->exit(); } void DlgReportViewer::changeEvent(QEvent *e) { QMainWindow::changeEvent(e); switch(e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } void DlgReportViewer::closeEvent(QCloseEvent *event) { // Make sure we exit the local event loop on exit if(this->p_local_event_loop!=NULL) { this->p_local_event_loop->exit(); this->p_local_event_loop=NULL; } event->accept(); } void DlgReportViewer::exec() { // Create local event loop this->p_local_event_loop=new QEventLoop(this); // Show window and enter loop this->show(); this->p_local_event_loop->exec(); } void DlgReportViewer::on_action_Print_triggered() { // Print report QPrinter printer; QPrintDialog *p_dlg_print=new QPrintDialog(&printer); if(p_dlg_print->exec()==QDialog::Accepted) { this->ui->WebView->print(&printer); } delete p_dlg_print; } void DlgReportViewer::on_action_Close_triggered() { this->close(); } diff --git a/tags/fred-0.1.0beta3/fred.pro b/tags/fred-0.1.0beta3/fred.pro index 3e7eb42..0117df8 100644 --- a/tags/fred-0.1.0beta3/fred.pro +++ b/tags/fred-0.1.0beta3/fred.pro @@ -1,104 +1,106 @@ #******************************************************************************* # 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 . * #******************************************************************************/ # Generate compileinfo.h system(bash compileinfo.sh > compileinfo.h) #compileinfo.target = compileinfo.h #compileinfo.commands = $$PWD/compileinfo.sh > compileinfo.h #QMAKE_EXTRA_TARGETS += compileinfo #PRE_TARGETDEPS += compileinfo.h # Build fred QMAKE_CXXFLAGS += -Wall QT += core \ gui \ 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 \ registrykeytable.cpp \ registrynodetree.cpp \ dlgsearch.cpp \ threadsearch.cpp \ searchresultwidget.cpp \ tabwidget.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 \ registrykeytable.h \ registrynodetree.h \ dlgsearch.h \ threadsearch.h \ searchresultwidget.h \ tabwidget.h FORMS += mainwindow.ui \ dlgabout.ui \ dlgkeydetails.ui \ dlgreportviewer.ui \ dlgsearch.ui #LIBS += -lhivex LIBS += $$PWD/hivex/lib/.libs/libhivex.a \ -liconv #DEFINES += __STDC_FORMAT_MACROS RESOURCES += fred.qrc +RC_FILE = fred.rc +ICON = resources/fred.icns diff --git a/tags/fred-0.1.0beta3/fred.rc b/tags/fred-0.1.0beta3/fred.rc new file mode 100644 index 0000000..2365184 --- /dev/null +++ b/tags/fred-0.1.0beta3/fred.rc @@ -0,0 +1 @@ +IDI_ICON1 ICON DISCARDABLE "resources/fred.ico" diff --git a/tags/fred-0.1.0beta3/hivex/lib/byte_conversions.h b/tags/fred-0.1.0beta3/hivex/lib/byte_conversions.h index aa4ffe6..2e4cafe 100644 --- a/tags/fred-0.1.0beta3/hivex/lib/byte_conversions.h +++ b/tags/fred-0.1.0beta3/hivex/lib/byte_conversions.h @@ -1,87 +1,87 @@ /* Useful byte conversion macros, not available on all platforms. * Copyright (C) 2009-2010 Red Hat Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ #ifndef hivex_byteorder_h #define hivex_byteorder_h #ifdef HAVE_ENDIAN_H #include #endif #include #if __BYTE_ORDER == __LITTLE_ENDIAN #ifndef be32toh -#define be32toh(x) __bswap_32 (x) +#define be32toh(x) bswap_32 (x) #endif #ifndef htobe32 -#define htobe32(x) __bswap_32 (x) +#define htobe32(x) bswap_32 (x) #endif #ifndef be64toh -#define be64toh(x) __bswap_64 (x) +#define be64toh(x) bswap_64 (x) #endif #ifndef htobe64 -#define htobe64(x) __bswap_64 (x) +#define htobe64(x) bswap_64 (x) #endif #ifndef le16toh #define le16toh(x) (x) #endif #ifndef htole16 #define htole16(x) (x) #endif #ifndef le32toh #define le32toh(x) (x) #endif #ifndef htole32 #define htole32(x) (x) #endif #ifndef le64toh #define le64toh(x) (x) #endif #ifndef htole64 #define htole64(x) (x) #endif #else /* __BYTE_ORDER == __BIG_ENDIAN */ #ifndef be32toh #define be32toh(x) (x) #endif #ifndef htobe32 #define htobe32(x) (x) #endif #ifndef be64toh #define be64toh(x) (x) #endif #ifndef htobe64 #define htobe64(x) (x) #endif #ifndef le16toh -#define le16toh(x) __bswap_16 (x) +#define le16toh(x) bswap_16 (x) #endif #ifndef htole16 -#define htole16(x) __bswap_16 (x) +#define htole16(x) bswap_16 (x) #endif #ifndef le32toh -#define le32toh(x) __bswap_32 (x) +#define le32toh(x) bswap_32 (x) #endif #ifndef htole32 -#define htole32(x) __bswap_32 (x) +#define htole32(x) bswap_32 (x) #endif #ifndef le64toh -#define le64toh(x) __bswap_64 (x) +#define le64toh(x) bswap_64 (x) #endif #ifndef htole64 -#define htole64(x) __bswap_64 (x) +#define htole64(x) bswap_64 (x) #endif #endif /* __BYTE_ORDER == __BIG_ENDIAN */ #endif /* hivex_byteorder_h */ diff --git a/tags/fred-0.1.0beta3/hivex_patches/byte_conversions.patch b/tags/fred-0.1.0beta3/hivex_patches/byte_conversions.patch new file mode 100644 index 0000000..467a35d --- /dev/null +++ b/tags/fred-0.1.0beta3/hivex_patches/byte_conversions.patch @@ -0,0 +1,54 @@ +diff --git a/lib/byte_conversions.h b/lib/byte_conversions.h +index aa4ffe6..2e4cafe 100644 +--- a/lib/byte_conversions.h ++++ b/lib/byte_conversions.h +@@ -22,16 +22,16 @@ + + #if __BYTE_ORDER == __LITTLE_ENDIAN + #ifndef be32toh +-#define be32toh(x) __bswap_32 (x) ++#define be32toh(x) bswap_32 (x) + #endif + #ifndef htobe32 +-#define htobe32(x) __bswap_32 (x) ++#define htobe32(x) bswap_32 (x) + #endif + #ifndef be64toh +-#define be64toh(x) __bswap_64 (x) ++#define be64toh(x) bswap_64 (x) + #endif + #ifndef htobe64 +-#define htobe64(x) __bswap_64 (x) ++#define htobe64(x) bswap_64 (x) + #endif + #ifndef le16toh + #define le16toh(x) (x) +@@ -65,22 +65,22 @@ + #define htobe64(x) (x) + #endif + #ifndef le16toh +-#define le16toh(x) __bswap_16 (x) ++#define le16toh(x) bswap_16 (x) + #endif + #ifndef htole16 +-#define htole16(x) __bswap_16 (x) ++#define htole16(x) bswap_16 (x) + #endif + #ifndef le32toh +-#define le32toh(x) __bswap_32 (x) ++#define le32toh(x) bswap_32 (x) + #endif + #ifndef htole32 +-#define htole32(x) __bswap_32 (x) ++#define htole32(x) bswap_32 (x) + #endif + #ifndef le64toh +-#define le64toh(x) __bswap_64 (x) ++#define le64toh(x) bswap_64 (x) + #endif + #ifndef htole64 +-#define htole64(x) __bswap_64 (x) ++#define htole64(x) bswap_64 (x) + #endif + #endif /* __BYTE_ORDER == __BIG_ENDIAN */ + diff --git a/tags/fred-0.1.0beta3/mainwindow.cpp b/tags/fred-0.1.0beta3/mainwindow.cpp index cc70ae7..6136a65 100644 --- a/tags/fred-0.1.0beta3/mainwindow.cpp +++ b/tags/fred-0.1.0beta3/mainwindow.cpp @@ -1,681 +1,685 @@ /******************************************************************************* * 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/" + #ifndef __MINGW32__ + #define FRED_REPORT_TEMPLATE_DIR "/usr/share/fred/report_templates/" + #else + #define FRED_REPORT_TEMPLATE_DIR ".\\report_templates\\" + #endif #endif #include #include #include #include #include #include #include "mainwindow.h" #include "ui_mainwindow.h" #include "dlgabout.h" #include "dlgkeydetails.h" #include "dlgreportviewer.h" #include "dlgsearch.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 TabWidget(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->addTab(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))); this->connect(this->p_tab_widget, SIGNAL(tabCloseRequested(int)), this, SLOT(SlotTabCloseButtonClicked(int))); // Add central widget this->setCentralWidget(this->p_horizontal_splitter); this->centralWidget()->setContentsMargins(4,4,4,0); // 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) { // Remove search results while(this->p_tab_widget->count()>1) { this->p_tab_widget->removeTab(this->p_tab_widget->count()-1); delete this->search_result_widgets.at(this->p_tab_widget->count()-1); this->search_result_widgets.removeLast(); } // 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 keywords; keywords.append(QByteArray(QString("Windows").toAscii())); // Add new search widget to tabwidget and to internal widget list SearchResultWidget *p_search_widget= new SearchResultWidget(this->p_tab_widget); p_search_widget->setEnabled(false); 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"),true); 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=this->p_reg_node_tree_model->GetNodePath(index); // 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("Byte offset: 0x%1 (%2)") .arg((uint16_t)hex_offset,4,16,QChar('0')) .arg(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); // Enable result widget this->search_result_widgets.last()->setEnabled(true); } void MainWindow::SlotSearchResultWidgetDoubleClicked(QModelIndex index) { SearchResultWidget *p_sender; QString path; QString match_type; QString value; QString key=""; int i; if(!index.isValid()) return; // 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(); value=p_sender->item(index.row(),2)->text(); if(match_type==tr("Node name")) { // Node name is not part of path. Add it if(path=="\\") path.append(value); else path.append("\\").append(value); } else if(match_type==tr("Key name")) { // Key name is stored in value key=value; } else if(match_type==tr("Key value")) { // Key name is part of path. Save and remove it QStringList nodes=path.split("\\",QString::SkipEmptyParts); key=nodes.at(nodes.count()-1); // Remove \ from path path.chop(key.length()+1); } // Expand treeview to correct node QList indexes= this->p_reg_node_tree_model->GetIndexListOf(path); for(i=0;ip_node_tree->expand(indexes.at(i)); } if(indexes.count()>0) { // Scroll to last expanded node, select it and update widgets this->p_node_tree->scrollTo(indexes.at(indexes.count()-1), QAbstractItemView::PositionAtCenter); this->p_node_tree->selectionModel()->clear(); this->p_node_tree->selectionModel()-> select(indexes.at(indexes.count()-1), QItemSelectionModel::Select); this->SlotNodeTreeClicked(indexes.at(indexes.count()-1)); } // Select correct key if search matched on keay name / value if(key!="") { int row=this->p_reg_key_table_model->GetKeyRow(key); this->p_key_table->clearSelection(); this->p_key_table->scrollTo(this->p_reg_key_table_model->index(row,0), QAbstractItemView::PositionAtCenter); this->p_key_table->selectRow(row); this->SlotKeyTableClicked(this->p_reg_key_table_model->index(row,0)); } } void MainWindow::SlotTabCloseButtonClicked(int index) { // Delete tab widget and remove tab this->p_tab_widget->removeTab(index); delete this->search_result_widgets.at(index-1); this->search_result_widgets.removeAt(index-1); } 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("%1 v%2").arg(APP_TITLE,APP_VERSION)); } else { this->setWindowTitle(QString("%1 v%2 - %3").arg(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;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->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/tags/fred-0.1.0beta3/registrykeytable.cpp b/tags/fred-0.1.0beta3/registrykeytable.cpp index 68fe059..ad65f73 100644 --- a/tags/fred-0.1.0beta3/registrykeytable.cpp +++ b/tags/fred-0.1.0beta3/registrykeytable.cpp @@ -1,128 +1,129 @@ /******************************************************************************* * 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 "registrykeytable.h" #include #include #include RegistryKeyTable::RegistryKeyTable(QWidget *p_parent) : QTableView(p_parent) { // Configure widget this->setSelectionMode(QAbstractItemView::SingleSelection); this->setSelectionBehavior(QAbstractItemView::SelectRows); 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(); } /* 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; // 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))) { 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::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/tags/fred-0.1.0beta3/resources/fred.icns b/tags/fred-0.1.0beta3/resources/fred.icns new file mode 100644 index 0000000..a6da484 Binary files /dev/null and b/tags/fred-0.1.0beta3/resources/fred.icns differ diff --git a/tags/fred-0.1.0beta3/resources/fred.ico b/tags/fred-0.1.0beta3/resources/fred.ico new file mode 100644 index 0000000..e06b47b Binary files /dev/null and b/tags/fred-0.1.0beta3/resources/fred.ico differ diff --git a/trunk/fred.pro b/trunk/fred.pro index 1faf7a0..0117df8 100644 --- a/trunk/fred.pro +++ b/trunk/fred.pro @@ -1,105 +1,106 @@ #******************************************************************************* # 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 . * #******************************************************************************/ # Generate compileinfo.h system(bash compileinfo.sh > compileinfo.h) #compileinfo.target = compileinfo.h #compileinfo.commands = $$PWD/compileinfo.sh > compileinfo.h #QMAKE_EXTRA_TARGETS += compileinfo #PRE_TARGETDEPS += compileinfo.h # Build fred QMAKE_CXXFLAGS += -Wall QT += core \ gui \ 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 \ registrykeytable.cpp \ registrynodetree.cpp \ dlgsearch.cpp \ threadsearch.cpp \ searchresultwidget.cpp \ tabwidget.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 \ registrykeytable.h \ registrynodetree.h \ dlgsearch.h \ threadsearch.h \ searchresultwidget.h \ tabwidget.h FORMS += mainwindow.ui \ dlgabout.ui \ dlgkeydetails.ui \ dlgreportviewer.ui \ dlgsearch.ui #LIBS += -lhivex LIBS += $$PWD/hivex/lib/.libs/libhivex.a \ -liconv #DEFINES += __STDC_FORMAT_MACROS RESOURCES += fred.qrc RC_FILE = fred.rc +ICON = resources/fred.icns diff --git a/trunk/resources/fred.icns b/trunk/resources/fred.icns new file mode 100644 index 0000000..a6da484 Binary files /dev/null and b/trunk/resources/fred.icns differ