Index: plaso/parsers/amcache.py |
diff --git a/plaso/parsers/amcache.py b/plaso/parsers/amcache.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4771143dfbd9f4cd7907240a6d75134ef6d02fbb |
--- /dev/null |
+++ b/plaso/parsers/amcache.py |
@@ -0,0 +1,103 @@ |
+# -*- coding: utf-8 -*- |
+"""File containing a Windows Registry plugin to parse the Amcache Hive.""" |
+ |
onager
2017/08/09 10:38:17
add "from __future__ import unicode_literals" and
rbdebeer
2017/08/22 11:25:59
Done.
|
+import pyregf |
+ |
+from dfdatetime import filetime |
+from plaso.containers import events |
+from plaso.containers import time_events |
+from plaso.lib import definitions |
+from plaso.parsers import interface |
+from plaso.parsers import manager |
+ |
+__author__ = 'Ramses de Beer, rbdebeer@google.com' |
+ |
+class AmcacheEventData(events.EventData): |
+ """Amcache event data. |
onager
2017/08/09 10:38:17
+blank line
rbdebeer
2017/08/22 11:26:00
Done.
|
+ Attributes: |
+ amcachedatetime (str): last modified time of amcache file referenced |
onager
2017/08/09 10:38:17
This doesn't need to be in the eventdata, it's in
rbdebeer
2017/08/22 11:25:59
Done.
|
+ full_path (str): full path of file |
+ sha1 (str): sha1 of file |
onager
2017/08/09 10:38:17
Why not extract all the data from the key? Product
rbdebeer
2017/08/22 11:25:59
The 3 values extracted are always there, the other
|
+ """ |
+ |
+ DATA_TYPE = u'windows:registry:amcache' |
+ |
+ def __init__(self): |
+ """Initializes event data.""" |
+ super(AmcacheEventData, self).__init__(data_type=self.DATA_TYPE) |
+ self.datetime = None |
+ self.full_path = None |
+ self.sha1 = None |
+ |
+class AmcacheParser(interface.FileObjectParser): |
+ """Amcache Registry plugin for recently run programs.""" |
+ |
+ NAME = u'amcache' |
+ DESCRIPTION = u'Parser for Amcache Registry entries.' |
+ |
+ URLS = [ |
+ (u'http://www.swiftforensics.com/2013/12/' |
+ 'amcachehve-in-windows-8-goldmine-for.html')] |
+ |
+ _SOURCE_APPEND = u': Amcache Entries' |
onager
2017/08/09 10:38:17
Remove this - source_append is going away, and thi
rbdebeer
2017/08/22 11:26:00
Done.
|
+ |
+ _AMCACHE_ENTRY_SHA1 = "101" |
+ _AMCACHE_ENTRY_DATETIME = "17" |
+ _AMCACHE_ENTRY_FULL_PATH = "15" |
+ _AMCACHE_ROOT_KEY = "Root\\File" |
onager
2017/08/09 10:38:17
What about Root\\Programs? It also looks like it m
rbdebeer
2017/08/22 11:26:00
It maps to the control panel -> installed programs
|
+ |
+ |
+ #TODO Add GetFormatSpecification when issues are fixed with adding |
onager
2017/08/09 10:38:17
Please open a github issue for this, and reference
|
+ # multiple parsers for the same file format (in this case regf files) |
+ # AddNewSignature -> |
+ # b'\x41\x00\x6d\x00\x63\x00\x61\x00\x63\x00\x68\x00\x65', offset=88 |
+ |
+ def ParseFileObject(self, parser_mediator, file_object, **kwargs): |
+ """Parses an Amcache.hve file for events. |
+ |
+ Args: |
+ parser_mediator (ParserMediator): mediates interactions between parsers |
+ and other components, such as storage and dfvfs. |
+ file_object (dfvfs.FileIO): file-like object. |
+ """ |
+ regf_file = pyregf.file() # pylint: disable=no-member |
+ try: |
+ regf_file.open_file_object(file_object) |
+ except IOError as exception: #pylint: disable=unused-variable |
onager
2017/08/09 10:38:17
you can just "except IOError" here, and avoid the
rbdebeer
2017/08/22 11:26:00
Done.
rbdebeer
2017/08/22 11:26:00
Done.
|
+ return |
+ |
+ root_key = regf_file.get_root_key() |
+ if root_key is None: |
+ return |
+ |
+ root_file_key = root_key.get_sub_key_by_path(self._AMCACHE_ROOT_KEY) |
+ if root_file_key is None: |
+ return |
+ |
+ volume_keys = root_file_key.get_number_of_sub_keys() |
+ |
+ for volume in range(volume_keys): |
+ volume_key = root_file_key.get_sub_key(volume) |
+ amcache_keys = volume_key.get_number_of_sub_keys() |
+ |
+ for amcache_key in range(amcache_keys): |
onager
2017/08/09 10:38:17
This seems a little wierd - why not "for amcache_k
rbdebeer
2017/08/22 11:26:00
Done.
|
+ amcache_key_entry = volume_key.get_sub_key(amcache_key) |
+ amcache_datetime = amcache_key_entry.get_value_by_name( |
+ self._AMCACHE_ENTRY_DATETIME).get_data_as_integer() |
+ amcache_sha1 = amcache_key_entry.get_value_by_name( |
+ self._AMCACHE_ENTRY_SHA1).get_data_as_string() |
+ amcache_fullpath = amcache_key_entry.get_value_by_name( |
+ self._AMCACHE_ENTRY_FULL_PATH).get_data_as_string() |
+ event_data = AmcacheEventData() |
+ event_data.datetime = amcache_datetime |
+ event_data.full_path = amcache_fullpath |
+ event_data.sha1 = amcache_sha1 |
+ |
+ event = time_events.DateTimeValuesEvent( |
+ filetime.Filetime(amcache_datetime), |
+ definitions.TIME_DESCRIPTION_LAST_RUN) |
+ parser_mediator.ProduceEventWithEventData(event, event_data) |
+ |
+ regf_file.close() |
+ |
+manager.ParsersManager.RegisterParser(AmcacheParser) |