diff --git a/trunk/datareporterengine.cpp b/trunk/datareporterengine.cpp index 465b6e4..6046fdb 100644 --- a/trunk/datareporterengine.cpp +++ b/trunk/datareporterengine.cpp @@ -1,363 +1,369 @@ /******************************************************************************* * fred Copyright (c) 2011-2012 by Gillen Daniel * * * * Forensic Registry EDitor (fred) is a cross-platform M$ registry hive editor * * with special feautures useful during forensic analysis. * * * * This program is free software: you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation, either version 3 of the License, or (at your option) * * any later version. * * * * This program is distributed in the hope that it will be useful, but WITHOUT * * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details. * * * * You should have received a copy of the GNU General Public License along with * * this program. If not, see . * *******************************************************************************/ #include "datareporterengine.h" #include #include #include #include #include #include DataReporterEngine::DataReporterEngine(RegistryHive *p_hive) : QScriptEngine() { // Init vars this->p_registry_hive=p_hive; this->report_content=""; // Add our types to engine qScriptRegisterMetaType(this, this->RegistryKeyValueToScript, this->RegistryKeyValueFromScript); this->p_type_byte_array=new ByteArray(this); this->globalObject().setProperty("ByteArray", this->p_type_byte_array->constructor()); // Add our functions // print QScriptValue func_print=this->newFunction(this->Print); this->globalObject().setProperty("print",func_print); // println QScriptValue func_println=this->newFunction(this->PrintLn); this->globalObject().setProperty("println",func_println); // GetRegistryNodes QScriptValue func_get_nodes=this->newFunction(this->GetRegistryNodes,1); func_get_nodes.setData(this->newQObject(this->p_registry_hive)); this->globalObject().setProperty("GetRegistryNodes",func_get_nodes); // GetRegistryKeys QScriptValue func_get_keys=this->newFunction(this->GetRegistryKeys,1); func_get_keys.setData(this->newQObject(this->p_registry_hive)); this->globalObject().setProperty("GetRegistryKeys",func_get_keys); // GetRegistryKeyValue QScriptValue func_get_key_value=this->newFunction(this->GetRegistryKeyValue, 2); func_get_key_value.setData(this->newQObject(this->p_registry_hive)); this->globalObject().setProperty("GetRegistryKeyValue",func_get_key_value); // GetRegistryKeyModTime QScriptValue func_get_key_modt=this->newFunction(this->GetRegistryKeyModTime, 2); func_get_key_modt.setData(this->newQObject(this->p_registry_hive)); this->globalObject().setProperty("GetRegistryKeyModTime",func_get_key_modt); // RegistryKeyValueToString QScriptValue func_value_to_string= this->newFunction(this->RegistryKeyValueToString,2); this->globalObject().setProperty("RegistryKeyValueToString", func_value_to_string); // RegistryKeyValueToVariant QScriptValue func_value_to_variant= this->newFunction(this->RegistryKeyValueToVariant); this->globalObject().setProperty("RegistryKeyValueToVariant", func_value_to_variant); // RegistryKeyTypeToString QScriptValue func_type_to_string= this->newFunction(this->RegistryKeyTypeToString,1); this->globalObject().setProperty("RegistryKeyTypeToString", func_type_to_string); } DataReporterEngine::~DataReporterEngine() { delete this->p_type_byte_array; } QScriptValue DataReporterEngine::Print(QScriptContext *context, QScriptEngine *engine) { int i; QString content; // Append all arguments to content for(i=0;iargumentCount();++i) { //if(i>0) content.append(" "); content.append(context->argument(i).toString()); } //QScriptValue calleeData=context->callee().data(); //DataReporterEngine *engine= // qobject_cast(calleeData.toQObject()); qobject_cast(engine)->report_content.append(content); return engine->undefinedValue(); } QScriptValue DataReporterEngine::PrintLn(QScriptContext *context, QScriptEngine *engine) { int i; QString content; // Append all arguments to content for(i=0;iargumentCount();++i) { //if(i>0) content.append(" "); content.append(context->argument(i).toString()); } qobject_cast(engine)-> report_content.append(content).append("\n"); return engine->undefinedValue(); } /* * GetRegistryNodes */ QScriptValue DataReporterEngine::GetRegistryNodes(QScriptContext *context, QScriptEngine *engine) { QScriptValue calleeData; RegistryHive *p_hive; QMap nodes; QScriptValue ret_nodes; int ii=0; // This function needs one argument, parent node path if(context->argumentCount()!=1) return engine->undefinedValue(); // Get calle data (Pointer to RegistryHive class) calleeData=context->callee().data(); p_hive=qobject_cast(calleeData.toQObject()); // Get nodes nodes=p_hive->GetNodes(context->argument(0).toString()); if(p_hive->Error()) { // Clear error state p_hive->GetErrorMsg(); return engine->undefinedValue(); } // Build script array ret_nodes=engine->newArray(nodes.count()); QMapIterator i(nodes); while(i.hasNext()) { i.next(); ret_nodes.setProperty(ii++,QScriptValue(i.key())); } return ret_nodes; } /* * GetRegistryKeys */ QScriptValue DataReporterEngine::GetRegistryKeys(QScriptContext *context, QScriptEngine *engine) { QScriptValue calleeData; RegistryHive *p_hive; QMap keys; QScriptValue ret_keys; int ii=0; // This function needs one argument, parent node path if(context->argumentCount()!=1) return engine->undefinedValue(); // Get calle data (Pointer to RegistryHive class) calleeData=context->callee().data(); p_hive=qobject_cast(calleeData.toQObject()); // Get keys keys=p_hive->GetKeys(context->argument(0).toString()); if(p_hive->Error()) { // Clear error state p_hive->GetErrorMsg(); return engine->undefinedValue(); } //qDebug(QString("P: %1 A: %2").arg(context->argument(0).toString()).arg(keys.count()).toAscii().constData()); // Build script array ret_keys=engine->newArray(keys.count()); QMapIterator i(keys); while(i.hasNext()) { i.next(); ret_keys.setProperty(ii++,QScriptValue(i.key())); } return ret_keys; } /* * RegistryKeyValueToScript */ QScriptValue DataReporterEngine::RegistryKeyValueToScript(QScriptEngine *engine, const s_RegistryKeyValue &s) { QScriptValue obj=engine->newObject(); obj.setProperty("type",s.type); obj.setProperty("length",s.length); ByteArray *p_byte_array=new ByteArray(engine); obj.setProperty("value",p_byte_array->newInstance(s.value)); return obj; } /* * RegistryKeyValueFromScriptValue */ void DataReporterEngine::RegistryKeyValueFromScript(const QScriptValue &obj, s_RegistryKeyValue &s) { s.type=obj.property("type").toInt32(); s.length=obj.property("length").toInt32(); // TODO: Don't know if this works, but it probably does ;) s.value=qvariant_cast(obj.property("value").data().toVariant()); } QScriptValue DataReporterEngine::GetRegistryKeyValue(QScriptContext *context, QScriptEngine *engine) { QScriptValue calleeData; RegistryHive *p_hive; QByteArray key_value; int key_type=0; size_t key_length=0; s_RegistryKeyValue script_key_value; // This function needs two arguments, key path and key name if(context->argumentCount()!=2) return engine->undefinedValue(); // Get calle data (Pointer to RegistryHive class) calleeData=context->callee().data(); p_hive=qobject_cast(calleeData.toQObject()); // Get key value key_value=p_hive->GetKeyValue(context->argument(0).toString(), context->argument(1).toString(), &key_type, &key_length); if(p_hive->Error()) { // Get error message to clear error state p_hive->GetErrorMsg(); // printf("\nError: %s\n",p_hive->GetErrorMsg().toAscii().constData()); return engine->undefinedValue(); } // Save key value to s_RegistryKeyValue struct script_key_value.type=key_type; script_key_value.length=key_length; script_key_value.value=key_value; return DataReporterEngine::RegistryKeyValueToScript(engine,script_key_value); } QScriptValue DataReporterEngine::RegistryKeyValueToString( QScriptContext *context, QScriptEngine *engine) { QByteArray key_value; QString ret=""; // This function needs two arguments, key value and value type if(context->argumentCount()!=2) return engine->undefinedValue(); // Cast ByteArray argument to QByteArray and convert key_value=qvariant_cast(context->argument(0).data().toVariant()); ret=RegistryHive::KeyValueToString(key_value, context->argument(1).toInt32()); return engine->newVariant(ret); } QScriptValue DataReporterEngine::RegistryKeyValueToVariant( QScriptContext *context, QScriptEngine *engine) { int offset=0; int length=-1; + bool little_endian=true; QByteArray key_value; QString format=""; QString ret=""; // This function needs at least two arguments, key value and variant type, - // and may have two optional arguments, offset and length - if(context->argumentCount()<2 || context->argumentCount()>4) { + // and may have three optional arguments, offset, length and little_endian + if(context->argumentCount()<2 || context->argumentCount()>5) { return engine->undefinedValue(); } if(context->argumentCount()==3) { offset=context->argument(2).toInt32(); } if(context->argumentCount()==4) { offset=context->argument(2).toInt32(); length=context->argument(3).toInt32(); } + if(context->argumentCount()==5) { + offset=context->argument(2).toInt32(); + length=context->argument(3).toInt32(); + little_endian=(context->argument(4).toInt32()==1); + } // Cast ByteArray argument to QByteArray key_value=qvariant_cast(context->argument(0).data().toVariant()); format=context->argument(1).toString(); - ret=RegistryHive::KeyValueToString(key_value,format,offset,length); + ret=RegistryHive::KeyValueToString(key_value,format,offset,length,little_endian); return engine->newVariant(ret); } QScriptValue DataReporterEngine::RegistryKeyTypeToString( QScriptContext *context, QScriptEngine *engine) { QString ret=""; - // This function needs one arguments, key type + // This function needs one argument, key type if(context->argumentCount()!=1) return engine->undefinedValue(); ret=RegistryHive::KeyTypeToString(context->argument(0).toInt32()); return engine->newVariant(ret); } QScriptValue DataReporterEngine::GetRegistryKeyModTime( QScriptContext *context, QScriptEngine *engine) { QScriptValue calleeData; RegistryHive *p_hive; int64_t mod_time=0; // This function needs two argument, key path and key name if(context->argumentCount()!=2) return engine->undefinedValue(); // Get calle data (Pointer to RegistryHive class) calleeData=context->callee().data(); p_hive=qobject_cast(calleeData.toQObject()); mod_time=p_hive->GetKeyModTime(context->argument(0).toString(), context->argument(1).toString()); if(p_hive->Error()) { // Get error message to clear error state p_hive->GetErrorMsg(); return engine->undefinedValue(); } QDateTime date_time; date_time.setTimeSpec(Qt::UTC); date_time.setTime_t(RegistryHive::FiletimeToUnixtime(mod_time)); return engine->newVariant(date_time.toString("yyyy/MM/dd hh:mm:ss")); } diff --git a/trunk/report_templates/NTUSER_LaunchedApplications.qs b/trunk/report_templates/NTUSER_LaunchedApplications.qs new file mode 100644 index 0000000..92a51a3 --- /dev/null +++ b/trunk/report_templates/NTUSER_LaunchedApplications.qs @@ -0,0 +1,101 @@ +function IsValid(val) { + if(typeof val !== 'undefined') return true; + else return false; +} + +function PrintTableRow(cell01,cell02,cell03) { + println(" ",cell01,"",cell02,"",cell03,""); +} + +function Rot13Decode(val) { + var ret=""; + + for(var i=0;i64 && decoded<91) || (decoded>96 && decoded<123)) { + if((decoded-13)<65 || (decoded>96 && (decoded-13)<97)) { + decoded=(decoded-13)+26; + } else { + if(decoded>96 && (decoded-13)<97) { + decoded+=13; + } else { + decoded-=13; + } + } + ret+=String.fromCharCode(decoded); + } else { + ret+=val[i]; + } + } + + return ret; +} + +function PrintUserAssistEntry(key,val,os) { + var run_count; + var last_run; + + switch(os) { + case "winxp": + run_count=RegistryKeyValueToVariant(val.value,"uint32",4); + + break; + case "win7": + run_count=RegistryKeyValueToVariant(val.value,"uint32",4,0,1); + last_run=RegistryKeyValueToVariant(val.value,"filetime",60); + break; + } + + PrintTableRow(key,run_count,last_run); +} + +println(""); +println(" Launched Applications"); +println(" "); +println("

Launched applications

"); + +// First, we need to find the correct GUID for the current Windows version +var path; +var apps; +var os; + +// Windows XP +os="winxp"; +path="\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{5E6AB780-7743-11CF-A12B-00AA004AE837}\\Count"; +apps=GetRegistryKeys(path); + +// TODO: Determine GUIDs for Vista / Win8 + +if(!IsValid(apps)) { + // Windows 7 + os="win7"; + path="\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist\\{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}\\Count"; + apps=GetRegistryKeys(path); +} + + + + +if(IsValid(apps)) { + if(apps.length!=0) { + println("

"); + println(" "); + println(" "); + + for(var i=0;i"); + println("

"); + } else { + println("

"); + println(" The list of launched applications is empty."); + println("

"); + } +} else { + println("

"); + println(" This registry hive does not contain a list of launched applications!"); + println("

"); +} diff --git a/trunk/report_templates/NTUSER_RecentDocs.qs b/trunk/report_templates/NTUSER_RecentDocs.qs index c4359a5..112669d 100644 --- a/trunk/report_templates/NTUSER_RecentDocs.qs +++ b/trunk/report_templates/NTUSER_RecentDocs.qs @@ -1,36 +1,41 @@ function IsValid(val) { if(typeof val !== 'undefined') return true; else return false; } println(""); println(" Recent Documents"); println(" "); println("

Recent documents

"); // Get list of recent docs var recent_docs=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs","MRUListEx"); if(IsValid(recent_docs)) { - println("

"); - println("

ApplicationRun countLast run
"); - println(" "); - // Iterate over all recent docs var i=0; var runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i); - while(Number(runlist)!=0xffffffff) { - var entry=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs",runlist.toString(10)); - println(" "); - i+=4; - runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i); - } + if(Number(runlist)!=0xffffffff) { + println("

"); + println("

Document
",RegistryKeyValueToVariant(entry.value,"utf16",0),"
"); - println("
"); - println("

"); + while(Number(runlist)!=0xffffffff) { + var entry=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RecentDocs",runlist.toString(10)); + println(" ",RegistryKeyValueToVariant(entry.value,"utf16",0),""); + i+=4; + runlist=RegistryKeyValueToVariant(recent_docs.value,"uint32",i); + } + + println(" "); + println("

"); + } else { + println("

"); + println(" The list of recent documents is empty."); + println("

"); + } } else { println("

"); println(" This registry hive does not contain a list of recent documents!"); println("

"); } println(""); diff --git a/trunk/report_templates/NTUSER_TypedUrls.qs b/trunk/report_templates/NTUSER_TypedUrls.qs index a94144d..b581da7 100644 --- a/trunk/report_templates/NTUSER_TypedUrls.qs +++ b/trunk/report_templates/NTUSER_TypedUrls.qs @@ -1,31 +1,36 @@ function IsValid(val) { if(typeof val !== 'undefined') return true; else return false; } println(""); println(" Typed Urls"); println(" "); println("

Typed urls

"); // Iterate over all typed urls var typed_urls=GetRegistryKeys("\\Software\\Microsoft\\Internet Explorer\\TypedURLs"); if(IsValid(typed_urls)) { - println("

"); - println(" "); - println(" "); + if(typed_urls.length!=0) { + println("

"); + println("

Url
"); - for(var i=0;i"); - } + for(var i=0;i"); + } - println("
",RegistryKeyValueToString(val.value,val.type),"
",RegistryKeyValueToString(val.value,val.type),"
"); - println("

"); + println(" "); + println("

"); + } else { + println("

"); + println(" The list of typed urls is empty."); + println("

"); + } } else { println("

"); println(" This registry hive does not contain a list of typed urls!"); println("

"); } println(""); diff --git a/trunk/report_templates/NTUSER_Windows7_SearchKeywords.qs b/trunk/report_templates/NTUSER_Windows7_SearchKeywords.qs new file mode 100644 index 0000000..effaa23 --- /dev/null +++ b/trunk/report_templates/NTUSER_Windows7_SearchKeywords.qs @@ -0,0 +1,41 @@ +function IsValid(val) { + if(typeof val !== 'undefined') return true; + else return false; +} + +println(""); +println(" Document And Folder Search Keywords"); +println(" "); +println("

Document and folder search keywords

"); + +// Get list of search keys +var mrulist=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\WordWheelQuery","MRUListEx"); +if(IsValid(mrulist)) { + // Iterate over all items + var i=0; + var runlist=RegistryKeyValueToVariant(mrulist.value,"uint32",i); + if(Number(runlist)!=0xffffffff) { + println("

"); + println(" "); + + while(Number(runlist)!=0xffffffff) { + var entry=GetRegistryKeyValue("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\WordWheelQuery",runlist.toString(10)); + println(" "); + i+=4; + runlist=RegistryKeyValueToVariant(mrulist.value,"uint32",i); + } + + println("
",RegistryKeyValueToVariant(entry.value,"utf16",0),"
"); + println("

"); + } else { + println("

"); + println(" The list of document and search keywords is empty."); + println("

"); + } +} else { + println("

"); + println(" This registry hive does not contain a list of document and folder search keywords!"); + println("

"); +} + +println(""); diff --git a/trunk/report_templates/NTUSER_Windows7_TypedPaths.qs b/trunk/report_templates/NTUSER_Windows7_TypedPaths.qs new file mode 100644 index 0000000..4411897 --- /dev/null +++ b/trunk/report_templates/NTUSER_Windows7_TypedPaths.qs @@ -0,0 +1,36 @@ +function IsValid(val) { + if(typeof val !== 'undefined') return true; + else return false; +} + +println(""); +println(" Typed Paths"); +println(" "); +println("

Typed paths

"); + +// Iterate over all typed paths +var urls=GetRegistryKeys("\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\TypedPaths"); +if(IsValid(urls)) { + if(urls.length!=0) { + println("

"); + println(" "); + + for(var i=0;i"); + } + + println("
",RegistryKeyValueToString(val.value,val.type),"
"); + println("

"); + } else { + println("

"); + println(" The list of typed paths is empty."); + println("

"); + } +} else { + println("

"); + println(" This registry hive does not contain a list of typed paths!"); + println("

"); +} + +println("");