Source code for plaso.parsers.amcache

# -*- coding: utf-8 -*-
"""File containing a Windows Registry plugin to parse the Amcache Hive."""

from __future__ import unicode_literals

import pyregf

from dfdatetime import filetime
from dfdatetime import posix_time
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


[docs]class AmcacheEventData(events.EventData): """Amcache event data. Attributes: full_path (str): full path of file sha1 (str): sha1 of file productname (str): product name file belongs to companyname (str): company name that created product file belongs to fileversion (str): version of file languagecode (int): language code of file filesize (int): size of file in bytes filedescription (str): description of file linkerts (int): unix timestamp when file was linked lastmodifiedts (int): filetime timestamp of last modified datetime of file createdtd (int): filetime timestamp of created datetime of file programid (str): GUID of entry under Root/Program key file belongs to """ DATA_TYPE = 'windows:registry:amcache' def __init__(self): """Initializes event data.""" super(AmcacheEventData, self).__init__(data_type=self.DATA_TYPE) self.full_path = None self.sha1 = None self.productname = None self.companyname = None self.fileversion = None self.languagecode = None self.filesize = None self.filedescription = None self.linkerts = None self.lastmodifiedts = None self.createdts = None
self.programid = None
[docs]class AmcacheProgramEventData(events.EventData): """Amcache programs event data. Attributes: name (str): name of installed program version (str): version of program publisher (str): publisher of program languagecode (int): languagecode of program entrytype (str): type of entry (usually AddRemoveProgram) uninstallkey (str): unicode string of uninstall registry key for program filepath (str): file path of installed program productcode (str): product code of program packagecode (str): package code of program msiproductcode (str): MSI product code of program msipackagecode (str): MSI package code of program files (str): list of files belonging to program """ DATA_TYPE = 'windows:registry:amcache:programs' def __init__(self): """Initializes event data.""" super(AmcacheProgramEventData, self).__init__(data_type=self.DATA_TYPE) self.name = None self.version = None self.publisher = None self.languagecode = None self.entrytype = None self.uninstallkey = None self.filepaths = None self.productcode = None self.packagecode = None self.msiproductcode = None self.msipackagecode = None
self.files = None
[docs]class AmcacheParser(interface.FileObjectParser): """Amcache Registry plugin for recently run programs.""" NAME = 'amcache' DESCRIPTION = 'Parser for Amcache Registry entries.' URLS = [ ('http://www.swiftforensics.com/2013/12/' 'amcachehve-in-windows-8-goldmine-for.html')] _AMCACHE_SHA1 = "101" _AMCACHE_DATETIME = "17" _AMCACHE_FULL_PATH = "15" _AMCACHE_ROOT_FILE_KEY = "Root\\File" _AMCACHE_ROOT_PROGRAM_KEY = "Root\\Programs" _AMCACHE_PRODUCTNAME = "0" _AMCACHE_COMPANYNAME = "1" _AMCACHE_FILEVERSION = "5" _AMCACHE_LANGUAGECODE = "3" _AMCACHE_FILESIZE = "6" _AMCACHE_FILEDESCRIPTION = "c" _AMCACHE_LINKERTS = "f" _AMCACHE_LASTMODIFIEDTS = "11" _AMCACHE_CREATEDTS = "12" _AMCACHE_PROGRAMID = "100" _AMCACHE_P_INSTALLDATE = "a" _AMCACHE_P_NAME = "0" _AMCACHE_P_VERSION = "1" _AMCACHE_P_PUBLISHER = "2" _AMCACHE_P_LANGUAGECODE = "3" _AMCACHE_P_ENTRYTYPE = "6" _AMCACHE_P_UNINSTALLKEY = "7" _AMCACHE_P_FILEPATHS = "d" _AMCACHE_P_PRODUCTCODE = "f" _AMCACHE_P_PACKAGECODE = "10" _AMCACHE_P_MSIPRODUCTCODE = "11" _AMCACHE_P_MSIPACKAGECODE = "12" _AMCACHE_P_FILES = "Files" #TODO Add GetFormatSpecification when issues are fixed with adding # 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
[docs] def ParseFileObject(self, parser_mediator, file_object): """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: # The error is currently ignored -> see TODO above related to the # fixing of handling multiple parsers for the same file format. return root_key = regf_file.get_root_key() if root_key is None: regf_file.close() return root_file_key = root_key.get_sub_key_by_path(self._AMCACHE_ROOT_FILE_KEY) if root_file_key is None: regf_file.close() return for volume_key in root_file_key.sub_keys: for am_entry in volume_key.sub_keys: self._ProcessAMCacheFileKey(am_entry, parser_mediator) root_program_key = root_key.get_sub_key_by_path( self._AMCACHE_ROOT_PROGRAM_KEY) if root_program_key is None: regf_file.close() return for am_entry in root_program_key.sub_keys: self._ProcessAMCacheProgramKey(am_entry, parser_mediator)
regf_file.close() def _ProcessAMCacheProgramKey(self, am_entry, parser_mediator): """Parses an Amcache Root/Programs key for events. Args: am_entry (pyregf.key): amcache Programs key. parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. """ amcache_datetime = am_entry.get_value_by_name( self._AMCACHE_P_INSTALLDATE).get_data_as_integer() event_data = AmcacheProgramEventData() name = am_entry.get_value_by_name(self._AMCACHE_P_NAME) if name: event_data.name = name.get_data_as_string() version = am_entry.get_value_by_name(self._AMCACHE_P_VERSION) if version: event_data.version = version.get_data_as_string() publisher = am_entry.get_value_by_name(self._AMCACHE_P_PUBLISHER) if publisher: event_data.publisher = publisher.get_data_as_string() languagecode = am_entry.get_value_by_name(self._AMCACHE_P_LANGUAGECODE) if languagecode: event_data.languagecode = languagecode.get_data_as_string() entrytype = am_entry.get_value_by_name(self._AMCACHE_P_ENTRYTYPE) if entrytype: event_data.entrytype = entrytype.get_data_as_string() uninstallkey = am_entry.get_value_by_name(self._AMCACHE_P_UNINSTALLKEY) if uninstallkey: uninstallkey = uninstallkey.get_data() uninstallkey = uninstallkey.decode('utf-16-LE') event_data.uninstallkey = uninstallkey filepaths = am_entry.get_value_by_name(self._AMCACHE_P_FILEPATHS) if filepaths: filepaths = filepaths.get_data() filepaths = filepaths.decode('utf-16-LE') event_data.filepaths = filepaths productcode = am_entry.get_value_by_name(self._AMCACHE_P_PRODUCTCODE) if productcode: event_data.productcode = productcode.get_data_as_string() packagecode = am_entry.get_value_by_name(self._AMCACHE_P_PACKAGECODE) if packagecode: event_data.packagecode = packagecode.get_data_as_string() msiproductcode = am_entry.get_value_by_name(self._AMCACHE_P_MSIPRODUCTCODE) if msiproductcode: msiproductcode = msiproductcode.get_data() msiproductcode = msiproductcode.decode('utf-16-LE') event_data.msiproductcode = msiproductcode msipackagecode = am_entry.get_value_by_name(self._AMCACHE_P_MSIPACKAGECODE) if msipackagecode: msipackagecode = msipackagecode.get_data() msipackagecode = msipackagecode.decode('utf-16-LE') event_data.msipackagecode = msipackagecode files = am_entry.get_value_by_name(self._AMCACHE_P_FILES) if files: files = files.get_data() files = files.decode('utf-16-LE') event_data.files = files event = time_events.DateTimeValuesEvent( posix_time.PosixTime(amcache_datetime), definitions.TIME_DESCRIPTION_INSTALLATION) parser_mediator.ProduceEventWithEventData(event, event_data) def _ProcessAMCacheFileKey(self, am_entry, parser_mediator): """"Parses an Amcache Root/File key for events. Args: am_entry (pyregf.key): amcache File key. parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfvfs. """ amcache_datetime = am_entry.get_value_by_name( self._AMCACHE_DATETIME).get_data_as_integer() event_data = AmcacheEventData() event_data.full_path = am_entry.get_value_by_name( self._AMCACHE_FULL_PATH).get_data_as_string() # Strip off the 4 leading zero's from the sha1 hash. event_data.sha1 = am_entry.get_value_by_name( self._AMCACHE_SHA1).get_data_as_string()[4:] productname = am_entry.get_value_by_name(self._AMCACHE_PRODUCTNAME) if productname: event_data.productname = productname.get_data_as_string() companyname = am_entry.get_value_by_name(self._AMCACHE_COMPANYNAME) if companyname: event_data.companyname = companyname.get_data_as_string() fileversion = am_entry.get_value_by_name(self._AMCACHE_FILEVERSION) if fileversion: event_data.fileversion = fileversion.get_data_as_string() languagecode = am_entry.get_value_by_name(self._AMCACHE_LANGUAGECODE) if languagecode: event_data.languagecode = languagecode.get_data_as_integer() filesize = am_entry.get_value_by_name(self._AMCACHE_FILESIZE) if filesize: event_data.filesize = filesize.get_data_as_integer() filedescription = am_entry.get_value_by_name(self._AMCACHE_FILEDESCRIPTION) if filedescription: event_data.filedescription = filedescription.get_data_as_string() linkerts = am_entry.get_value_by_name(self._AMCACHE_LINKERTS) if linkerts: event_data.linkerts = linkerts.get_data_as_integer() lastmodifiedts = am_entry.get_value_by_name(self._AMCACHE_LASTMODIFIEDTS) if lastmodifiedts: event_data.lastmodifiedts = lastmodifiedts.get_data_as_integer() createdts = am_entry.get_value_by_name(self._AMCACHE_CREATEDTS) if createdts: event_data.createdts = createdts.get_data_as_integer() programid = am_entry.get_value_by_name(self._AMCACHE_PROGRAMID) if programid: event_data.programid = programid.get_data_as_string() event = time_events.DateTimeValuesEvent( filetime.Filetime(amcache_datetime), definitions.TIME_DESCRIPTION_MODIFICATION) parser_mediator.ProduceEventWithEventData(event, event_data) if event_data.createdts: event = time_events.DateTimeValuesEvent( filetime.Filetime(event_data.createdts), definitions.TIME_DESCRIPTION_CREATION) parser_mediator.ProduceEventWithEventData(event, event_data) if event_data.lastmodifiedts: event = time_events.DateTimeValuesEvent( filetime.Filetime(event_data.lastmodifiedts), definitions.TIME_DESCRIPTION_MODIFICATION) parser_mediator.ProduceEventWithEventData(event, event_data) if event_data.linkerts: event = time_events.DateTimeValuesEvent( posix_time.PosixTime(event_data.linkerts), definitions.TIME_DESCRIPTION_CHANGE)
parser_mediator.ProduceEventWithEventData(event, event_data) manager.ParsersManager.RegisterParser(AmcacheParser)