diff --git a/trunk/argparser.cpp b/trunk/argparser.cpp index bf362d0..c1d8c13 100644 --- a/trunk/argparser.cpp +++ b/trunk/argparser.cpp @@ -1,159 +1,127 @@ /******************************************************************************* * fred Copyright (c) 2011-2012 by Gillen Daniel * * * * Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor * * with special feautures useful during forensic analysis. * * * * This program is free software: you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation, either version 3 of the License, or (at your option) * * any later version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * *******************************************************************************/ -#include - #include "argparser.h" ArgParser::ArgParser(QStringList args) { this->argv=QStringList(args); this->argc=this->argv.count(); this->error_msg=""; this->parsed_args.clear(); } QString ArgParser::GetErrorMsg() { QString msg=this->error_msg; this->error_msg=""; return msg; } bool ArgParser::ParseArgs() { int i=0; int sep_pos=0; QString cur_arg=""; QString cur_arg_param=""; while(i+1argc) { // Get current argument cur_arg=this->argv.at(++i); if(cur_arg.size()>1) { // Check for short mode command line args if(cur_arg[0]=='-' && cur_arg[1]!='-') { if(cur_arg=="-?" || cur_arg=="-h") { this->parsed_args.insert(cur_arg.mid(1),QString()); continue; } else if(cur_arg=="-v") { this->parsed_args.insert(cur_arg.mid(1),QString()); continue; } else { // Unknown argument this->SetError(QString("Unknown command line argument '%1'!") .arg(cur_arg)); return false; } } // Check for long mode command line args if(cur_arg[0]=='-' && cur_arg[1]=='-') { // Extract argument parameter if there is one sep_pos=cur_arg.indexOf('='); if(sep_pos!=-1) { cur_arg_param=cur_arg.mid(sep_pos+1); // Remove parameter from arg cur_arg=cur_arg.left(sep_pos); } else { cur_arg_param=""; } if(cur_arg=="--") { // Stop processing arguments. Anything that follows this argument is // considered to be a hive to open i++; break; } else if(cur_arg=="--help") { this->parsed_args.insert(cur_arg.mid(2),QString()); continue; } else if(cur_arg=="--version") { this->parsed_args.insert(cur_arg.mid(2),QString()); continue; } else if(cur_arg=="--dump-report") { this->parsed_args.insert(cur_arg.mid(2),cur_arg_param); continue; } else { // Unknown argument this->SetError(QString("Unknown command line argument '%1'!") .arg(cur_arg)); return false; } } } // Found argument not beginning with '-' or '--' if(i+1==this->argc) { // If this is the last argument, it should be a hive file this->parsed_args.insert(QString("hive-file"),cur_arg); break; } else { // If it isn't the last argument, there is an error this->SetError(QString("Unknown command line argument '%1'!") .arg(cur_arg)); return false; } } return true; } bool ArgParser::IsSet(QString arg) { return this->parsed_args.contains(arg); } QString ArgParser::GetArgVal(QString arg) { // If arg is not in parsed_args, the following will return a // "default-constructed value" which should be a QString() according to the // docs. return this->parsed_args[arg]; } - - - - - -void ArgParser::PrintUsage() { - printf("Usage:\n"); - printf(" %s [opts] [hive]\n\n",this->argv.at(0).toAscii().constData()); - printf("Options:\n"); - printf(" opts:\n"); - printf(" -?, -h, --help : Display this help message.\n"); - printf(" -v, --version : Display version info.\n"); - - printf(" --dump-report=FILE : Dump the specified report to stdout.\n"); - - - printf(" hive:\n"); - printf(" Use the specified hive file.\n"); - - printf("\n"); -} - - - - - - - - - void ArgParser::SetError(QString msg) { this->error_msg=msg; } diff --git a/trunk/argparser.h b/trunk/argparser.h index ee0f157..04a2eb5 100644 --- a/trunk/argparser.h +++ b/trunk/argparser.h @@ -1,50 +1,45 @@ /******************************************************************************* * fred Copyright (c) 2011-2012 by Gillen Daniel * * * * Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor * * with special feautures useful during forensic analysis. * * * * This program is free software: you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation, either version 3 of the License, or (at your option) * * any later version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * *******************************************************************************/ #ifndef ARGPARSER_H #define ARGPARSER_H #include #include #include class ArgParser { public: ArgParser(QStringList args); - QString GetErrorMsg(); - bool ParseArgs(); - bool IsSet(QString arg); QString GetArgVal(QString arg); - void PrintUsage(); - private: QStringList argv; int argc; QString error_msg; QHash parsed_args; void SetError(QString msg=QString()); }; #endif // ARGPARSER_H diff --git a/trunk/datareporter.cpp b/trunk/datareporter.cpp index 6687996..a37fe85 100644 --- a/trunk/datareporter.cpp +++ b/trunk/datareporter.cpp @@ -1,171 +1,200 @@ /******************************************************************************* * fred Copyright (c) 2011-2012 by Gillen Daniel * * * * Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor * * with special feautures useful during forensic analysis. * * * * This program is free software: you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation, either version 3 of the License, or (at your option) * * any later version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * *******************************************************************************/ #include "datareporter.h" #include #include #include #include DataReporter::DataReporter() { this->report_templates.clear(); //this->p_report_engine=new DataReporterEngine(); } DataReporter::~DataReporter() { //delete this->p_report_engine; qDeleteAll(this->report_templates); } void DataReporter::LoadReportTemplates(QString dir) { QString report_template=""; int i=0; int ii=0; bool found=false; QString report_category=""; QString report_name=""; ReportTemplate *p_report; // Get all template files in report_templates directory QDir report_dir(dir); QStringList found_report_templates=report_dir. entryList(QStringList()<<"*.qs"); for(i=0;i_.qs) report_category=found_report_templates.value(i).left( found_report_templates.value(i).indexOf("_")); report_name=found_report_templates.value(i).mid( found_report_templates.value(i).indexOf("_")+1); report_name=report_name.left(report_name.lastIndexOf(".")); // Check if a report with the same category/name was already added found=false; for(ii=0;iireport_templates.count();ii++) { if(this->report_templates.at(ii)->Category()==report_category && this->report_templates.at(ii)->Name()==report_name) { found=true; break; } } if(!found) { // Add report to list p_report=new ReportTemplate(report_category, report_name, report_template); this->report_templates.append(p_report); } else { // Update report entry p_report=this->report_templates.at(ii); p_report->SetFile(report_template); } } } QStringList DataReporter::GetAvailableReportCategories() { QStringList ret; QString cat; int i=0; ret.clear(); for(i=0;ireport_templates.count();i++) { cat=this->report_templates.value(i)->Category(); if(!ret.contains(cat)) ret.append(cat); } ret.sort(); return ret; } QStringList DataReporter::GetAvailableReports(QString category) { QStringList ret; QString cat; int i=0; ret.clear(); for(i=0;ireport_templates.count();i++) { cat=this->report_templates.value(i)->Category(); if(cat==category) ret.append(this->report_templates.value(i)->Name()); } ret.sort(); return ret; } QString DataReporter::GenerateReport(RegistryHive *p_hive, QString report_category, QString report_name) { int i=0; ReportTemplate *p_report; - DataReporterEngine engine(p_hive); - QString report_code; - //ReportData report_data; + // Search report template for(i=0;ireport_templates.count();i++) { p_report=this->report_templates.value(i); if(p_report->Category()!=report_category || p_report->Name()!=report_name) { continue; } + // Report template was found, now generate report and return result + return this->GenerateReport(p_hive,p_report->File()); + } + + // Report template couldn't be found + QMessageBox::critical(0, + "Report engine error", + QString("Unable to find report with name '%1' in category '%2'!") + .arg(report_name) + .arg(report_category)); + return QString(); +} - 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); +QString DataReporter::GenerateReport(RegistryHive *p_hive, + QString report_template, + bool console_mode) +{ + QString report_code; - // 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"); + // Init data reporter engine + DataReporterEngine engine(p_hive); + QScriptValue hive_value=engine.newQObject(p_hive); + engine.globalObject().setProperty("RegistryHive",hive_value); + + // Open report template + QFile template_file(report_template); + if(!template_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + if(!console_mode) { + QMessageBox::critical(0, + "Report engine error", + QString("Couldn't open report template file '%1'!") + .arg(report_template)); + } else { + printf("ERROR: Couldn't open report template file '%s'!\n", + report_template.toAscii().constData()); } - // Close report template file - template_file.close(); + return QString(); + } + + // Read template file + QTextStream in(&template_file); + while(!in.atEnd()) report_code.append(in.readLine()).append("\n"); - QScriptValue report_result=engine.evaluate(report_code,p_report->File()); + // Close report template file + template_file.close(); - if (report_result.isError() || engine.hasUncaughtException()) { + // Execute report template script + QScriptValue report_result=engine.evaluate(report_code,report_template); + if (report_result.isError() || engine.hasUncaughtException()) { + if(!console_mode) { QMessageBox::critical(0, "Report engine error", QString::fromLatin1("%0:%1: %2") - .arg(p_report->File()) - .arg(report_result.property("lineNumber").toInt32()) + .arg(report_template) + .arg(report_result.property("lineNumber") + .toInt32()) .arg(report_result.toString())); - return QString(); + } else { + printf("ERROR: %s:%u: %s\n", + report_template.toAscii().constData(), + report_result.property("lineNumber").toInt32(), + report_result.toString().toAscii().constData()); } - - return engine.report_content; + return QString(); } - return QString(); + return engine.report_content; } diff --git a/trunk/datareporter.h b/trunk/datareporter.h index 5da277d..ae04051 100644 --- a/trunk/datareporter.h +++ b/trunk/datareporter.h @@ -1,48 +1,51 @@ /******************************************************************************* * fred Copyright (c) 2011-2012 by Gillen Daniel * * * * Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor * * with special feautures useful during forensic analysis. * * * * This program is free software: you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation, either version 3 of the License, or (at your option) * * any later version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * *******************************************************************************/ #ifndef DATAREPORTER_H #define DATAREPORTER_H #include #include "reporttemplate.h" #include "datareporterengine.h" #include "registryhive.h" class DataReporter { public: DataReporter(); ~DataReporter(); void LoadReportTemplates(QString dir); QStringList GetAvailableReportCategories(); QStringList GetAvailableReports(QString category); QString GenerateReport(RegistryHive *p_hive, QString report_category, QString report_name); + QString GenerateReport(RegistryHive *p_hive, + QString report_template, + bool console_mode=false); private: QList report_templates; //DataReporterEngine *p_report_engine; }; #endif // DATAREPORTER_H diff --git a/trunk/main.cpp b/trunk/main.cpp index 815d97b..052e5d4 100644 --- a/trunk/main.cpp +++ b/trunk/main.cpp @@ -1,105 +1,148 @@ /******************************************************************************* * fred Copyright (c) 2011-2012 by Gillen Daniel * * * * Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor * * with special feautures useful during forensic analysis. * * * * This program is free software: you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation, either version 3 of the License, or (at your option) * * any later version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * *******************************************************************************/ #include #include #include #include "mainwindow.h" #include "argparser.h" #include "compileinfo.h" +#include "datareporter.h" +#include "registryhive.h" +// Forward declarations +void PrintUsage(); +void DumpReport(QString report_template, QString hive_file); + +// Main entry point int main(int argc, char *argv[]) { // Disable output buffering setbuf(stdout,NULL); // Init QApplication QApplication a(argc, argv); #define PRINT_HEADER { \ printf("%s v%s %s\n\n",APP_NAME,APP_VERSION,APP_COPYRIGHT); \ } #define PRINT_HEADER_AND_USAGE { \ PRINT_HEADER; \ - args.PrintUsage(); \ + PrintUsage(); \ } #define PRINT_VERSION printf("%s\n",APP_VERSION); #define PRINT_UNKNOWN_ARG_ERROR(s) { \ PRINT_HEADER; \ printf("ERROR: Unknown command line argument '%s'!\n\n",s); \ - args.PrintUsage(); \ + PrintUsage(); \ } // Parse command line args ArgParser args(a.arguments()); if(!args.ParseArgs()) { PRINT_HEADER; printf("ERROR: %s\n\n",args.GetErrorMsg().toAscii().constData()); - args.PrintUsage(); + PrintUsage(); exit(1); } // Check command line args for correctness if(args.IsSet("dump-report")) { if(args.GetArgVal("dump-report")=="") { PRINT_HEADER; printf("ERROR: --dump-report specified without a report file!\n\n"); - args.PrintUsage(); + PrintUsage(); exit(1); } if(!args.IsSet("hive-file")) { PRINT_HEADER; printf("ERROR: --dump-report specified without a hive file!\n\n"); - args.PrintUsage(); + PrintUsage(); exit(1); } } // React on some command line args if(args.IsSet("?") || args.IsSet("h") || args.IsSet("help")) { PRINT_HEADER_AND_USAGE; exit(0); } if(args.IsSet("v") || args.IsSet("version")) { PRINT_VERSION; exit(0); } if(args.IsSet("dump-report")) { - printf("Dumping report '%s' using hive '%s'\n", - args.GetArgVal("dump-report").toAscii().constData(), - args.GetArgVal("hive-file").toAscii().constData()); - - // TODO: Open hive and dump report - + // Dump report to stdout + DumpReport(args.GetArgVal("dump-report"),args.GetArgVal("hive-file")); exit(0); } #undef PRINT_UNKNOWN_ARG_ERROR #undef PRINT_VERSION #undef PRINT_HEADER_AND_USAGE #undef PRINT_HEADER // Create and show main window MainWindow w(&args); w.show(); return a.exec(); } + +void PrintUsage() { + printf("Usage:\n"); + printf(" %s [opts] [hive]\n\n", + qApp->arguments().at(0).toAscii().constData()); + printf("Options:\n"); + printf(" opts:\n"); + printf(" -?, -h, --help : Display this help message.\n"); + printf(" -v, --version : Display version info.\n"); + + printf(" --dump-report=FILE : Dump the specified report to stdout.\n"); + + printf(" hive:\n"); + printf(" Use the specified hive file.\n"); + + printf("\n"); +} + +void DumpReport(QString report_template, QString hive_file) { + RegistryHive *p_hive=new RegistryHive(); + DataReporter *p_data_reporter=new DataReporter(); + + // Open hive + if(!p_hive->Open(hive_file,true)) { + printf("ERROR: Unable to open hive file '%s'!\n", + hive_file.toAscii().constData()); + exit(1); + } + + // Generate report + QString result=p_data_reporter->GenerateReport(p_hive,report_template,true); + + // Close hive and free DataReporter and RegistryHive + p_hive->Close(); + delete p_data_reporter; + delete p_hive; + + // Print result to stdout + printf("%s",result.toAscii().constData()); +}