Shofel2_T124_python/venv/lib/python3.10/site-packages/Registry/Registry.py

454 lines
14 KiB
Python

#!/bin/python
# This file is part of python-registry.
#
# Copyright 2011, 2012 Willi Ballenthin <william.ballenthin@mandiant.com>
# while at Mandiant <http://www.mandiant.com>
#
# 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.
from __future__ import print_function
import sys
import ntpath
from enum import Enum
from . import RegistryParse
RegSZ = 0x0001
RegExpandSZ = 0x0002
RegBin = 0x0003
RegDWord = 0x0004
RegMultiSZ = 0x0007
RegQWord = 0x000B
RegNone = 0x0000
RegBigEndian = 0x0005
RegLink = 0x0006
RegResourceList = 0x0008
RegFullResourceDescriptor = 0x0009
RegResourceRequirementsList = 0x000A
RegFileTime = 0x0010
DEVPROP_MASK_TYPE = 0x00000FFF
class HiveType(Enum):
UNKNOWN = ""
NTUSER = "ntuser.dat"
SAM = "sam"
SECURITY = "security"
SOFTWARE = "software"
SYSTEM = "system"
USRCLASS = "usrclass.dat"
BCD = "bcd"
COMPONENTS = "components"
DEFAULT = "default"
SCHEMA = "schema.dat"
SETTINGS = "settings.dat"
class RegistryKeyHasNoParentException(RegistryParse.RegistryStructureDoesNotExist):
"""
"""
def __init__(self, value):
"""
Constructor.
Arguments:
- `value`: A string description.
"""
super(RegistryKeyHasNoParentException, self).__init__(value)
def __str__(self):
return "Registry key has no parent key: %s" % (self._value)
class RegistryKeyNotFoundException(RegistryParse.RegistryStructureDoesNotExist):
"""
"""
def __init__(self, value):
"""
Arguments:
- `value`:
"""
super(RegistryKeyNotFoundException, self).__init__(value)
def __str__(self):
return "Registry key not found: %s" % (self._value)
class RegistryValueNotFoundException(RegistryParse.RegistryStructureDoesNotExist):
"""
"""
def __init__(self, value):
"""
Arguments:
- `value`:
"""
super(RegistryValueNotFoundException, self).__init__(value)
def __str__(self):
return "Registry value not found: %s" % (self._value)
class RegistryValue(object):
"""
This is a high level structure for working with the Windows Registry.
It represents the 3-tuple of (name, type, value) associated with
a registry value.
"""
def __init__(self, vkrecord):
self._vkrecord = vkrecord
def name(self):
"""
Get the name of the value as a string.
The name of the default value is returned as "(default)".
"""
if self._vkrecord.has_name():
return self._vkrecord.name()
else:
return "(default)"
def value_type(self):
"""
Get the type of the value as an integer constant.
One of:
- RegSZ = 0x0001
- RegExpandSZ = 0x0002
- RegBin = 0x0003
- RegDWord = 0x0004
- RegMultiSZ = 0x0007
- RegQWord = 0x000B
- RegNone = 0x0000
- RegBigEndian = 0x0005
- RegLink = 0x0006
- RegResourceList = 0x0008
- RegFullResourceDescriptor = 0x0009
- RegResourceRequirementsList = 0x000A
- RegUint8 = 0x101
- RegInt16 = 0x102
- RegUint16 = 0x103
- RegInt32 = 0x104
- RegUint32 = 0x105
- RegInt64 = 0x106
- RegUint64 = 0x107
- RegFloat = 0x108
- RegDouble = 0x109
- RegUnicodeChar = 0x10A
- RegBoolean = 0x10B
- RegUnicodeString = 0x10C
- RegCompositeValue = 0x10D
- RegDateTimeOffset = 0x10E
- RegTimeSpan = 0x10F
- RegGUID = 0x110
- RegUnk111 = 0x111
- RegUnk112 = 0x112
- RegUnk113 = 0x113
- RegBytesArray = 0x114
- RegInt16Array = 0x115
- RegUint16Array = 0x116
- RegInt32Array = 0x117
- RegUInt32Array = 0x118
- RegInt64Array = 0x119
- RegUInt64Array = 0x11A
- RegFloatArray = 0x11B
- RegDoubleArray = 0x11C
- RegUnicodeCharArray = 0x11D
- RegBooleanArray = 0x11E
- RegUnicodeStringArray = 0x11F
"""
return self._vkrecord.data_type()
def value_type_str(self):
"""
Get the type of the value as a string.
One of:
- RegSZ
- RegExpandSZ
- RegBin
- RegDWord
- RegMultiSZ
- RegQWord
- RegNone
- RegBigEndian
- RegLink
- RegResourceList
- RegFullResourceDescriptor
- RegResourceRequirementsList
- RegUint8
- RegInt16
- RegUint16
- RegInt32
- RegUint32
- RegInt64
- RegUint64
- RegFloat
- RegDouble
- RegUnicodeChar
- RegBoolean
- RegUnicodeString
- RegCompositeValue
- RegDateTimeOffset
- RegTimeSpan
- RegGUID
- RegUnk111
- RegUnk112
- RegUnk113
- RegBytesArray
- RegInt16Array
- RegUint16Array
- RegInt32Array
- RegUInt32Array
- RegInt64Array
- RegUInt64Array
- RegFloatArray
- RegDoubleArray
- RegUnicodeCharArray
- RegBooleanArray
- RegUnicodeStringArray
"""
return self._vkrecord.data_type_str()
def value(self, overrun=0):
return self._vkrecord.data(overrun)
def raw_data(self, overrun=0):
return self._vkrecord.raw_data(overrun)
def timestamp(self):
"""
Get the last modified timestamp as a Python datetime. Only valid for
AppContainer settings.dat reg hive
"""
return self._vkrecord.timestamp()
class RegistryKey(object):
"""
A high level structure for use in traversing the Windows Registry.
A RegistryKey is a node in a tree-like structure.
A RegistryKey may have a set of values associated with it,
as well as a last modified timestamp.
"""
def __init__(self, nkrecord):
"""
Arguments:
- `NKRecord`:
"""
self._nkrecord = nkrecord
def __str__(self):
return "Registry Key %s with %d values and %d subkeys" % \
(self.path(), len(self.values()), len(self.subkeys()))
def __getitem__(self, key):
return self.value(key)
def timestamp(self):
"""
Get the last modified timestamp as a Python datetime.
"""
return self._nkrecord.timestamp()
def name(self):
"""
Get the name of the key as a string.
For example, "Windows" if the key path were
/{hive name}/SOFTWARE/Microsoft/Windows
See RegistryKey.path() to get the complete key name.
"""
return self._nkrecord.name()
def path(self):
"""
Get the full path of the RegistryKey as a string.
For example, "/{hive name}/SOFTWARE/Microsoft/Windows"
"""
return self._nkrecord.path()
def parent(self):
"""
Get the parent RegistryKey of this key, or raise
RegistryKeyHasNoParentException if it does not exist (for example,
the root key has no parent).
"""
# there may be a memory inefficiency here, since we create
# a new RegistryKey from the NKRecord parent key, rather
# than using the parent of this instance, if it exists.
try:
return RegistryKey(self._nkrecord.parent_key())
except RegistryParse.ParseException:
raise RegistryKeyHasNoParentException(self.name())
def subkeys(self):
"""
Return a list of all subkeys.
Each element in the list is a RegistryKey.
If the key has no subkeys, the empty list is returned.
"""
if self._nkrecord.subkey_number() == 0:
return []
l = self._nkrecord.subkey_list()
return [RegistryKey(k) for k in l.keys()]
def subkey(self, name):
"""
Return the subkey with a given name as a RegistryKey.
Raises RegistryKeyNotFoundException if the subkey with
the given name does not exist.
"""
if self._nkrecord.subkey_number() == 0:
raise RegistryKeyNotFoundException(self.path() + "\\" + name)
for k in self._nkrecord.subkey_list().keys():
if k.name().lower() == name.lower():
return RegistryKey(k)
raise RegistryKeyNotFoundException(self.path() + "\\" + name)
def values(self):
"""
Return a list containing the values associated with this RegistryKey.
Each element of the list will be a RegistryValue.
If there are no values associated with this RegistryKey, then the
empty list is returned.
"""
try:
return [RegistryValue(v) for v in self._nkrecord.values_list().values()]
except RegistryParse.RegistryStructureDoesNotExist:
return []
def value(self, name):
"""
Return the value with the given name as a RegistryValue.
Raises RegistryValueNotFoundExceptiono if the value with
the given name does not exist.
"""
if name == "(default)":
name = ""
try:
for v in self._nkrecord.values_list().values():
if v.name().lower() == name.lower():
return RegistryValue(v)
except RegistryParse.RegistryStructureDoesNotExist:
raise RegistryValueNotFoundException(self.path() + " : " + name)
raise RegistryValueNotFoundException(self.path() + " : " + name)
def find_key(self, path):
"""
Perform a search for a RegistryKey with a specific path.
"""
if len(path) == 0:
return self
(immediate, _, future) = path.partition("\\")
return self.subkey(immediate).find_key(future)
def values_number(self):
"""
Return the number of values associated with this key
"""
return self._nkrecord.values_number()
def subkeys_number(self):
"""
Return the number of subkeys associated with this key
"""
return self._nkrecord.subkey_number()
class Registry(object):
"""
A class for parsing and reading from a Windows Registry file.
"""
def __init__(self, filelikeobject):
"""
Constructor.
Arguments:
- `filelikeobject`: A file-like object with a .read() method.
If a Python string is passed, it is interpreted as a filename,
and the corresponding file is opened.
"""
try:
self._buf = filelikeobject.read()
except AttributeError:
with open(filelikeobject, "rb") as f:
self._buf = f.read()
self._regf = RegistryParse.REGFBlock(self._buf, 0, False)
def hive_name(self):
"""Returns the internal file name"""
return self._regf.hive_name()
def hive_type(self):
"""Returns the hive type"""
temp = self.hive_name()
temp = temp.replace('\\??\\', '')
temp = ntpath.basename(temp)
if temp.lower() == HiveType.NTUSER.value:
return HiveType.NTUSER
elif temp.lower() == HiveType.SAM.value:
return HiveType.SAM
elif temp.lower() == HiveType.SECURITY.value:
return HiveType.SECURITY
elif temp.lower() == HiveType.SOFTWARE.value:
return HiveType.SOFTWARE
elif temp.lower() == HiveType.SYSTEM.value:
return HiveType.SYSTEM
elif temp.lower() == HiveType.USRCLASS.value:
return HiveType.USRCLASS
elif temp.lower() == HiveType.BCD.value:
return HiveType.BCD
elif temp.lower() == HiveType.COMPONENTS.value:
return HiveType.COMPONENTS
elif temp.lower() == HiveType.DEFAULT.value:
return HiveType.DEFAULT
elif temp.lower() == HiveType.SCHEMA.value:
return HiveType.SCHEMA
elif temp.lower() == HiveType.SETTINGS.value:
return HiveType.SETTINGS
else:
return HiveType.UNKNOWN
def root(self):
"""
Return the first RegistryKey in the hive.
"""
return RegistryKey(self._regf.first_key())
def open(self, path):
"""
Return a RegistryKey by full path.
Subkeys are separated by the backslash character ('\').
A trailing backslash may or may not be present.
The hive name should not be included.
"""
# is the first registry key always the root?
# are there any other keys at this
# level? is this the name of the hive?
return RegistryKey(self._regf.first_key()).find_key(path)
def print_all(key):
if len(key.subkeys()) == 0:
print(key.path())
else:
for k in key.subkeys():
print_all(k)
if __name__ == '__main__':
r = Registry(sys.argv[1])
print_all(r.root())