From 1ae43783aa687afdecfd7e99bf6407fdf14b1c0b Mon Sep 17 00:00:00 2001 From: Dave Lassalle Date: Wed, 21 Mar 2018 10:50:44 -0500 Subject: [PATCH] create utility function for converting windows timestamps --- volatility/framework/interfaces/renderers.py | 2 +- volatility/framework/objects/utility.py | 11 ++++++++++- .../symbols/windows/extensions/__init__.py | 13 +++---------- volatility/plugins/windows/printkey.py | 10 +++++----- volatility/plugins/windows/pslist.py | 6 ++++-- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/volatility/framework/interfaces/renderers.py b/volatility/framework/interfaces/renderers.py index dcce61fda..b1486abf3 100644 --- a/volatility/framework/interfaces/renderers.py +++ b/volatility/framework/interfaces/renderers.py @@ -114,7 +114,7 @@ class TreeGrid(object, metaclass = ABCMeta): and to create cycles. """ - simple_types = (int, str, float, bytes, datetime) # type: typing.ClassVar[typing.Tuple] + simple_types = (int, str, float, bytes, datetime.datetime) # type: typing.ClassVar[typing.Tuple] def __init__(self, columns: ColumnsType, generator: typing.Generator) -> None: """Constructs a TreeGrid object using a specific set of columns diff --git a/volatility/framework/objects/utility.py b/volatility/framework/objects/utility.py index 5c20b4e93..56354f397 100644 --- a/volatility/framework/objects/utility.py +++ b/volatility/framework/objects/utility.py @@ -1,6 +1,7 @@ import typing +import datetime -from volatility.framework import objects, interfaces +from volatility.framework import interfaces, objects, renderers from volatility.framework.objects import templates @@ -39,3 +40,11 @@ def array_of_pointers(array: objects.Array, raise TypeError("Subtype must be a valid object template") subtype_pointer = objects.templates.ObjectTemplate(objects.Pointer, type_name = 'pointer', subtype = subtype) return array.cast("array", count = count, subtype = subtype_pointer) + + +def wintime_to_datetime(wintime: objects.Struct) -> datetime.datetime: + unix_time = wintime.QuadPart // 10000000 + if unix_time == 0: + return renderers.NotApplicableValue() + unix_time = unix_time - 11644473600 + return datetime.datetime.utcfromtimestamp(unix_time) diff --git a/volatility/framework/symbols/windows/extensions/__init__.py b/volatility/framework/symbols/windows/extensions/__init__.py index 774611587..4e3965db8 100644 --- a/volatility/framework/symbols/windows/extensions/__init__.py +++ b/volatility/framework/symbols/windows/extensions/__init__.py @@ -5,6 +5,7 @@ import logging import typing from volatility.framework import constants, exceptions, interfaces, objects, renderers +from volatility.framework.objects import utility from volatility.framework.symbols import generic vollog = logging.getLogger(__name__) @@ -452,18 +453,10 @@ class _EPROCESS(generic.GenericIntelProcess): return renderers.UnreadableValue() def get_create_time(self): - unix_time = self.CreateTime.QuadPart // 10000000 - if unix_time == 0: - return renderers.NotApplicableValue() - unix_time = unix_time - 11644473600 - return str(datetime.datetime.utcfromtimestamp(unix_time)) + return utility.wintime_to_datetime(self.CreateTime) def get_exit_time(self): - unix_time = self.ExitTime.QuadPart // 10000000 - if unix_time == 0: - return renderers.NotApplicableValue() - unix_time = unix_time - 11644473600 - return str(datetime.datetime.utcfromtimestamp(unix_time)) + return utility.wintime_to_datetime(self.ExitTime) def get_wow_64_process(self): if hasattr(self, "Wow64Process"): diff --git a/volatility/plugins/windows/printkey.py b/volatility/plugins/windows/printkey.py index 9971a86e2..1ae675e64 100644 --- a/volatility/plugins/windows/printkey.py +++ b/volatility/plugins/windows/printkey.py @@ -6,6 +6,7 @@ import volatility.framework.interfaces.plugins as plugins from volatility.framework import objects, renderers from volatility.framework.configuration import requirements from volatility.framework.layers.registry import RegistryHive +from volatility.framework.objects import utility from volatility.framework.renderers import TreeGrid from volatility.framework.symbols.windows.extensions.registry import RegValueTypes @@ -51,12 +52,11 @@ class PrintKey(plugins.PluginInterface): node = node_path[-1] if key_path is None: key_path = node.get_key_path() - unix_time = node.LastWriteTime.QuadPart // 10000000 - unix_time = unix_time - 11644473600 + last_write_time = utility.wintime_to_datetime(node.LastWriteTime) for key_node in node.get_subkeys(): result = (key_path.count("\\"), - (str(datetime.datetime.utcfromtimestamp(unix_time)), + (last_write_time, renderers.format_hints.Hex(hive.hive_offset), "Key", key_path, @@ -67,7 +67,7 @@ class PrintKey(plugins.PluginInterface): for value_node in node.get_values(): result = (key_path.count("\\"), - (str(datetime.datetime.utcfromtimestamp(unix_time)), + (last_write_time, renderers.format_hints.Hex(hive.hive_offset), RegValueTypes(value_node.Type).name, key_path, @@ -113,7 +113,7 @@ class PrintKey(plugins.PluginInterface): def run(self): - return TreeGrid(columns = [('Last Write Time', str), + return TreeGrid(columns = [('Last Write Time', datetime.datetime), ('Hive Offset', renderers.format_hints.Hex), ('Type', str), ('Key', str), diff --git a/volatility/plugins/windows/pslist.py b/volatility/plugins/windows/pslist.py index f3e258482..209b6d469 100644 --- a/volatility/plugins/windows/pslist.py +++ b/volatility/plugins/windows/pslist.py @@ -1,3 +1,5 @@ +import datetime + import volatility.framework.interfaces.plugins as plugins from volatility.framework import renderers from volatility.framework.configuration import requirements @@ -95,6 +97,6 @@ class PsList(plugins.PluginInterface): ("Handles", int), ("SessionId", int), ("Wow64", bool), - ("CreateTime", str), - ("ExitTime", str)], + ("CreateTime", datetime.datetime), + ("ExitTime", datetime.datetime)], self._generator())