Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7687821
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
18 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/trunk/datareporterengine.cpp b/trunk/datareporterengine.cpp
index 15697fe..a2932ab 100644
--- a/trunk/datareporterengine.cpp
+++ b/trunk/datareporterengine.cpp
@@ -1,361 +1,363 @@
/*******************************************************************************
* fred Copyright (c) 2011-2012 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 "datareporterengine.h"
#include <QString>
#include <QMap>
#include <QMapIterator>
#include <QStringList>
#include <QDateTime>
#include <stdio.h>
DataReporterEngine::DataReporterEngine(RegistryHive *p_hive) : QScriptEngine() {
// Init vars
this->p_registry_hive=p_hive;
this->report_content="";
// Add our types to engine
qScriptRegisterMetaType<s_RegistryKeyValue>(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;i<context->argumentCount();++i) {
//if(i>0) content.append(" ");
content.append(context->argument(i).toString());
}
//QScriptValue calleeData=context->callee().data();
//DataReporterEngine *engine=
// qobject_cast<DataReporterEngine*>(calleeData.toQObject());
qobject_cast<DataReporterEngine*>(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;i<context->argumentCount();++i) {
//if(i>0) content.append(" ");
content.append(context->argument(i).toString());
}
qobject_cast<DataReporterEngine*>(engine)->
report_content.append(content).append("\n");
return engine->undefinedValue();
}
/*
* GetRegistryNodes
*/
QScriptValue DataReporterEngine::GetRegistryNodes(QScriptContext *context,
QScriptEngine *engine)
{
QScriptValue calleeData;
RegistryHive *p_hive;
QMap<QString,int> 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<RegistryHive*>(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<QString,int> 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<QString,int> 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<RegistryHive*>(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<QString,int> 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<QByteArray>(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<RegistryHive*>(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<QByteArray>(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;
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) {
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();
}
// Cast ByteArray argument to QByteArray
key_value=qvariant_cast<QByteArray>(context->argument(0).data().toVariant());
format=context->argument(1).toString();
ret=RegistryHive::KeyValueToString(key_value,format,offset,length);
return engine->newVariant(ret);
}
QScriptValue DataReporterEngine::RegistryKeyTypeToString(
QScriptContext *context,
QScriptEngine *engine)
{
QString ret="";
// This function needs one arguments, 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<RegistryHive*>(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/dlgreportviewer.ui b/trunk/dlgreportviewer.ui
index 831704e..8e90a91 100644
--- a/trunk/dlgreportviewer.ui
+++ b/trunk/dlgreportviewer.ui
@@ -1,82 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DlgReportViewer</class>
<widget class="QMainWindow" name="DlgReportViewer">
<property name="windowModality">
- <enum>Qt::WindowModal</enum>
+ <enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>605</width>
<height>497</height>
</rect>
</property>
<property name="windowTitle">
<string/>
</property>
<property name="windowIcon">
<iconset resource="fred.qrc">
<normaloff>:/icons/resources/fred.png</normaloff>:/icons/resources/fred.png</iconset>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWebView" name="WebView">
<property name="url">
<url>
<string>about:blank</string>
</url>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>605</width>
- <height>25</height>
+ <height>27</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&File</string>
</property>
<addaction name="action_Print"/>
<addaction name="separator"/>
<addaction name="action_Close"/>
</widget>
<addaction name="menu_File"/>
</widget>
<action name="action_Save">
<property name="text">
<string>&Save</string>
</property>
</action>
<action name="action_Print">
<property name="text">
<string>&Print</string>
</property>
</action>
<action name="action_Close">
<property name="text">
<string>&Close</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>QWebView</class>
<extends>QWidget</extends>
<header>QtWebKit/QWebView</header>
</customwidget>
</customwidgets>
<resources>
<include location="fred.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/trunk/report_templates/SYSTEM_Services.qs b/trunk/report_templates/SYSTEM_Services.qs
new file mode 100644
index 0000000..a3cbc25
--- /dev/null
+++ b/trunk/report_templates/SYSTEM_Services.qs
@@ -0,0 +1,94 @@
+function IsValid(val) {
+ if(typeof val !== 'undefined') return true;
+ else return false;
+}
+
+function ZeroPad(number,padlen) {
+ var ret=number.toString(10);
+ if(!padlen || ret.length>=padlen) return ret;
+ return Math.pow(10,padlen-ret.length).toString().slice(1)+ret;
+}
+
+function PrintTableRow(cell01,cell02,cell03) {
+ println(" <tr><td style=\"padding:2px\">",cell01,"</td><td style=\"padding:2px\">",cell02,"</td><td style=\"padding:2px\">",cell03,"</td></tr>");
+}
+
+function ListService(service_node) {
+ // Service name
+ var name=GetRegistryKeyValue(service_node,"DisplayName");
+ name=(IsValid(name)) ? RegistryKeyValueToString(name.value,name.type) : "Unknwon";
+ // Service exe
+ var image=GetRegistryKeyValue(service_node,"ImagePath");
+ image=(IsValid(image)) ? RegistryKeyValueToString(image.value,image.type) : "Unknwon";
+ // Start
+ var start=GetRegistryKeyValue(service_node,"Start");
+ start=(IsValid(start)) ? RegistryKeyValueToString(start.value,start.type) : -1;
+ switch(Number(start)) {
+ case 0:
+ start="Boot";
+ break;
+ case 1:
+ start="System";
+ break;
+ case 2:
+ start="Automatic";
+ break;
+ case 3:
+ start="Manual";
+ break;
+ case 4:
+ start="Disabled";
+ break;
+ default:
+ start="Unknown";
+ }
+ // Description??
+
+ PrintTableRow(name,start,image)
+}
+
+// Global vars
+var val;
+
+println("<html>");
+println(" <head><title>Services</title></head>");
+println(" <body style=\"font-size:12\">");
+println(" <h2>Services</h2>");
+
+// Get current controlset
+var cur_controlset=GetRegistryKeyValue("\\Select","Current");
+if(IsValid(cur_controlset)) {
+ cur_controlset=RegistryKeyValueToString(cur_controlset.value,cur_controlset.type);
+ // Current holds a DWORD value, thus we get a string like 0x00000000, but
+ // control sets are referenced by its decimal representation.
+ cur_controlset="ControlSet"+ZeroPad(parseInt(String(cur_controlset).substr(2,8),16),3)
+
+ // Get list of possible services
+ var services=GetRegistryNodes(cur_controlset+"\\Services");
+ if(IsValid(services)) {
+ println(" <p style=\"font-size:12; white-space:nowrap\">");
+ println(" <table style=\"margin-left:20px; font-size:12; white-space:nowrap\">");
+ println(" <tr><td style=\"padding:2px\"><b>Name</b></td style=\"padding:2px\"><td><b>Startup</b></td><td style=\"padding:2px\"><b>Image path</b></td></tr>");
+ for(var i=0;i<services.length;i++) {
+ // Get service type
+ val=GetRegistryKeyValue(cur_controlset+"\\Services\\"+services[i],"Type");
+ if(!IsValid(val)) continue;
+ val=RegistryKeyValueToString(val.value,val.type);
+ if(Number(val)!=16 && Number(val)!=32) continue;
+ ListService(cur_controlset+"\\Services\\"+services[i]);
+ }
+ println(" </table>");
+ println(" </p>");
+ } else {
+ println(" <p><font color='red'>");
+ println(" This registry hive does not contain any services!<br />");
+ println(" </font></p>");
+ }
+} else {
+ println(" <p><font color='red'>");
+ println(" Unable to determine current control set!<br />");
+ println(" Are you sure you are running this report against the correct registry hive?");
+ println(" </font></p>");
+}
+
+println("</html>");
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Oct 30, 1:14 AM (9 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1346145
Default Alt Text
(18 KB)
Attached To
Mode
rFRED fred
Attached
Detach File
Event Timeline
Log In to Comment