# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved. # # This software is provided under under a slightly modified version # of the Apache Software License. See the accompanying LICENSE file # for more information. # # Author: Alberto Solino (@agsolino) # # Description: # [MS-RRP] Interface implementation # # Best way to learn how to use these calls is to grab the protocol standard # so you understand what the call does, and then read the test case located # at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC # # Some calls have helper functions, which makes it even easier to use. # They are located at the end of this file. # Helper functions start with "h". # There are test cases for them too. # from struct import unpack, pack from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantVaryingArray, NDRUniConformantArray from impacket.dcerpc.v5.dtypes import DWORD, UUID, ULONG, LPULONG, BOOLEAN, SECURITY_INFORMATION, PFILETIME, \ RPC_UNICODE_STRING, FILETIME, NULL, MAXIMUM_ALLOWED, OWNER_SECURITY_INFORMATION, PWCHAR, PRPC_UNICODE_STRING from impacket.dcerpc.v5.rpcrt import DCERPCException from impacket import system_errors, LOG from impacket.uuid import uuidtup_to_bin MSRPC_UUID_RRP = uuidtup_to_bin(('338CD001-2244-31F1-AAAA-900038001003', '1.0')) class DCERPCSessionError(DCERPCException): def __init__(self, error_string=None, error_code=None, packet=None): DCERPCException.__init__(self, error_string, error_code, packet) def __str__( self ): key = self.error_code if key in system_errors.ERROR_MESSAGES: error_msg_short = system_errors.ERROR_MESSAGES[key][0] error_msg_verbose = system_errors.ERROR_MESSAGES[key][1] return 'RRP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose) else: return 'RRP SessionError: unknown error code: 0x%x' % self.error_code ################################################################################ # CONSTANTS ################################################################################ # 2.2.2 PREGISTRY_SERVER_NAME PREGISTRY_SERVER_NAME = PWCHAR # 2.2.3 error_status_t error_status_t = ULONG # 2.2.5 RRP_UNICODE_STRING RRP_UNICODE_STRING = RPC_UNICODE_STRING PRRP_UNICODE_STRING = PRPC_UNICODE_STRING # 2.2.4 REGSAM REGSAM = ULONG KEY_QUERY_VALUE = 0x00000001 KEY_SET_VALUE = 0x00000002 KEY_CREATE_SUB_KEY = 0x00000004 KEY_ENUMERATE_SUB_KEYS = 0x00000008 KEY_CREATE_LINK = 0x00000020 KEY_WOW64_64KEY = 0x00000100 KEY_WOW64_32KEY = 0x00000200 REG_BINARY = 3 REG_DWORD = 4 REG_DWORD_LITTLE_ENDIAN = 4 REG_DWORD_BIG_ENDIAN = 5 REG_EXPAND_SZ = 2 REG_LINK = 6 REG_MULTI_SZ = 7 REG_NONE = 0 REG_QWORD = 11 REG_QWORD_LITTLE_ENDIAN = 11 REG_SZ = 1 # 3.1.5.7 BaseRegCreateKey (Opnum 6) REG_CREATED_NEW_KEY = 0x00000001 REG_OPENED_EXISTING_KEY = 0x00000002 # 3.1.5.19 BaseRegRestoreKey (Opnum 19) # Flags REG_WHOLE_HIVE_VOLATILE = 0x00000001 REG_REFRESH_HIVE = 0x00000002 REG_NO_LAZY_FLUSH = 0x00000004 REG_FORCE_RESTORE = 0x00000008 ################################################################################ # STRUCTURES ################################################################################ # 2.2.1 RPC_HKEY class RPC_HKEY(NDRSTRUCT): structure = ( ('context_handle_attributes',ULONG), ('context_handle_uuid',UUID), ) def __init__(self, data=None, isNDR64=False): NDRSTRUCT.__init__(self, data, isNDR64) self['context_handle_uuid'] = b'\x00'*16 def isNull(self): return self['context_handle_uuid'] == b'\x00'*16 # 2.2.6 RVALENT class RVALENT(NDRSTRUCT): structure = ( ('ve_valuename',PRRP_UNICODE_STRING), ('ve_valuelen',DWORD), ('ve_valueptr',DWORD), ('ve_type',DWORD), ) class RVALENT_ARRAY(NDRUniConformantVaryingArray): item = RVALENT # 2.2.9 RPC_SECURITY_DESCRIPTOR class BYTE_ARRAY(NDRUniConformantVaryingArray): pass class PBYTE_ARRAY(NDRPOINTER): referent = ( ('Data', BYTE_ARRAY), ) class RPC_SECURITY_DESCRIPTOR(NDRSTRUCT): structure = ( ('lpSecurityDescriptor',PBYTE_ARRAY), ('cbInSecurityDescriptor',DWORD), ('cbOutSecurityDescriptor',DWORD), ) # 2.2.8 RPC_SECURITY_ATTRIBUTES class RPC_SECURITY_ATTRIBUTES(NDRSTRUCT): structure = ( ('nLength',DWORD), ('RpcSecurityDescriptor',RPC_SECURITY_DESCRIPTOR), ('bInheritHandle',BOOLEAN), ) class PRPC_SECURITY_ATTRIBUTES(NDRPOINTER): referent = ( ('Data', RPC_SECURITY_ATTRIBUTES), ) ################################################################################ # RPC CALLS ################################################################################ # 3.1.5.1 OpenClassesRoot (Opnum 0) class OpenClassesRoot(NDRCALL): opnum = 0 structure = ( ('ServerName', PREGISTRY_SERVER_NAME), ('samDesired', REGSAM), ) class OpenClassesRootResponse(NDRCALL): structure = ( ('phKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.2 OpenCurrentUser (Opnum 1) class OpenCurrentUser(NDRCALL): opnum = 1 structure = ( ('ServerName', PREGISTRY_SERVER_NAME), ('samDesired', REGSAM), ) class OpenCurrentUserResponse(NDRCALL): structure = ( ('phKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.3 OpenLocalMachine (Opnum 2) class OpenLocalMachine(NDRCALL): opnum = 2 structure = ( ('ServerName', PREGISTRY_SERVER_NAME), ('samDesired', REGSAM), ) class OpenLocalMachineResponse(NDRCALL): structure = ( ('phKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.4 OpenPerformanceData (Opnum 3) class OpenPerformanceData(NDRCALL): opnum = 3 structure = ( ('ServerName', PREGISTRY_SERVER_NAME), ('samDesired', REGSAM), ) class OpenPerformanceDataResponse(NDRCALL): structure = ( ('phKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.5 OpenUsers (Opnum 4) class OpenUsers(NDRCALL): opnum = 4 structure = ( ('ServerName', PREGISTRY_SERVER_NAME), ('samDesired', REGSAM), ) class OpenUsersResponse(NDRCALL): structure = ( ('phKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.6 BaseRegCloseKey (Opnum 5) class BaseRegCloseKey(NDRCALL): opnum = 5 structure = ( ('hKey', RPC_HKEY), ) class BaseRegCloseKeyResponse(NDRCALL): structure = ( ('hKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.7 BaseRegCreateKey (Opnum 6) class BaseRegCreateKey(NDRCALL): opnum = 6 structure = ( ('hKey', RPC_HKEY), ('lpSubKey', RRP_UNICODE_STRING), ('lpClass', RRP_UNICODE_STRING), ('dwOptions', DWORD), ('samDesired', REGSAM), ('lpSecurityAttributes', PRPC_SECURITY_ATTRIBUTES), ('lpdwDisposition', LPULONG), ) class BaseRegCreateKeyResponse(NDRCALL): structure = ( ('phkResult', RPC_HKEY), ('lpdwDisposition', LPULONG), ('ErrorCode', error_status_t), ) # 3.1.5.8 BaseRegDeleteKey (Opnum 7) class BaseRegDeleteKey(NDRCALL): opnum = 7 structure = ( ('hKey', RPC_HKEY), ('lpSubKey', RRP_UNICODE_STRING), ) class BaseRegDeleteKeyResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.9 BaseRegDeleteValue (Opnum 8) class BaseRegDeleteValue(NDRCALL): opnum = 8 structure = ( ('hKey', RPC_HKEY), ('lpValueName', RRP_UNICODE_STRING), ) class BaseRegDeleteValueResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.10 BaseRegEnumKey (Opnum 9) class BaseRegEnumKey(NDRCALL): opnum = 9 structure = ( ('hKey', RPC_HKEY), ('dwIndex', DWORD), ('lpNameIn', RRP_UNICODE_STRING), ('lpClassIn', PRRP_UNICODE_STRING), ('lpftLastWriteTime', PFILETIME), ) class BaseRegEnumKeyResponse(NDRCALL): structure = ( ('lpNameOut', RRP_UNICODE_STRING), ('lplpClassOut', PRRP_UNICODE_STRING), ('lpftLastWriteTime', PFILETIME), ('ErrorCode', error_status_t), ) # 3.1.5.11 BaseRegEnumValue (Opnum 10) class BaseRegEnumValue(NDRCALL): opnum = 10 structure = ( ('hKey', RPC_HKEY), ('dwIndex', DWORD), ('lpValueNameIn', RRP_UNICODE_STRING), ('lpType', LPULONG), ('lpData', PBYTE_ARRAY), ('lpcbData', LPULONG), ('lpcbLen', LPULONG), ) class BaseRegEnumValueResponse(NDRCALL): structure = ( ('lpValueNameOut', RRP_UNICODE_STRING), ('lpType', LPULONG), ('lpData', PBYTE_ARRAY), ('lpcbData', LPULONG), ('lpcbLen', LPULONG), ('ErrorCode', error_status_t), ) # 3.1.5.12 BaseRegFlushKey (Opnum 11) class BaseRegFlushKey(NDRCALL): opnum = 11 structure = ( ('hKey', RPC_HKEY), ) class BaseRegFlushKeyResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.13 BaseRegGetKeySecurity (Opnum 12) class BaseRegGetKeySecurity(NDRCALL): opnum = 12 structure = ( ('hKey', RPC_HKEY), ('SecurityInformation', SECURITY_INFORMATION), ('pRpcSecurityDescriptorIn', RPC_SECURITY_DESCRIPTOR), ) class BaseRegGetKeySecurityResponse(NDRCALL): structure = ( ('pRpcSecurityDescriptorOut', RPC_SECURITY_DESCRIPTOR), ('ErrorCode', error_status_t), ) # 3.1.5.14 BaseRegLoadKey (Opnum 13) class BaseRegLoadKey(NDRCALL): opnum = 13 structure = ( ('hKey', RPC_HKEY), ('lpSubKey', RRP_UNICODE_STRING), ('lpFile', RRP_UNICODE_STRING), ) class BaseRegLoadKeyResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.15 BaseRegOpenKey (Opnum 15) class BaseRegOpenKey(NDRCALL): opnum = 15 structure = ( ('hKey', RPC_HKEY), ('lpSubKey', RRP_UNICODE_STRING), ('dwOptions', DWORD), ('samDesired', REGSAM), ) class BaseRegOpenKeyResponse(NDRCALL): structure = ( ('phkResult', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.16 BaseRegQueryInfoKey (Opnum 16) class BaseRegQueryInfoKey(NDRCALL): opnum = 16 structure = ( ('hKey', RPC_HKEY), ('lpClassIn', RRP_UNICODE_STRING), ) class BaseRegQueryInfoKeyResponse(NDRCALL): structure = ( ('lpClassOut', RPC_UNICODE_STRING), ('lpcSubKeys', DWORD), ('lpcbMaxSubKeyLen', DWORD), ('lpcbMaxClassLen', DWORD), ('lpcValues', DWORD), ('lpcbMaxValueNameLen', DWORD), ('lpcbMaxValueLen', DWORD), ('lpcbSecurityDescriptor', DWORD), ('lpftLastWriteTime', FILETIME), ('ErrorCode', error_status_t), ) # 3.1.5.17 BaseRegQueryValue (Opnum 17) class BaseRegQueryValue(NDRCALL): opnum = 17 structure = ( ('hKey', RPC_HKEY), ('lpValueName', RRP_UNICODE_STRING), ('lpType', LPULONG), ('lpData', PBYTE_ARRAY), ('lpcbData', LPULONG), ('lpcbLen', LPULONG), ) class BaseRegQueryValueResponse(NDRCALL): structure = ( ('lpType', LPULONG), ('lpData', PBYTE_ARRAY), ('lpcbData', LPULONG), ('lpcbLen', LPULONG), ('ErrorCode', error_status_t), ) # 3.1.5.18 BaseRegReplaceKey (Opnum 18) class BaseRegReplaceKey(NDRCALL): opnum = 18 structure = ( ('hKey', RPC_HKEY), ('lpSubKey', RRP_UNICODE_STRING), ('lpNewFile', RRP_UNICODE_STRING), ('lpOldFile', RRP_UNICODE_STRING), ) class BaseRegReplaceKeyResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.19 BaseRegRestoreKey (Opnum 19) class BaseRegRestoreKey(NDRCALL): opnum = 19 structure = ( ('hKey', RPC_HKEY), ('lpFile', RRP_UNICODE_STRING), ('Flags', DWORD), ) class BaseRegRestoreKeyResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.20 BaseRegSaveKey (Opnum 20) class BaseRegSaveKey(NDRCALL): opnum = 20 structure = ( ('hKey', RPC_HKEY), ('lpFile', RRP_UNICODE_STRING), ('pSecurityAttributes', PRPC_SECURITY_ATTRIBUTES), ) class BaseRegSaveKeyResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.21 BaseRegSetKeySecurity (Opnum 21) class BaseRegSetKeySecurity(NDRCALL): opnum = 21 structure = ( ('hKey', RPC_HKEY), ('SecurityInformation', SECURITY_INFORMATION), ('pRpcSecurityDescriptor', RPC_SECURITY_DESCRIPTOR), ) class BaseRegSetKeySecurityResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.22 BaseRegSetValue (Opnum 22) class BaseRegSetValue(NDRCALL): opnum = 22 structure = ( ('hKey', RPC_HKEY), ('lpValueName', RRP_UNICODE_STRING), ('dwType', DWORD), ('lpData', NDRUniConformantArray), ('cbData', DWORD), ) class BaseRegSetValueResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.23 BaseRegUnLoadKey (Opnum 23) class BaseRegUnLoadKey(NDRCALL): opnum = 23 structure = ( ('hKey', RPC_HKEY), ('lpSubKey', RRP_UNICODE_STRING), ) class BaseRegUnLoadKeyResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.24 BaseRegGetVersion (Opnum 26) class BaseRegGetVersion(NDRCALL): opnum = 26 structure = ( ('hKey', RPC_HKEY), ) class BaseRegGetVersionResponse(NDRCALL): structure = ( ('lpdwVersion', DWORD), ('ErrorCode', error_status_t), ) # 3.1.5.25 OpenCurrentConfig (Opnum 27) class OpenCurrentConfig(NDRCALL): opnum = 27 structure = ( ('ServerName', PREGISTRY_SERVER_NAME), ('samDesired', REGSAM), ) class OpenCurrentConfigResponse(NDRCALL): structure = ( ('phKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.26 BaseRegQueryMultipleValues (Opnum 29) class BaseRegQueryMultipleValues(NDRCALL): opnum = 29 structure = ( ('hKey', RPC_HKEY), ('val_listIn', RVALENT_ARRAY), ('num_vals', DWORD), ('lpvalueBuf', PBYTE_ARRAY), ('ldwTotsize', DWORD), ) class BaseRegQueryMultipleValuesResponse(NDRCALL): structure = ( ('val_listOut', RVALENT_ARRAY), ('lpvalueBuf', PBYTE_ARRAY), ('ldwTotsize', DWORD), ('ErrorCode', error_status_t), ) # 3.1.5.27 BaseRegSaveKeyEx (Opnum 31) class BaseRegSaveKeyEx(NDRCALL): opnum = 31 structure = ( ('hKey', RPC_HKEY), ('lpFile', RRP_UNICODE_STRING), ('pSecurityAttributes', PRPC_SECURITY_ATTRIBUTES), ('Flags', DWORD), ) class BaseRegSaveKeyExResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) # 3.1.5.28 OpenPerformanceText (Opnum 32) class OpenPerformanceText(NDRCALL): opnum = 32 structure = ( ('ServerName', PREGISTRY_SERVER_NAME), ('samDesired', REGSAM), ) class OpenPerformanceTextResponse(NDRCALL): structure = ( ('phKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.29 OpenPerformanceNlsText (Opnum 33) class OpenPerformanceNlsText(NDRCALL): opnum = 33 structure = ( ('ServerName', PREGISTRY_SERVER_NAME), ('samDesired', REGSAM), ) class OpenPerformanceNlsTextResponse(NDRCALL): structure = ( ('phKey', RPC_HKEY), ('ErrorCode', error_status_t), ) # 3.1.5.30 BaseRegQueryMultipleValues2 (Opnum 34) class BaseRegQueryMultipleValues2(NDRCALL): opnum = 34 structure = ( ('hKey', RPC_HKEY), ('val_listIn', RVALENT_ARRAY), ('num_vals', DWORD), ('lpvalueBuf', PBYTE_ARRAY), ('ldwTotsize', DWORD), ) class BaseRegQueryMultipleValues2Response(NDRCALL): structure = ( ('val_listOut', RVALENT_ARRAY), ('lpvalueBuf', PBYTE_ARRAY), ('ldwRequiredSize', DWORD), ('ErrorCode', error_status_t), ) # 3.1.5.31 BaseRegDeleteKeyEx (Opnum 35) class BaseRegDeleteKeyEx(NDRCALL): opnum = 35 structure = ( ('hKey', RPC_HKEY), ('lpSubKey', RRP_UNICODE_STRING), ('AccessMask', REGSAM), ('Reserved', DWORD), ) class BaseRegDeleteKeyExResponse(NDRCALL): structure = ( ('ErrorCode', error_status_t), ) ################################################################################ # OPNUMs and their corresponding structures ################################################################################ OPNUMS = { 0 : (OpenClassesRoot, OpenClassesRootResponse), 1 : (OpenCurrentUser, OpenCurrentUserResponse), 2 : (OpenLocalMachine, OpenLocalMachineResponse), 3 : (OpenPerformanceData, OpenPerformanceDataResponse), 4 : (OpenUsers, OpenUsersResponse), 5 : (BaseRegCloseKey, BaseRegCloseKeyResponse), 6 : (BaseRegCreateKey, BaseRegCreateKeyResponse), 7 : (BaseRegDeleteKey, BaseRegDeleteKeyResponse), 8 : (BaseRegDeleteValue, BaseRegDeleteValueResponse), 9 : (BaseRegEnumKey, BaseRegEnumKeyResponse), 10 : (BaseRegEnumValue, BaseRegEnumValueResponse), 11 : (BaseRegFlushKey, BaseRegFlushKeyResponse), 12 : (BaseRegGetKeySecurity, BaseRegGetKeySecurityResponse), 13 : (BaseRegLoadKey, BaseRegLoadKeyResponse), 15 : (BaseRegOpenKey, BaseRegOpenKeyResponse), 16 : (BaseRegQueryInfoKey, BaseRegQueryInfoKeyResponse), 17 : (BaseRegQueryValue, BaseRegQueryValueResponse), 18 : (BaseRegReplaceKey, BaseRegReplaceKeyResponse), 19 : (BaseRegRestoreKey, BaseRegRestoreKeyResponse), 20 : (BaseRegSaveKey, BaseRegSaveKeyResponse), 21 : (BaseRegSetKeySecurity, BaseRegSetKeySecurityResponse), 22 : (BaseRegSetValue, BaseRegSetValueResponse), 23 : (BaseRegUnLoadKey, BaseRegUnLoadKeyResponse), 26 : (BaseRegGetVersion, BaseRegGetVersionResponse), 27 : (OpenCurrentConfig, OpenCurrentConfigResponse), 29 : (BaseRegQueryMultipleValues, BaseRegQueryMultipleValuesResponse), 31 : (BaseRegSaveKeyEx, BaseRegSaveKeyExResponse), 32 : (OpenPerformanceText, OpenPerformanceTextResponse), 33 : (OpenPerformanceNlsText, OpenPerformanceNlsTextResponse), 34 : (BaseRegQueryMultipleValues2, BaseRegQueryMultipleValues2Response), 35 : (BaseRegDeleteKeyEx, BaseRegDeleteKeyExResponse), } ################################################################################ # HELPER FUNCTIONS ################################################################################ def checkNullString(string): if string == NULL: return string if string[-1:] != '\x00': return string + '\x00' else: return string def packValue(valueType, value): if valueType == REG_DWORD: retData = pack('L', value) elif valueType == REG_EXPAND_SZ: try: retData = value.encode('utf-16le') except UnicodeDecodeError: import sys retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le') elif valueType == REG_MULTI_SZ: try: retData = value.encode('utf-16le') except UnicodeDecodeError: import sys retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le') elif valueType == REG_QWORD: retData = pack('Q', value) elif valueType == REG_SZ: try: retData = value.encode('utf-16le') except UnicodeDecodeError: import sys retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le') else: retData = value return retData def unpackValue(valueType, value): if valueType == REG_DWORD: retData = unpack('L', b''.join(value))[0] elif valueType == REG_EXPAND_SZ: retData = b''.join(value).decode('utf-16le') elif valueType == REG_MULTI_SZ: retData = b''.join(value).decode('utf-16le') elif valueType == REG_QWORD: retData = unpack('Q', b''.join(value))[0] elif valueType == REG_SZ: retData = b''.join(value).decode('utf-16le') else: retData = b''.join(value) return retData def hOpenClassesRoot(dce, samDesired = MAXIMUM_ALLOWED): request = OpenClassesRoot() request['ServerName'] = NULL request['samDesired'] = samDesired return dce.request(request) def hOpenCurrentUser(dce, samDesired = MAXIMUM_ALLOWED): request = OpenCurrentUser() request['ServerName'] = NULL request['samDesired'] = samDesired return dce.request(request) def hOpenLocalMachine(dce, samDesired = MAXIMUM_ALLOWED): request = OpenLocalMachine() request['ServerName'] = NULL request['samDesired'] = samDesired return dce.request(request) def hOpenPerformanceData(dce, samDesired = MAXIMUM_ALLOWED): request = OpenPerformanceData() request['ServerName'] = NULL request['samDesired'] = samDesired return dce.request(request) def hOpenUsers(dce, samDesired = MAXIMUM_ALLOWED): request = OpenUsers() request['ServerName'] = NULL request['samDesired'] = samDesired return dce.request(request) def hBaseRegCloseKey(dce, hKey): request = BaseRegCloseKey() request['hKey'] = hKey return dce.request(request) def hBaseRegCreateKey(dce, hKey, lpSubKey, lpClass = NULL, dwOptions = 0x00000001, samDesired = MAXIMUM_ALLOWED, lpSecurityAttributes = NULL, lpdwDisposition = REG_CREATED_NEW_KEY): request = BaseRegCreateKey() request['hKey'] = hKey request['lpSubKey'] = checkNullString(lpSubKey) request['lpClass'] = checkNullString(lpClass) request['dwOptions'] = dwOptions request['samDesired'] = samDesired if lpSecurityAttributes == NULL: request['lpSecurityAttributes']['RpcSecurityDescriptor']['lpSecurityDescriptor'] = NULL else: request['lpSecurityAttributes'] = lpSecurityAttributes request['lpdwDisposition'] = lpdwDisposition return dce.request(request) def hBaseRegDeleteKey(dce, hKey, lpSubKey): request = BaseRegDeleteKey() request['hKey'] = hKey request['lpSubKey'] = checkNullString(lpSubKey) return dce.request(request) def hBaseRegEnumKey(dce, hKey, dwIndex, lpftLastWriteTime = NULL): request = BaseRegEnumKey() request['hKey'] = hKey request['dwIndex'] = dwIndex request.fields['lpNameIn'].fields['MaximumLength'] = 1024 request.fields['lpNameIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = 1024//2 request['lpClassIn'] = ' '* 64 request['lpftLastWriteTime'] = lpftLastWriteTime return dce.request(request) def hBaseRegEnumValue(dce, hKey, dwIndex, dataLen=256): request = BaseRegEnumValue() request['hKey'] = hKey request['dwIndex'] = dwIndex retries = 1 # We need to be aware the size might not be enough, so let's catch ERROR_MORE_DATA exception while True: try: # Only the maximum length field of the lpValueNameIn is used to determine the buffer length to be allocated # by the service. Specify a string with a zero length but maximum length set to the largest buffer size # needed to hold the value names. request.fields['lpValueNameIn'].fields['MaximumLength'] = dataLen*2 request.fields['lpValueNameIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = dataLen request['lpData'] = b' ' * dataLen request['lpcbData'] = dataLen request['lpcbLen'] = dataLen resp = dce.request(request) except DCERPCSessionError as e: if retries > 1: LOG.debug('Too many retries when calling hBaseRegEnumValue, aborting') raise if e.get_error_code() == system_errors.ERROR_MORE_DATA: # We need to adjust the size retries +=1 dataLen = e.get_packet()['lpcbData'] continue else: raise else: break return resp def hBaseRegFlushKey(dce, hKey): request = BaseRegFlushKey() request['hKey'] = hKey return dce.request(request) def hBaseRegGetKeySecurity(dce, hKey, securityInformation = OWNER_SECURITY_INFORMATION ): request = BaseRegGetKeySecurity() request['hKey'] = hKey request['SecurityInformation'] = securityInformation request['pRpcSecurityDescriptorIn']['lpSecurityDescriptor'] = NULL request['pRpcSecurityDescriptorIn']['cbInSecurityDescriptor'] = 1024 return dce.request(request) def hBaseRegLoadKey(dce, hKey, lpSubKey, lpFile): request = BaseRegLoadKey() request['hKey'] = hKey request['lpSubKey'] = checkNullString(lpSubKey) request['lpFile'] = checkNullString(lpFile) return dce.request(request) def hBaseRegUnLoadKey(dce, hKey, lpSubKey): request = BaseRegUnLoadKey() request['hKey'] = hKey request['lpSubKey'] = checkNullString(lpSubKey) return dce.request(request) def hBaseRegOpenKey(dce, hKey, lpSubKey, dwOptions=0x00000001, samDesired = MAXIMUM_ALLOWED): request = BaseRegOpenKey() request['hKey'] = hKey request['lpSubKey'] = checkNullString(lpSubKey) request['dwOptions'] = dwOptions request['samDesired'] = samDesired return dce.request(request) def hBaseRegQueryInfoKey(dce, hKey): request = BaseRegQueryInfoKey() request['hKey'] = hKey # Not the cleanest way, but oh well # Plus, Windows XP needs MaximumCount also set request.fields['lpClassIn'].fields['MaximumLength'] = 1024 request.fields['lpClassIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = 1024//2 return dce.request(request) def hBaseRegQueryValue(dce, hKey, lpValueName, dataLen=512): request = BaseRegQueryValue() request['hKey'] = hKey request['lpValueName'] = checkNullString(lpValueName) retries = 1 # We need to be aware the size might not be enough, so let's catch ERROR_MORE_DATA exception while True: try: request['lpData'] =b' ' * dataLen request['lpcbData'] = dataLen request['lpcbLen'] = dataLen resp = dce.request(request) except DCERPCSessionError as e: if retries > 1: LOG.debug('Too many retries when calling hBaseRegQueryValue, aborting') raise if e.get_error_code() == system_errors.ERROR_MORE_DATA: # We need to adjust the size dataLen = e.get_packet()['lpcbData'] continue else: raise else: break # Returns # ( dataType, data ) return resp['lpType'], unpackValue(resp['lpType'], resp['lpData']) def hBaseRegReplaceKey(dce, hKey, lpSubKey, lpNewFile, lpOldFile): request = BaseRegReplaceKey() request['hKey'] = hKey request['lpSubKey'] = checkNullString(lpSubKey) request['lpNewFile'] = checkNullString(lpNewFile) request['lpOldFile'] = checkNullString(lpOldFile) return dce.request(request) def hBaseRegRestoreKey(dce, hKey, lpFile, flags=REG_REFRESH_HIVE): request = BaseRegRestoreKey() request['hKey'] = hKey request['lpFile'] = checkNullString(lpFile) request['Flags'] = flags return dce.request(request) def hBaseRegSaveKey(dce, hKey, lpFile, pSecurityAttributes = NULL): request = BaseRegSaveKey() request['hKey'] = hKey request['lpFile'] = checkNullString(lpFile) request['pSecurityAttributes'] = pSecurityAttributes return dce.request(request) def hBaseRegSetValue(dce, hKey, lpValueName, dwType, lpData): request = BaseRegSetValue() request['hKey'] = hKey request['lpValueName'] = checkNullString(lpValueName) request['dwType'] = dwType request['lpData'] = packValue(dwType,lpData) request['cbData'] = len(request['lpData']) return dce.request(request) def hBaseRegGetVersion(dce, hKey): request = BaseRegGetVersion() request['hKey'] = hKey return dce.request(request) def hOpenCurrentConfig(dce, samDesired = MAXIMUM_ALLOWED): request = OpenCurrentConfig() request['ServerName'] = NULL request['samDesired'] = samDesired return dce.request(request) def hBaseRegQueryMultipleValues(dce, hKey, val_listIn): # ToDo, check the result to see whether we need to # have a bigger buffer for the data to receive request = BaseRegQueryMultipleValues() request['hKey'] = hKey for item in val_listIn: itemn = RVALENT() itemn['ve_valuename'] = checkNullString(item['ValueName']) itemn['ve_valuelen'] = len(itemn['ve_valuename']) itemn['ve_valueptr'] = NULL itemn['ve_type'] = item['ValueType'] request['val_listIn'].append(itemn) request['num_vals'] = len(request['val_listIn']) request['lpvalueBuf'] = list(b' '*128) request['ldwTotsize'] = 128 resp = dce.request(request) retVal = list() for item in resp['val_listOut']: itemn = dict() itemn['ValueName'] = item['ve_valuename'] itemn['ValueData'] = unpackValue(item['ve_type'], resp['lpvalueBuf'][item['ve_valueptr'] : item['ve_valueptr']+item['ve_valuelen']]) retVal.append(itemn) return retVal def hBaseRegSaveKeyEx(dce, hKey, lpFile, pSecurityAttributes = NULL, flags=1): request = BaseRegSaveKeyEx() request['hKey'] = hKey request['lpFile'] = checkNullString(lpFile) request['pSecurityAttributes'] = pSecurityAttributes request['Flags'] = flags return dce.request(request) def hOpenPerformanceText(dce, samDesired = MAXIMUM_ALLOWED): request = OpenPerformanceText() request['ServerName'] = NULL request['samDesired'] = samDesired return dce.request(request) def hOpenPerformanceNlsText(dce, samDesired = MAXIMUM_ALLOWED): request = OpenPerformanceNlsText() request['ServerName'] = NULL request['samDesired'] = samDesired return dce.request(request) def hBaseRegDeleteValue(dce, hKey, lpValueName): request = BaseRegDeleteValue() request['hKey'] = hKey request['lpValueName'] = checkNullString(lpValueName) return dce.request(request)