/usr/lib/python2.7/dist-packages/dfwinreg/fake.py is in python-dfwinreg 20170706-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | # -*- coding: utf-8 -*-
"""Fake Windows Registry objects implementation."""
from __future__ import unicode_literals
import collections
try:
import construct_legacy as construct
except:
import construct
from dfdatetime import filetime as dfdatetime_filetime
from dfwinreg import definitions
from dfwinreg import errors
from dfwinreg import interface
from dfwinreg import key_paths
class FakeWinRegistryFile(interface.WinRegistryFile):
"""Fake implementation of a Windows Registry file."""
def __init__(self, ascii_codepage='cp1252', key_path_prefix=''):
"""Initializes a Windows Registry file.
Args:
ascii_codepage (str): ASCII string codepage.
key_path_prefix (str): Windows Registry key path prefix.
"""
super(FakeWinRegistryFile, self).__init__(
ascii_codepage=ascii_codepage, key_path_prefix=key_path_prefix)
self._root_key = None
def AddKeyByPath(self, key_path, registry_key):
"""Adds a Windows Registry key for a specific key path.
Args:
key_path (str): Windows Registry key path to add the key.
registry_key (WinRegistryKey): Windows Registry key.
Raises:
KeyError: if the subkey already exists.
ValueError: if the Windows Registry key cannot be added.
"""
if not key_path.startswith(definitions.KEY_PATH_SEPARATOR):
raise ValueError('Key path does not start with: {0:s}'.format(
definitions.KEY_PATH_SEPARATOR))
if not self._root_key:
self._root_key = FakeWinRegistryKey(self._key_path_prefix)
path_segments = key_paths.SplitKeyPath(key_path)
parent_key = self._root_key
for path_segment in path_segments:
try:
subkey = FakeWinRegistryKey(path_segment)
parent_key.AddSubkey(subkey)
except KeyError:
subkey = parent_key.GetSubkeyByName(path_segment)
parent_key = subkey
parent_key.AddSubkey(registry_key)
def Close(self):
"""Closes the Windows Registry file."""
return
def GetKeyByPath(self, key_path):
"""Retrieves the key for a specific path.
Args:
key_path (str): Windows Registry key path.
Returns:
WinRegistryKey: Windows Registry key or None if not available.
"""
key_path_upper = key_path.upper()
if key_path_upper.startswith(self._key_path_prefix_upper):
relative_key_path = key_path[self._key_path_prefix_length:]
elif key_path.startswith(definitions.KEY_PATH_SEPARATOR):
relative_key_path = key_path
key_path = ''.join([self._key_path_prefix, key_path])
else:
return
path_segments = key_paths.SplitKeyPath(relative_key_path)
registry_key = self._root_key
if not registry_key:
return
for path_segment in path_segments:
registry_key = registry_key.GetSubkeyByName(path_segment)
if not registry_key:
return
return registry_key
def GetRootKey(self):
"""Retrieves the root key.
Returns:
WinRegistryKey: Windows Registry key or None if not available.
"""
return self._root_key
def Open(self, unused_file_object):
"""Opens the Windows Registry file using a file-like object.
Args:
file_object (file): file-like object.
Returns:
bool: True if successful or False if not.
"""
return True
class FakeWinRegistryKey(interface.WinRegistryKey):
"""Fake implementation of a Windows Registry key."""
def __init__(
self, name, key_path='', last_written_time=None, offset=None,
subkeys=None, values=None):
"""Initializes a Windows Registry key.
Subkeys and values with duplicate names are silenty ignored.
Args:
name (str): name of the Windows Registry key.
key_path (Optional[str]): Windows Registry key path.
last_written_time (Optional[int]): last written time, formatted as
a FILETIME timestamp.
offset (Optional[int]): offset of the key within the Windows Registry
file.
subkeys (Optional[list[FakeWinRegistryKey]]): list of subkeys.
values (Optional[list[FakeWinRegistryValue]]): list of values.
"""
super(FakeWinRegistryKey, self).__init__(key_path=key_path)
self._last_written_time = last_written_time
self._name = name
self._offset = offset
self._subkeys = collections.OrderedDict()
self._values = collections.OrderedDict()
self._BuildKeyHierarchy(subkeys, values)
@property
def last_written_time(self):
"""dfdatetime.DateTimeValues: last written time or None."""
if self._last_written_time is not None:
return dfdatetime_filetime.Filetime(timestamp=self._last_written_time)
@property
def name(self):
"""str: name of the key."""
return self._name
@property
def number_of_subkeys(self):
"""int: number of subkeys within the key."""
return len(self._subkeys)
@property
def number_of_values(self):
"""int: number of values within the key."""
return len(self._values)
@property
def offset(self):
"""int: offset of the key within the Windows Registry file or None."""
return self._offset
def _BuildKeyHierarchy(self, subkeys, values):
"""Builds the Windows Registry key hierarchy.
Args:
subkeys (list[FakeWinRegistryKey]): list of subkeys.
values (list[FakeWinRegistryValue]): list of values.
"""
if subkeys:
for registry_key in subkeys:
name = registry_key.name.upper()
if name in self._subkeys:
continue
self._subkeys[name] = registry_key
# pylint: disable=protected-access
registry_key._key_path = key_paths.JoinKeyPath([
self._key_path, registry_key.name])
if values:
for registry_value in values:
name = registry_value.name.upper()
if name in self._values:
continue
self._values[name] = registry_value
def AddSubkey(self, registry_key):
"""Adds a subkey.
Args:
registry_key (WinRegistryKey): Windows Registry subkey.
Raises:
KeyError: if the subkey already exists.
"""
name = registry_key.name.upper()
if name in self._subkeys:
raise KeyError(
'Subkey: {0:s} already exists.'.format(registry_key.name))
self._subkeys[name] = registry_key
key_path = key_paths.JoinKeyPath([self._key_path, registry_key.name])
registry_key._key_path = key_path # pylint: disable=protected-access
def AddValue(self, registry_value):
"""Adds a value.
Args:
registry_value (WinRegistryValue): Windows Registry value.
Raises:
KeyError: if the value already exists.
"""
name = registry_value.name.upper()
if name in self._values:
raise KeyError(
'Value: {0:s} already exists.'.format(registry_value.name))
self._values[name] = registry_value
def GetSubkeyByIndex(self, index):
"""Retrieves a subkey by index.
Args:
index (int): index of the subkey.
Returns:
WinRegistryKey: Windows Registry subkey or None if not found.
Raises:
IndexError: if the index is out of bounds.
"""
subkeys = list(self._subkeys.values())
if index < 0 or index >= len(subkeys):
raise IndexError('Index out of bounds.')
return subkeys[index]
def GetSubkeyByName(self, name):
"""Retrieves a subkey by name.
Args:
name (str): name of the subkey.
Returns:
WinRegistryKey: Windows Registry subkey or None if not found.
"""
return self._subkeys.get(name.upper(), None)
def GetSubkeyByPath(self, path):
"""Retrieves a subkey by path.
Args:
path (str): path of the subkey.
Returns:
WinRegistryKey: Windows Registry subkey or None if not found.
"""
subkey = self
for path_segment in key_paths.SplitKeyPath(path):
subkey = subkey.GetSubkeyByName(path_segment)
if not subkey:
break
return subkey
def GetSubkeys(self):
"""Retrieves all subkeys within the key.
Yields:
WinRegistryKey: Windows Registry subkey.
"""
return iter(self._subkeys.values())
def GetValueByName(self, name):
"""Retrieves a value by name.
Args:
name (str): name of the value or an empty string for the default value.
Returns:
WinRegistryValue: Windows Registry value or None if not found.
"""
return self._values.get(name.upper(), None)
def GetValues(self):
"""Retrieves all values within the key.
Yields:
WinRegistryValue: Windows Registry value.
"""
return iter(self._values.values())
class FakeWinRegistryValue(interface.WinRegistryValue):
"""Fake implementation of a Windows Registry value."""
_INT32_BIG_ENDIAN = construct.SBInt32('value')
_INT32_LITTLE_ENDIAN = construct.SLInt32('value')
_INT64_LITTLE_ENDIAN = construct.SLInt64('value')
def __init__(self, name, data=b'', data_type=definitions.REG_NONE, offset=0):
"""Initializes a Windows Registry value.
Args:
name (str): name of the Windows Registry value.
data (Optional[bytes]): value data.
data_type (Optional[int]): value data type.
offset (Optional[int]): offset of the value within the Windows Registry
file.
"""
super(FakeWinRegistryValue, self).__init__()
self._data = data
self._data_type = data_type
self._data_size = len(data)
self._name = name
self._offset = offset
@property
def data(self):
"""bytes: value data as a byte string."""
return self._data
@property
def data_type(self):
"""int: data type."""
return self._data_type
@property
def name(self):
"""str: name of the value."""
return self._name
@property
def offset(self):
"""int: offset of the value within the Windows Registry file."""
return self._offset
def GetDataAsObject(self):
"""Retrieves the data as an object.
Returns:
object: data as a Python type.
Raises:
WinRegistryValueError: if the value data cannot be read.
"""
if not self._data:
return
if self._data_type in self._STRING_VALUE_TYPES:
try:
return self._data.decode('utf-16-le')
# AttributeError is raised when self._data has no decode method.
except AttributeError as exception:
raise errors.WinRegistryValueError((
'Unsupported data type: {0!s} of value: {1!s} with error: '
'{2!s}').format(type(self._data), self._name, exception))
except UnicodeError as exception:
raise errors.WinRegistryValueError(
'Unable to decode data of value: {0!s} with error: {1!s}'.format(
self._name, exception))
elif (self._data_type == definitions.REG_DWORD and
self._data_size == 4):
return self._INT32_LITTLE_ENDIAN.parse(self._data)
elif (self._data_type == definitions.REG_DWORD_BIG_ENDIAN and
self._data_size == 4):
return self._INT32_BIG_ENDIAN.parse(self._data)
elif (self._data_type == definitions.REG_QWORD and
self._data_size == 8):
return self._INT64_LITTLE_ENDIAN.parse(self._data)
elif self._data_type == definitions.REG_MULTI_SZ:
try:
utf16_string = self._data.decode('utf-16-le')
# TODO: evaluate the use of filter here is appropriate behavior.
return list(filter(None, utf16_string.split('\x00')))
# AttributeError is raised when self._data has no decode method.
except AttributeError as exception:
raise errors.WinRegistryValueError((
'Unsupported data type: {0!s} of value: {1!s} with error: '
'{2!s}').format(type(self._data), self._name, exception))
except UnicodeError as exception:
raise errors.WinRegistryValueError(
'Unable to read data from value: {0!s} with error: {1!s}'.format(
self._name, exception))
return self._data
|