def OpenHive( self, filename_or_path_spec, hive_collector, hive_collector_name=None, codepage='cp1252'): """Open a Registry hive based on a collector or a filename. Args: filename_or_path_spec: file path to the hive as a string or a path spec object (instance of dfvfs.path.path_spec.PathSpec) hive_collector: the collector to use (instance of dfvfs.helpers.file_system_searcher.FileSystemSearcher) hive_collector_name: optional string denoting the name of the collector used. The default value is None. codepage: the default codepage, default is cp1252. Returns: A hive helper object (instance of PregHiveHelper). """ PregCache.knowledge_base_object.SetDefaultCodepage(codepage) if isinstance(filename_or_path_spec, basestring): filename = filename_or_path_spec path_spec = None else: filename = filename_or_path_spec.location path_spec = filename_or_path_spec if not hive_collector: path_spec = path_spec_factory.Factory.NewPathSpec( dfvfs_definitions.TYPE_INDICATOR_OS, location=filename) file_entry = path_spec_resolver.Resolver.OpenFileEntry(path_spec) else: file_entry = hive_collector.GetFileEntryByPathSpec(path_spec) win_registry = winregistry.WinRegistry( winregistry.WinRegistry.BACKEND_PYREGF) try: hive_object = win_registry.OpenFile( file_entry, codepage=PregCache.knowledge_base_object.codepage) except IOError: if filename is not None: filename_string = filename elif path_spec: filename_string = path_spec.location else: filename_string = u'unknown file path' logging.error( u'Unable to open Registry hive: {0:s} [{1:s}]'.format( filename_string, hive_collector_name)) return return PregHiveHelper( hive_object, file_entry=file_entry, collector_name=hive_collector_name)
def _GetKeyFromFileEntry(self, file_entry, key_path): """Retrieves a Windows Registry key from a file. Args: file_entry: A dfVFS file_entry object that references a test file. key_path: The path of the key to parse. Returns: A Windows Registry key (instance of WinRegKey). """ registry = winregistry.WinRegistry(winregistry.WinRegistry.BACKEND_PYREGF) winreg_file = registry.OpenFile(file_entry, codepage='cp1252') return winreg_file.GetKeyByPath(key_path)
def testBuildCache(self): """Tests creating a Windows Registry objects cache.""" registry = winregistry.WinRegistry( winregistry.WinRegistry.BACKEND_PYREGF) test_file = self._GetTestFilePath(['SYSTEM']) file_entry = self._GetTestFileEntry(test_file) winreg_file = registry.OpenFile(file_entry, codepage='cp1252') winreg_cache = cache.WinRegistryCache() # Test if this function does not raise an exception. winreg_cache.BuildCache(winreg_file, 'SYSTEM') self.assertEqual(winreg_cache.attributes['current_control_set'], 'ControlSet001')
def _GetKeyFromFile(self, path, key_path): """Retrieves a Windows Registry key from a file. Args: path: the path of the file. key_path: the path of the key to parse. Returns: A Windows Registry key (instance of WinRegKey). """ path_spec = path_spec_factory.Factory.NewPathSpec( definitions.TYPE_INDICATOR_OS, location=path) file_entry = path_spec_resolver.Resolver.OpenFileEntry(path_spec) registry = winregistry.WinRegistry( winregistry.WinRegistry.BACKEND_PYREGF) winreg_file = registry.OpenFile(file_entry, codepage='cp1252') return winreg_file.GetKeyByPath(key_path)
def testMountFile(self): """Tests mounting REGF files in the Registry.""" registry = winregistry.WinRegistry( winregistry.WinRegistry.BACKEND_PYREGF) test_file = self._GetTestFilePath(['SOFTWARE']) file_entry = self._GetTestFileEntry(test_file) winreg_file = registry.OpenFile(file_entry, codepage='cp1252') registry.MountFile(winreg_file, u'HKEY_LOCAL_MACHINE\\Software') test_file = self._GetTestFilePath(['NTUSER-WIN7.DAT']) file_entry = self._GetTestFileEntry(test_file) winreg_file = registry.OpenFile(file_entry, codepage='cp1252') with self.assertRaises(KeyError): registry.MountFile(winreg_file, u'HKEY_LOCAL_MACHINE\\Software') registry.MountFile(winreg_file, u'HKEY_CURRENT_USER')
def GetValue(self, searcher): """Return the value gathered from a registry key for preprocessing. Args: searcher: The file system searcher object (instance of dfvfs.FileSystemSearcher). Raises: errors.PreProcessFail: if the preprocessing fails. """ # TODO: optimize this in one find. try: path = self._file_path_expander.ExpandPath(self.REG_PATH) except KeyError: path = u'' if not path: raise errors.PreProcessFail(u'Unable to expand path: {0:s}'.format( self.REG_PATH)) find_spec = file_system_searcher.FindSpec(location=path, case_sensitive=False) path_specs = list(searcher.Find(find_specs=[find_spec])) if not path_specs or len(path_specs) != 1: raise errors.PreProcessFail( u'Unable to find directory: {0:s}'.format(self.REG_PATH)) directory_location = getattr(path_specs[0], 'location', None) if not directory_location: raise errors.PreProcessFail( u'Missing directory location for: {0:s}'.format(self.REG_PATH)) # The path is split in segments to make it path segement separator # independent (and thus platform independent). path_segments = searcher.SplitPath(directory_location) path_segments.append(self.REG_FILE) find_spec = file_system_searcher.FindSpec(location=path_segments, case_sensitive=False) path_specs = list(searcher.Find(find_specs=[find_spec])) if not path_specs: raise errors.PreProcessFail( u'Unable to find file: {0:s} in directory: {1:s}'.format( self.REG_FILE, directory_location)) if len(path_specs) != 1: raise errors.PreProcessFail( (u'Find for file: {1:s} in directory: {0:s} returned {2:d} ' u'results.').format(self.REG_FILE, directory_location, len(path_specs))) file_location = getattr(path_specs[0], 'location', None) if not directory_location: raise errors.PreProcessFail( u'Missing file location for: {0:s} in directory: {1:s}'.format( self.REG_FILE, directory_location)) try: file_entry = searcher.GetFileEntryByPathSpec(path_specs[0]) except IOError as exception: raise errors.PreProcessFail( u'Unable to open file entry: {0:s} with error: {1:s}'.format( file_location, exception)) if not file_entry: raise errors.PreProcessFail( u'Unable to open file entry: {0:s}'.format(file_location)) # TODO: remove this check win_registry.OpenFile doesn't fail instead? try: file_object = file_entry.GetFileObject() file_object.close() except IOError as exception: raise errors.PreProcessFail( u'Unable to open file object: {0:s} with error: {1:s}'.format( file_location, exception)) codepage = getattr(self._obj_store, 'code_page', 'cp1252') win_registry = winregistry.WinRegistry( winregistry.WinRegistry.BACKEND_PYREGF) try: winreg_file = win_registry.OpenFile(file_entry, codepage=codepage) except IOError as exception: raise errors.PreProcessFail( u'Unable to open Registry file: {0:s} with error: {1:s}'. format(file_location, exception)) self.winreg_file = winreg_file if not self._key_path_expander: # TODO: it is more efficient to have one cache that is passed to every # plugin, or maybe one path expander. Or replace the path expander by # dfvfs WindowsPathResolver? reg_cache = cache.WinRegistryCache() reg_cache.BuildCache(winreg_file, self.REG_FILE) self._key_path_expander = winreg_path_expander.WinRegistryKeyPathExpander( self._obj_store, reg_cache) try: key_path = self._key_path_expander.ExpandPath(self.REG_KEY) except KeyError: key_path = u'' if not key_path: raise errors.PreProcessFail(u'Unable to expand path: {0:s}'.format( self.REG_KEY)) try: key = winreg_file.GetKeyByPath(key_path) except IOError as exception: raise errors.PreProcessFail( u'Unable to fetch Registry key: {0:s} with error: {1:s}'. format(key_path, exception)) if not key: raise errors.PreProcessFail( u'Registry key {0:s} does not exist.'.format(self.REG_KEY)) return self.ParseKey(key)
def Parse(self, parser_mediator, **kwargs): """Parses a Windows Registry file. Args: parser_mediator: A parser mediator object (instance of ParserMediator). """ # TODO: Remove this magic reads when the classifier has been # implemented, until then we need to make sure we are dealing with # a Windows NT Registry file before proceeding. file_object = parser_mediator.GetFileObject() try: data = file_object.read(4) finally: file_object.close() file_entry = parser_mediator.GetFileEntry() if data != b'regf': raise errors.UnableToParseFile(( u'[{0:s}] unable to parse file: {1:s} with error: invalid ' u'signature.').format(self.NAME, file_entry.name)) registry = winregistry.WinRegistry( winregistry.WinRegistry.BACKEND_PYREGF) # Determine type, find all parsers try: winreg_file = registry.OpenFile( file_entry, codepage=parser_mediator.codepage) except IOError as exception: raise errors.UnableToParseFile( u'[{0:s}] unable to parse file: {1:s} with error: {2:s}'.format( self.NAME, file_entry.name, exception)) # Detect the Windows Registry file type. registry_type = 'UNKNOWN' for reg_type in self.REG_TYPES: if reg_type == 'UNKNOWN': continue # Check if all the known keys for a certain Registry file exist. known_keys_found = True for known_key_path in self.REG_TYPES[reg_type]: if not winreg_file.GetKeyByPath(known_key_path): known_keys_found = False break if known_keys_found: registry_type = reg_type break self._registry_type = registry_type logging.debug( u'Windows Registry file {0:s}: detected as: {1:s}'.format( file_entry.name, registry_type)) registry_cache = cache.WinRegistryCache() registry_cache.BuildCache(winreg_file, registry_type) plugins = {} number_of_plugins = 0 for weight in self._plugins.GetWeights(): plist = self._plugins.GetWeightPlugins(weight, registry_type) plugins[weight] = [] for plugin in plist: plugins[weight].append(plugin(reg_cache=registry_cache)) number_of_plugins += 1 logging.debug( u'Number of plugins for this Windows Registry file: {0:d}.'.format( number_of_plugins)) # Recurse through keys in the file and apply the plugins in the order: # 1. file type specific key-based plugins. # 2. generic key-based plugins. # 3. file type specific value-based plugins. # 4. generic value-based plugins. root_key = winreg_file.GetKeyByPath(u'\\') for key in self._RecurseKey(root_key): for weight in plugins.iterkeys(): # TODO: determine if the plugin matches the key and continue # to the next key. for plugin in plugins[weight]: if parser_mediator.abort: break plugin.UpdateChainAndProcess( parser_mediator, key=key, registry_type=self._registry_type, codepage=parser_mediator.codepage) winreg_file.Close()
def Parse(self, file_entry): """Extract data from a Windows Registry file. Args: file_entry: A file entry object. Yields: An event object. """ # TODO: Remove this magic reads when the classifier has been # implemented, until then we need to make sure we are dealing with # a Windows NT Registry file before proceeding. magic = 'regf' file_object = file_entry.GetFileObject() file_object.seek(0, os.SEEK_SET) data = file_object.read(len(magic)) file_object.close() if data != magic: raise errors.UnableToParseFile( (u'[{0:s}] unable to parse file: {1:s} with error: invalid ' u'signature.').format(self.parser_name, file_entry.name)) registry = winregistry.WinRegistry( winregistry.WinRegistry.BACKEND_PYREGF) # Determine type, find all parsers try: winreg_file = registry.OpenFile(file_entry, codepage=self._codepage) except IOError as exception: raise errors.UnableToParseFile( u'[{0:s}] unable to parse file: {1:s} with error: {2:s}'. format(self.parser_name, file_entry.name, exception)) # Detect the Windows Registry file type. registry_type = 'UNKNOWN' for reg_type in self.REG_TYPES: if reg_type == 'UNKNOWN': continue # Check if all the known keys for a certain Registry file exist. known_keys_found = True for known_key_path in self.REG_TYPES[reg_type]: if not winreg_file.GetKeyByPath(known_key_path): known_keys_found = False break if known_keys_found: registry_type = reg_type break self._registry_type = registry_type logging.debug( u'Windows Registry file {0:s}: detected as: {1:s}'.format( file_entry.name, registry_type)) registry_cache = cache.WinRegistryCache() registry_cache.BuildCache(winreg_file, registry_type) plugins = {} number_of_plugins = 0 for weight in self._plugins.GetWeights(): plist = self._plugins.GetWeightPlugins(weight, registry_type) plugins[weight] = [] for plugin in plist: plugins[weight].append( plugin(pre_obj=self._pre_obj, reg_cache=registry_cache)) number_of_plugins += 1 logging.debug( u'Number of plugins for this Windows Registry file: {0:d}.'.format( number_of_plugins)) # Recurse through keys in the file and apply the plugins in the order: # 1. file type specific key-based plugins. # 2. generic key-based plugins. # 3. file type specific value-based plugins. # 4. generic value-based plugins. root_key = winreg_file.GetKeyByPath(u'\\') for key in self._RecurseKey(root_key): parsed = False for weight in plugins: if parsed: break for plugin in plugins[weight]: call_back = plugin.Process(key) if call_back: parsed = True for event_object in self.GetEvents(call_back, key): event_object.plugin = plugin.plugin_name yield event_object break winreg_file.Close()