#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright 2013 The Plaso Project Authors. # Please see the AUTHORS file for details on individual authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """This file contains the Windows Registry class.""" from plaso.winreg import interface from plaso.winreg import winpyregf class WinRegistry(object): """Class to provided a uniform way to access the Windows Registry.""" BACKEND_PYREGF = 1 _KNOWN_KEYS = { 'NTUSER.DAT': '\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer', 'SAM': '\\SAM\\Domains\\Account\\Users', 'SECURITY': '\\Policy\\PolAdtEv', 'SOFTWARE': '\\Microsoft\\Windows\\CurrentVersion\\App Paths', 'SYSTEM': '\\Select', } # TODO: this list is not finished yet and will need some more research. # For now an empty string represent the root and None an unknown or # not mounted. _FILENAME_MOUNTED_PATHS = { 'DEFAULT': None, 'NTUSER.DAT': 'HKEY_CURRENT_USER', 'NTUSER.MAN': None, 'REG.DAT': '', 'SAM': 'HKEY_LOCAL_MACHINE\\SAM', 'SECURITY': 'HKEY_LOCAL_MACHINE\\Security', 'SOFTWARE': 'HKEY_LOCAL_MACHINE\\Software', 'SYSTEM': 'HKEY_LOCAL_MACHINE\\System', 'SYSCACHE.HVE': None, 'SYSTEM.DAT': 'HKEY_LOCAL_MACHINE', 'USERDIFF': None, 'USERS.DAT': 'HKEY_USERS', 'USRCLASS.DAT': 'HKEY_CURRENT_USER\\Software\\Classes', } def __init__(self, backend=1): """Initializes the Windows Registry. Args: backend: The back-end to use to read the Registry structures, the default is 1 (pyregf). """ self._backend = backend self._files = {} @classmethod def GetMountedPath(cls, filename): """Determines the mounted path based on the filename. Args: filename: The name of the Windows Registry file. Returns: The mounted path if successful or None otherwise. """ return cls._FILENAME_MOUNTED_PATHS.get(filename.upper(), None) def OpenFile(self, file_entry, codepage='cp1252'): """Opens the file object based on the back-end. Args: file_entry: The file entry object. codepage: Optional extended ASCII string codepage. The default is cp1252. Returns: The a Windows Registry file (instance of WinRegFile) if successful or None otherwise. """ winreg_file = None if self._backend == self.BACKEND_PYREGF: winreg_file = winpyregf.WinPyregfFile() if winreg_file: winreg_file.Open(file_entry, codepage=codepage) return winreg_file def MountFile(self, winreg_file, mounted_path): """Mounts a file in the Registry. Args: winreg_file: The Windows Registry file (instance of WinRegFile). mounted_path: The path of the key where the Windows Registry file is mounted. Raises: KeyError: if mounted path is already set. ValueError: if mounted path is not set. """ if not mounted_path: raise ValueError(u'Missing mounted path value') if mounted_path in self._files: raise KeyError(u'Mounted path: {0:s} already set.'.format(mounted_path)) self._files[mounted_path] = winreg_file def GetKeyByPath(self, path): """Retrieves a specific key defined by the Registry path. Returns: The key (instance of WinRegKey) if available or None otherwise. """ mounted_path = None if self._files: for mounted_path in self._files.keys(): if path.startswith(mounted_path): break if not mounted_path: return None winreg_file = self._files[mounted_path] mounted_path_length = len(mounted_path) if mounted_path.endswith(interface.WinRegKey.PATH_SEPARATOR): mounted_path_length -= 1 path = path[mounted_path_length:] if not winreg_file: return None winreg_key = winreg_file.GetKeyByPath(path) # TODO: correct the path of the key for the mounted location. return winreg_key