lib.common.registry

Package lib :: Package common :: Module registry |
[hide private]
[frames] | no frames]

# Source Code for Module lib.common.registry

      1  # Copyright (C) 2010-2013 Claudio Guarnieri.
      2  # Copyright (C) 2014-2016 Cuckoo Foundation.
      3  # This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
      4  # See the file 'docs/LICENSE' for copying permission.
      5
      6  import logging
      7  import _winreg
      8
      9  from ctypes import windll, POINTER, byref, Structure, pointer
     10  from ctypes import c_ushort, c_wchar_p, c_void_p, create_string_buffer
     11  from ctypes.wintypes import HANDLE, DWORD, LPCWSTR, ULONG, LONG
     12
     13  log = logging.getLogger(__name__)
     14
     15 -class UNICODE_STRING(Structure):
     16      _fields_ = [
     17          ("Length", c_ushort),
     18          ("MaximumLength", c_ushort),
     19          ("Buffer", c_wchar_p),
     20      ]
     21
     22  RegOpenKeyExW = windll.advapi32.RegOpenKeyExW
     23  RegOpenKeyExW.argtypes = HANDLE, LPCWSTR, DWORD, ULONG, POINTER(HANDLE)
     24  RegOpenKeyExW.restype = LONG
     25
     26  RegCreateKeyExW = windll.advapi32.RegCreateKeyExW
     27  RegCreateKeyExW.argtypes = (
     28      HANDLE, LPCWSTR, DWORD, LPCWSTR, DWORD, DWORD,
     29      DWORD, POINTER(HANDLE), POINTER(DWORD),
     30  )
     31  RegCreateKeyExW.restype = LONG
     32
     33  RegQueryValueExW = windll.advapi32.RegQueryValueExW
     34  RegQueryValueExW.argtypes = \
     35      HANDLE, LPCWSTR, POINTER(DWORD), POINTER(DWORD), c_void_p, POINTER(DWORD)
     36  RegQueryValueExW.restype = LONG
     37
     38  RegSetValueExW = windll.advapi32.RegSetValueExW
     39  RegSetValueExW.argtypes = HANDLE, LPCWSTR, DWORD, DWORD, c_void_p, DWORD
     40  RegSetValueExW.restype = LONG
     41
     42  NtRenameKey = windll.ntdll.NtRenameKey
     43  NtRenameKey.argtypes = HANDLE, POINTER(UNICODE_STRING)
     44
     45  RegCloseKey = windll.advapi32.RegCloseKey
     46  RegCloseKey.argtypes = HANDLE,
     47
     48  _rootkeys = {
     49      "HKEY_LOCAL_MACHINE": _winreg.HKEY_LOCAL_MACHINE,
     50      "HKEY_CURRENT_USER": _winreg.HKEY_CURRENT_USER,
     51  }
     52
     53  _regtypes = {
     54      "REG_DWORD": _winreg.REG_DWORD,
     55      "REG_SZ": _winreg.REG_SZ,
     56      "REG_BINARY": _winreg.REG_BINARY,
     57  }
     58
     59 -def rename_regkey(skey, ssubkey, dsubkey):
     60      """Rename an entire tree of values in the registry.
     61      Function by Thorsten Sick."""
     62      res_handle = HANDLE()
     63      options = DWORD(0)
     64      res = RegOpenKeyExW(
     65          skey, ssubkey, options, _winreg.KEY_ALL_ACCESS, byref(res_handle)
     66      )
     67      if not res:
     68          bsize = c_ushort(len(dsubkey) * 2)
     69          us = UNICODE_STRING()
     70          us.Buffer = c_wchar_p(dsubkey)
     71          us.Length = bsize
     72          us.MaximumLength = bsize
     73
     74          res = NtRenameKey(res_handle, pointer(us))
     75          if res:
     76              log.warning("Error renaming %s\\%s to %s (0x%x)",
     77                          skey, ssubkey, dsubkey, res % 2**32)
     78
     79      if res_handle:
     80          RegCloseKey(res_handle)
     81
     82 -def regkey_exists(rootkey, subkey):
     83      res_handle = HANDLE()
     84      res = RegOpenKeyExW(
     85          rootkey, subkey, 0, _winreg.KEY_QUERY_VALUE, byref(res_handle)
     86      )
     87      RegCloseKey(res_handle)
     88      return not res
     89
     90 -def set_regkey(rootkey, subkey, name, type_, value):
     91      if type_ == _winreg.REG_SZ:
     92          value = unicode(value)
     93      if type_ == _winreg.REG_MULTI_SZ:
     94          value = u"\u0000".join(value) + u"\u0000\u0000"
     95
     96      res_handle = HANDLE()
     97      res = RegCreateKeyExW(
     98          rootkey, subkey, 0, None, 0, _winreg.KEY_ALL_ACCESS,
     99          0, byref(res_handle), None
    100      )
    101      if not res:
    102          RegSetValueExW(res_handle, name, 0, type_, value, len(value))
    103          RegCloseKey(res_handle)
    104
    105 -def set_regkey_full(regkey, type_, value):
    106      components = regkey.split("\\")
    107      rootkey, subkey, name = components[0], components[1:-1], components[-1]
    108      if rootkey not in _rootkeys:
    109          log.warning("Unknown root key for registry key: %s", rootkey)
    110          return
    111
    112      set_regkey(
    113          _rootkeys[rootkey], "\\".join(subkey), name,
    114          _regtypes.get(type_, type_), value
    115      )
    116
    117 -def query_value(rootkey, subkey, name):
    118      res_handle = HANDLE()
    119      type_ = DWORD()
    120      value = create_string_buffer(1024 * 1024)
    121      length = DWORD(1024 * 1024)
    122
    123      res = RegOpenKeyExW(
    124          rootkey, subkey, 0, _winreg.KEY_QUERY_VALUE, byref(res_handle)
    125      )
    126      if not res:
    127          res = RegQueryValueExW(
    128              res_handle, name, None, byref(type_), value, byref(length)
    129          )
    130          RegCloseKey(res_handle)
    131
    132      if not res:
    133          if type_.value == _winreg.REG_SZ:
    134              return value.raw[:length.value].decode("utf16").rstrip("\x00")
    135          if type_.value == _winreg.REG_MULTI_SZ:
    136              value = value.raw[:length.value].decode("utf16")
    137              return value.rstrip(u"\u0000").split(u"\u0000")
    138          return value.raw[:length.value]
    139