Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/rrp.py : 87%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Impacket - Collection of Python classes for working with network protocols.
2#
3# SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved.
4#
5# This software is provided under a slightly modified version
6# of the Apache Software License. See the accompanying LICENSE file
7# for more information.
8#
9# Description:
10# [MS-RRP] Interface implementation
11#
12# Best way to learn how to use these calls is to grab the protocol standard
13# so you understand what the call does, and then read the test case located
14# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC
15#
16# Some calls have helper functions, which makes it even easier to use.
17# They are located at the end of this file.
18# Helper functions start with "h"<name of the call>.
19# There are test cases for them too.
20#
21# Author:
22# Alberto Solino (@agsolino)
23#
26from struct import unpack, pack
28from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantVaryingArray, NDRUniConformantArray
29from impacket.dcerpc.v5.dtypes import DWORD, UUID, ULONG, LPULONG, BOOLEAN, SECURITY_INFORMATION, PFILETIME, \
30 RPC_UNICODE_STRING, FILETIME, NULL, MAXIMUM_ALLOWED, OWNER_SECURITY_INFORMATION, PWCHAR, PRPC_UNICODE_STRING
31from impacket.dcerpc.v5.rpcrt import DCERPCException
32from impacket import system_errors, LOG
33from impacket.uuid import uuidtup_to_bin
35MSRPC_UUID_RRP = uuidtup_to_bin(('338CD001-2244-31F1-AAAA-900038001003', '1.0'))
37class DCERPCSessionError(DCERPCException):
38 def __init__(self, error_string=None, error_code=None, packet=None):
39 DCERPCException.__init__(self, error_string, error_code, packet)
41 def __str__( self ):
42 key = self.error_code
43 if key in system_errors.ERROR_MESSAGES: 43 ↛ 48line 43 didn't jump to line 48, because the condition on line 43 was never false
44 error_msg_short = system_errors.ERROR_MESSAGES[key][0]
45 error_msg_verbose = system_errors.ERROR_MESSAGES[key][1]
46 return 'RRP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
47 else:
48 return 'RRP SessionError: unknown error code: 0x%x' % self.error_code
50################################################################################
51# CONSTANTS
52################################################################################
53# 2.2.2 PREGISTRY_SERVER_NAME
54PREGISTRY_SERVER_NAME = PWCHAR
56# 2.2.3 error_status_t
57error_status_t = ULONG
59# 2.2.5 RRP_UNICODE_STRING
60RRP_UNICODE_STRING = RPC_UNICODE_STRING
61PRRP_UNICODE_STRING = PRPC_UNICODE_STRING
63# 2.2.4 REGSAM
64REGSAM = ULONG
66KEY_QUERY_VALUE = 0x00000001
67KEY_SET_VALUE = 0x00000002
68KEY_CREATE_SUB_KEY = 0x00000004
69KEY_ENUMERATE_SUB_KEYS = 0x00000008
70KEY_CREATE_LINK = 0x00000020
71KEY_WOW64_64KEY = 0x00000100
72KEY_WOW64_32KEY = 0x00000200
74REG_BINARY = 3
75REG_DWORD = 4
76REG_DWORD_LITTLE_ENDIAN = 4
77REG_DWORD_BIG_ENDIAN = 5
78REG_EXPAND_SZ = 2
79REG_LINK = 6
80REG_MULTI_SZ = 7
81REG_NONE = 0
82REG_QWORD = 11
83REG_QWORD_LITTLE_ENDIAN = 11
84REG_SZ = 1
86# 3.1.5.7 BaseRegCreateKey (Opnum 6)
87REG_CREATED_NEW_KEY = 0x00000001
88REG_OPENED_EXISTING_KEY = 0x00000002
90# 3.1.5.19 BaseRegRestoreKey (Opnum 19)
91# Flags
92REG_WHOLE_HIVE_VOLATILE = 0x00000001
93REG_REFRESH_HIVE = 0x00000002
94REG_NO_LAZY_FLUSH = 0x00000004
95REG_FORCE_RESTORE = 0x00000008
97################################################################################
98# STRUCTURES
99################################################################################
100# 2.2.1 RPC_HKEY
101class RPC_HKEY(NDRSTRUCT):
102 structure = (
103 ('context_handle_attributes',ULONG),
104 ('context_handle_uuid',UUID),
105 )
107 def __init__(self, data=None, isNDR64=False):
108 NDRSTRUCT.__init__(self, data, isNDR64)
109 self['context_handle_uuid'] = b'\x00'*16
111 def isNull(self):
112 return self['context_handle_uuid'] == b'\x00'*16
114# 2.2.6 RVALENT
115class RVALENT(NDRSTRUCT):
116 structure = (
117 ('ve_valuename',PRRP_UNICODE_STRING),
118 ('ve_valuelen',DWORD),
119 ('ve_valueptr',DWORD),
120 ('ve_type',DWORD),
121 )
123class RVALENT_ARRAY(NDRUniConformantVaryingArray):
124 item = RVALENT
126# 2.2.9 RPC_SECURITY_DESCRIPTOR
127class BYTE_ARRAY(NDRUniConformantVaryingArray):
128 pass
130class PBYTE_ARRAY(NDRPOINTER):
131 referent = (
132 ('Data', BYTE_ARRAY),
133 )
135class RPC_SECURITY_DESCRIPTOR(NDRSTRUCT):
136 structure = (
137 ('lpSecurityDescriptor',PBYTE_ARRAY),
138 ('cbInSecurityDescriptor',DWORD),
139 ('cbOutSecurityDescriptor',DWORD),
140 )
142# 2.2.8 RPC_SECURITY_ATTRIBUTES
143class RPC_SECURITY_ATTRIBUTES(NDRSTRUCT):
144 structure = (
145 ('nLength',DWORD),
146 ('RpcSecurityDescriptor',RPC_SECURITY_DESCRIPTOR),
147 ('bInheritHandle',BOOLEAN),
148 )
150class PRPC_SECURITY_ATTRIBUTES(NDRPOINTER):
151 referent = (
152 ('Data', RPC_SECURITY_ATTRIBUTES),
153 )
155################################################################################
156# RPC CALLS
157################################################################################
158# 3.1.5.1 OpenClassesRoot (Opnum 0)
159class OpenClassesRoot(NDRCALL):
160 opnum = 0
161 structure = (
162 ('ServerName', PREGISTRY_SERVER_NAME),
163 ('samDesired', REGSAM),
164 )
166class OpenClassesRootResponse(NDRCALL):
167 structure = (
168 ('phKey', RPC_HKEY),
169 ('ErrorCode', error_status_t),
170 )
172# 3.1.5.2 OpenCurrentUser (Opnum 1)
173class OpenCurrentUser(NDRCALL):
174 opnum = 1
175 structure = (
176 ('ServerName', PREGISTRY_SERVER_NAME),
177 ('samDesired', REGSAM),
178 )
180class OpenCurrentUserResponse(NDRCALL):
181 structure = (
182 ('phKey', RPC_HKEY),
183 ('ErrorCode', error_status_t),
184 )
186# 3.1.5.3 OpenLocalMachine (Opnum 2)
187class OpenLocalMachine(NDRCALL):
188 opnum = 2
189 structure = (
190 ('ServerName', PREGISTRY_SERVER_NAME),
191 ('samDesired', REGSAM),
192 )
194class OpenLocalMachineResponse(NDRCALL):
195 structure = (
196 ('phKey', RPC_HKEY),
197 ('ErrorCode', error_status_t),
198 )
200# 3.1.5.4 OpenPerformanceData (Opnum 3)
201class OpenPerformanceData(NDRCALL):
202 opnum = 3
203 structure = (
204 ('ServerName', PREGISTRY_SERVER_NAME),
205 ('samDesired', REGSAM),
206 )
208class OpenPerformanceDataResponse(NDRCALL):
209 structure = (
210 ('phKey', RPC_HKEY),
211 ('ErrorCode', error_status_t),
212 )
214# 3.1.5.5 OpenUsers (Opnum 4)
215class OpenUsers(NDRCALL):
216 opnum = 4
217 structure = (
218 ('ServerName', PREGISTRY_SERVER_NAME),
219 ('samDesired', REGSAM),
220 )
222class OpenUsersResponse(NDRCALL):
223 structure = (
224 ('phKey', RPC_HKEY),
225 ('ErrorCode', error_status_t),
226 )
228# 3.1.5.6 BaseRegCloseKey (Opnum 5)
229class BaseRegCloseKey(NDRCALL):
230 opnum = 5
231 structure = (
232 ('hKey', RPC_HKEY),
233 )
235class BaseRegCloseKeyResponse(NDRCALL):
236 structure = (
237 ('hKey', RPC_HKEY),
238 ('ErrorCode', error_status_t),
239 )
241# 3.1.5.7 BaseRegCreateKey (Opnum 6)
242class BaseRegCreateKey(NDRCALL):
243 opnum = 6
244 structure = (
245 ('hKey', RPC_HKEY),
246 ('lpSubKey', RRP_UNICODE_STRING),
247 ('lpClass', RRP_UNICODE_STRING),
248 ('dwOptions', DWORD),
249 ('samDesired', REGSAM),
250 ('lpSecurityAttributes', PRPC_SECURITY_ATTRIBUTES),
251 ('lpdwDisposition', LPULONG),
252 )
254class BaseRegCreateKeyResponse(NDRCALL):
255 structure = (
256 ('phkResult', RPC_HKEY),
257 ('lpdwDisposition', LPULONG),
258 ('ErrorCode', error_status_t),
259 )
261# 3.1.5.8 BaseRegDeleteKey (Opnum 7)
262class BaseRegDeleteKey(NDRCALL):
263 opnum = 7
264 structure = (
265 ('hKey', RPC_HKEY),
266 ('lpSubKey', RRP_UNICODE_STRING),
267 )
269class BaseRegDeleteKeyResponse(NDRCALL):
270 structure = (
271 ('ErrorCode', error_status_t),
272 )
274# 3.1.5.9 BaseRegDeleteValue (Opnum 8)
275class BaseRegDeleteValue(NDRCALL):
276 opnum = 8
277 structure = (
278 ('hKey', RPC_HKEY),
279 ('lpValueName', RRP_UNICODE_STRING),
280 )
282class BaseRegDeleteValueResponse(NDRCALL):
283 structure = (
284 ('ErrorCode', error_status_t),
285 )
287# 3.1.5.10 BaseRegEnumKey (Opnum 9)
288class BaseRegEnumKey(NDRCALL):
289 opnum = 9
290 structure = (
291 ('hKey', RPC_HKEY),
292 ('dwIndex', DWORD),
293 ('lpNameIn', RRP_UNICODE_STRING),
294 ('lpClassIn', PRRP_UNICODE_STRING),
295 ('lpftLastWriteTime', PFILETIME),
296 )
298class BaseRegEnumKeyResponse(NDRCALL):
299 structure = (
300 ('lpNameOut', RRP_UNICODE_STRING),
301 ('lplpClassOut', PRRP_UNICODE_STRING),
302 ('lpftLastWriteTime', PFILETIME),
303 ('ErrorCode', error_status_t),
304 )
306# 3.1.5.11 BaseRegEnumValue (Opnum 10)
307class BaseRegEnumValue(NDRCALL):
308 opnum = 10
309 structure = (
310 ('hKey', RPC_HKEY),
311 ('dwIndex', DWORD),
312 ('lpValueNameIn', RRP_UNICODE_STRING),
313 ('lpType', LPULONG),
314 ('lpData', PBYTE_ARRAY),
315 ('lpcbData', LPULONG),
316 ('lpcbLen', LPULONG),
317 )
319class BaseRegEnumValueResponse(NDRCALL):
320 structure = (
321 ('lpValueNameOut', RRP_UNICODE_STRING),
322 ('lpType', LPULONG),
323 ('lpData', PBYTE_ARRAY),
324 ('lpcbData', LPULONG),
325 ('lpcbLen', LPULONG),
326 ('ErrorCode', error_status_t),
327 )
329# 3.1.5.12 BaseRegFlushKey (Opnum 11)
330class BaseRegFlushKey(NDRCALL):
331 opnum = 11
332 structure = (
333 ('hKey', RPC_HKEY),
334 )
336class BaseRegFlushKeyResponse(NDRCALL):
337 structure = (
338 ('ErrorCode', error_status_t),
339 )
341# 3.1.5.13 BaseRegGetKeySecurity (Opnum 12)
342class BaseRegGetKeySecurity(NDRCALL):
343 opnum = 12
344 structure = (
345 ('hKey', RPC_HKEY),
346 ('SecurityInformation', SECURITY_INFORMATION),
347 ('pRpcSecurityDescriptorIn', RPC_SECURITY_DESCRIPTOR),
348 )
350class BaseRegGetKeySecurityResponse(NDRCALL):
351 structure = (
352 ('pRpcSecurityDescriptorOut', RPC_SECURITY_DESCRIPTOR),
353 ('ErrorCode', error_status_t),
354 )
356# 3.1.5.14 BaseRegLoadKey (Opnum 13)
357class BaseRegLoadKey(NDRCALL):
358 opnum = 13
359 structure = (
360 ('hKey', RPC_HKEY),
361 ('lpSubKey', RRP_UNICODE_STRING),
362 ('lpFile', RRP_UNICODE_STRING),
363 )
365class BaseRegLoadKeyResponse(NDRCALL):
366 structure = (
367 ('ErrorCode', error_status_t),
368 )
370# 3.1.5.15 BaseRegOpenKey (Opnum 15)
371class BaseRegOpenKey(NDRCALL):
372 opnum = 15
373 structure = (
374 ('hKey', RPC_HKEY),
375 ('lpSubKey', RRP_UNICODE_STRING),
376 ('dwOptions', DWORD),
377 ('samDesired', REGSAM),
378 )
380class BaseRegOpenKeyResponse(NDRCALL):
381 structure = (
382 ('phkResult', RPC_HKEY),
383 ('ErrorCode', error_status_t),
384 )
386# 3.1.5.16 BaseRegQueryInfoKey (Opnum 16)
387class BaseRegQueryInfoKey(NDRCALL):
388 opnum = 16
389 structure = (
390 ('hKey', RPC_HKEY),
391 ('lpClassIn', RRP_UNICODE_STRING),
392 )
394class BaseRegQueryInfoKeyResponse(NDRCALL):
395 structure = (
396 ('lpClassOut', RPC_UNICODE_STRING),
397 ('lpcSubKeys', DWORD),
398 ('lpcbMaxSubKeyLen', DWORD),
399 ('lpcbMaxClassLen', DWORD),
400 ('lpcValues', DWORD),
401 ('lpcbMaxValueNameLen', DWORD),
402 ('lpcbMaxValueLen', DWORD),
403 ('lpcbSecurityDescriptor', DWORD),
404 ('lpftLastWriteTime', FILETIME),
405 ('ErrorCode', error_status_t),
406 )
408# 3.1.5.17 BaseRegQueryValue (Opnum 17)
409class BaseRegQueryValue(NDRCALL):
410 opnum = 17
411 structure = (
412 ('hKey', RPC_HKEY),
413 ('lpValueName', RRP_UNICODE_STRING),
414 ('lpType', LPULONG),
415 ('lpData', PBYTE_ARRAY),
416 ('lpcbData', LPULONG),
417 ('lpcbLen', LPULONG),
418 )
420class BaseRegQueryValueResponse(NDRCALL):
421 structure = (
422 ('lpType', LPULONG),
423 ('lpData', PBYTE_ARRAY),
424 ('lpcbData', LPULONG),
425 ('lpcbLen', LPULONG),
426 ('ErrorCode', error_status_t),
427 )
429# 3.1.5.18 BaseRegReplaceKey (Opnum 18)
430class BaseRegReplaceKey(NDRCALL):
431 opnum = 18
432 structure = (
433 ('hKey', RPC_HKEY),
434 ('lpSubKey', RRP_UNICODE_STRING),
435 ('lpNewFile', RRP_UNICODE_STRING),
436 ('lpOldFile', RRP_UNICODE_STRING),
437 )
439class BaseRegReplaceKeyResponse(NDRCALL):
440 structure = (
441 ('ErrorCode', error_status_t),
442 )
444# 3.1.5.19 BaseRegRestoreKey (Opnum 19)
445class BaseRegRestoreKey(NDRCALL):
446 opnum = 19
447 structure = (
448 ('hKey', RPC_HKEY),
449 ('lpFile', RRP_UNICODE_STRING),
450 ('Flags', DWORD),
451 )
453class BaseRegRestoreKeyResponse(NDRCALL):
454 structure = (
455 ('ErrorCode', error_status_t),
456 )
458# 3.1.5.20 BaseRegSaveKey (Opnum 20)
459class BaseRegSaveKey(NDRCALL):
460 opnum = 20
461 structure = (
462 ('hKey', RPC_HKEY),
463 ('lpFile', RRP_UNICODE_STRING),
464 ('pSecurityAttributes', PRPC_SECURITY_ATTRIBUTES),
465 )
467class BaseRegSaveKeyResponse(NDRCALL):
468 structure = (
469 ('ErrorCode', error_status_t),
470 )
472# 3.1.5.21 BaseRegSetKeySecurity (Opnum 21)
473class BaseRegSetKeySecurity(NDRCALL):
474 opnum = 21
475 structure = (
476 ('hKey', RPC_HKEY),
477 ('SecurityInformation', SECURITY_INFORMATION),
478 ('pRpcSecurityDescriptor', RPC_SECURITY_DESCRIPTOR),
479 )
481class BaseRegSetKeySecurityResponse(NDRCALL):
482 structure = (
483 ('ErrorCode', error_status_t),
484 )
486# 3.1.5.22 BaseRegSetValue (Opnum 22)
487class BaseRegSetValue(NDRCALL):
488 opnum = 22
489 structure = (
490 ('hKey', RPC_HKEY),
491 ('lpValueName', RRP_UNICODE_STRING),
492 ('dwType', DWORD),
493 ('lpData', NDRUniConformantArray),
494 ('cbData', DWORD),
495 )
497class BaseRegSetValueResponse(NDRCALL):
498 structure = (
499 ('ErrorCode', error_status_t),
500 )
502# 3.1.5.23 BaseRegUnLoadKey (Opnum 23)
503class BaseRegUnLoadKey(NDRCALL):
504 opnum = 23
505 structure = (
506 ('hKey', RPC_HKEY),
507 ('lpSubKey', RRP_UNICODE_STRING),
508 )
510class BaseRegUnLoadKeyResponse(NDRCALL):
511 structure = (
512 ('ErrorCode', error_status_t),
513 )
515# 3.1.5.24 BaseRegGetVersion (Opnum 26)
516class BaseRegGetVersion(NDRCALL):
517 opnum = 26
518 structure = (
519 ('hKey', RPC_HKEY),
520 )
522class BaseRegGetVersionResponse(NDRCALL):
523 structure = (
524 ('lpdwVersion', DWORD),
525 ('ErrorCode', error_status_t),
526 )
528# 3.1.5.25 OpenCurrentConfig (Opnum 27)
529class OpenCurrentConfig(NDRCALL):
530 opnum = 27
531 structure = (
532 ('ServerName', PREGISTRY_SERVER_NAME),
533 ('samDesired', REGSAM),
534 )
536class OpenCurrentConfigResponse(NDRCALL):
537 structure = (
538 ('phKey', RPC_HKEY),
539 ('ErrorCode', error_status_t),
540 )
542# 3.1.5.26 BaseRegQueryMultipleValues (Opnum 29)
543class BaseRegQueryMultipleValues(NDRCALL):
544 opnum = 29
545 structure = (
546 ('hKey', RPC_HKEY),
547 ('val_listIn', RVALENT_ARRAY),
548 ('num_vals', DWORD),
549 ('lpvalueBuf', PBYTE_ARRAY),
550 ('ldwTotsize', DWORD),
551 )
553class BaseRegQueryMultipleValuesResponse(NDRCALL):
554 structure = (
555 ('val_listOut', RVALENT_ARRAY),
556 ('lpvalueBuf', PBYTE_ARRAY),
557 ('ldwTotsize', DWORD),
558 ('ErrorCode', error_status_t),
559 )
561# 3.1.5.27 BaseRegSaveKeyEx (Opnum 31)
562class BaseRegSaveKeyEx(NDRCALL):
563 opnum = 31
564 structure = (
565 ('hKey', RPC_HKEY),
566 ('lpFile', RRP_UNICODE_STRING),
567 ('pSecurityAttributes', PRPC_SECURITY_ATTRIBUTES),
568 ('Flags', DWORD),
569 )
571class BaseRegSaveKeyExResponse(NDRCALL):
572 structure = (
573 ('ErrorCode', error_status_t),
574 )
576# 3.1.5.28 OpenPerformanceText (Opnum 32)
577class OpenPerformanceText(NDRCALL):
578 opnum = 32
579 structure = (
580 ('ServerName', PREGISTRY_SERVER_NAME),
581 ('samDesired', REGSAM),
582 )
584class OpenPerformanceTextResponse(NDRCALL):
585 structure = (
586 ('phKey', RPC_HKEY),
587 ('ErrorCode', error_status_t),
588 )
590# 3.1.5.29 OpenPerformanceNlsText (Opnum 33)
591class OpenPerformanceNlsText(NDRCALL):
592 opnum = 33
593 structure = (
594 ('ServerName', PREGISTRY_SERVER_NAME),
595 ('samDesired', REGSAM),
596 )
598class OpenPerformanceNlsTextResponse(NDRCALL):
599 structure = (
600 ('phKey', RPC_HKEY),
601 ('ErrorCode', error_status_t),
602 )
604# 3.1.5.30 BaseRegQueryMultipleValues2 (Opnum 34)
605class BaseRegQueryMultipleValues2(NDRCALL):
606 opnum = 34
607 structure = (
608 ('hKey', RPC_HKEY),
609 ('val_listIn', RVALENT_ARRAY),
610 ('num_vals', DWORD),
611 ('lpvalueBuf', PBYTE_ARRAY),
612 ('ldwTotsize', DWORD),
613 )
615class BaseRegQueryMultipleValues2Response(NDRCALL):
616 structure = (
617 ('val_listOut', RVALENT_ARRAY),
618 ('lpvalueBuf', PBYTE_ARRAY),
619 ('ldwRequiredSize', DWORD),
620 ('ErrorCode', error_status_t),
621 )
623# 3.1.5.31 BaseRegDeleteKeyEx (Opnum 35)
624class BaseRegDeleteKeyEx(NDRCALL):
625 opnum = 35
626 structure = (
627 ('hKey', RPC_HKEY),
628 ('lpSubKey', RRP_UNICODE_STRING),
629 ('AccessMask', REGSAM),
630 ('Reserved', DWORD),
631 )
633class BaseRegDeleteKeyExResponse(NDRCALL):
634 structure = (
635 ('ErrorCode', error_status_t),
636 )
638################################################################################
639# OPNUMs and their corresponding structures
640################################################################################
641OPNUMS = {
642 0 : (OpenClassesRoot, OpenClassesRootResponse),
643 1 : (OpenCurrentUser, OpenCurrentUserResponse),
644 2 : (OpenLocalMachine, OpenLocalMachineResponse),
645 3 : (OpenPerformanceData, OpenPerformanceDataResponse),
646 4 : (OpenUsers, OpenUsersResponse),
647 5 : (BaseRegCloseKey, BaseRegCloseKeyResponse),
648 6 : (BaseRegCreateKey, BaseRegCreateKeyResponse),
649 7 : (BaseRegDeleteKey, BaseRegDeleteKeyResponse),
650 8 : (BaseRegDeleteValue, BaseRegDeleteValueResponse),
651 9 : (BaseRegEnumKey, BaseRegEnumKeyResponse),
65210 : (BaseRegEnumValue, BaseRegEnumValueResponse),
65311 : (BaseRegFlushKey, BaseRegFlushKeyResponse),
65412 : (BaseRegGetKeySecurity, BaseRegGetKeySecurityResponse),
65513 : (BaseRegLoadKey, BaseRegLoadKeyResponse),
65615 : (BaseRegOpenKey, BaseRegOpenKeyResponse),
65716 : (BaseRegQueryInfoKey, BaseRegQueryInfoKeyResponse),
65817 : (BaseRegQueryValue, BaseRegQueryValueResponse),
65918 : (BaseRegReplaceKey, BaseRegReplaceKeyResponse),
66019 : (BaseRegRestoreKey, BaseRegRestoreKeyResponse),
66120 : (BaseRegSaveKey, BaseRegSaveKeyResponse),
66221 : (BaseRegSetKeySecurity, BaseRegSetKeySecurityResponse),
66322 : (BaseRegSetValue, BaseRegSetValueResponse),
66423 : (BaseRegUnLoadKey, BaseRegUnLoadKeyResponse),
66526 : (BaseRegGetVersion, BaseRegGetVersionResponse),
66627 : (OpenCurrentConfig, OpenCurrentConfigResponse),
66729 : (BaseRegQueryMultipleValues, BaseRegQueryMultipleValuesResponse),
66831 : (BaseRegSaveKeyEx, BaseRegSaveKeyExResponse),
66932 : (OpenPerformanceText, OpenPerformanceTextResponse),
67033 : (OpenPerformanceNlsText, OpenPerformanceNlsTextResponse),
67134 : (BaseRegQueryMultipleValues2, BaseRegQueryMultipleValues2Response),
67235 : (BaseRegDeleteKeyEx, BaseRegDeleteKeyExResponse),
673}
675################################################################################
676# HELPER FUNCTIONS
677################################################################################
678def checkNullString(string):
679 if string == NULL:
680 return string
682 if string[-1:] != '\x00':
683 return string + '\x00'
684 else:
685 return string
687def packValue(valueType, value):
688 if valueType == REG_DWORD: 688 ↛ 689line 688 didn't jump to line 689, because the condition on line 688 was never true
689 retData = pack('<L', value)
690 elif valueType == REG_DWORD_BIG_ENDIAN: 690 ↛ 691line 690 didn't jump to line 691, because the condition on line 690 was never true
691 retData = pack('>L', value)
692 elif valueType == REG_EXPAND_SZ: 692 ↛ 693line 692 didn't jump to line 693, because the condition on line 692 was never true
693 try:
694 retData = value.encode('utf-16le')
695 except UnicodeDecodeError:
696 import sys
697 retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le')
698 elif valueType == REG_MULTI_SZ: 698 ↛ 699line 698 didn't jump to line 699, because the condition on line 698 was never true
699 try:
700 retData = value.encode('utf-16le')
701 except UnicodeDecodeError:
702 import sys
703 retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le')
704 elif valueType == REG_QWORD: 704 ↛ 705line 704 didn't jump to line 705, because the condition on line 704 was never true
705 retData = pack('<Q', value)
706 elif valueType == REG_QWORD_LITTLE_ENDIAN: 706 ↛ 707line 706 didn't jump to line 707, because the condition on line 706 was never true
707 retData = pack('>Q', value)
708 elif valueType == REG_SZ: 708 ↛ 715line 708 didn't jump to line 715, because the condition on line 708 was never false
709 try:
710 retData = value.encode('utf-16le')
711 except UnicodeDecodeError:
712 import sys
713 retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le')
714 else:
715 retData = value
717 return retData
719def unpackValue(valueType, value):
720 if valueType == REG_DWORD:
721 retData = unpack('<L', b''.join(value))[0]
722 elif valueType == REG_DWORD_BIG_ENDIAN: 722 ↛ 723line 722 didn't jump to line 723, because the condition on line 722 was never true
723 retData = unpack('>L', b''.join(value))[0]
724 elif valueType == REG_EXPAND_SZ: 724 ↛ 725line 724 didn't jump to line 725, because the condition on line 724 was never true
725 retData = b''.join(value).decode('utf-16le')
726 elif valueType == REG_MULTI_SZ: 726 ↛ 727line 726 didn't jump to line 727, because the condition on line 726 was never true
727 retData = b''.join(value).decode('utf-16le')
728 elif valueType == REG_QWORD: 728 ↛ 729line 728 didn't jump to line 729, because the condition on line 728 was never true
729 retData = unpack('<Q', b''.join(value))[0]
730 elif valueType == REG_QWORD_LITTLE_ENDIAN: 730 ↛ 731line 730 didn't jump to line 731, because the condition on line 730 was never true
731 retData = unpack('>Q', b''.join(value))[0]
732 elif valueType == REG_SZ: 732 ↛ 735line 732 didn't jump to line 735, because the condition on line 732 was never false
733 retData = b''.join(value).decode('utf-16le')
734 else:
735 retData = b''.join(value)
737 return retData
739def hOpenClassesRoot(dce, samDesired = MAXIMUM_ALLOWED):
740 request = OpenClassesRoot()
741 request['ServerName'] = NULL
742 request['samDesired'] = samDesired
743 return dce.request(request)
745def hOpenCurrentUser(dce, samDesired = MAXIMUM_ALLOWED):
746 request = OpenCurrentUser()
747 request['ServerName'] = NULL
748 request['samDesired'] = samDesired
749 return dce.request(request)
751def hOpenLocalMachine(dce, samDesired = MAXIMUM_ALLOWED):
752 request = OpenLocalMachine()
753 request['ServerName'] = NULL
754 request['samDesired'] = samDesired
755 return dce.request(request)
757def hOpenPerformanceData(dce, samDesired = MAXIMUM_ALLOWED):
758 request = OpenPerformanceData()
759 request['ServerName'] = NULL
760 request['samDesired'] = samDesired
761 return dce.request(request)
763def hOpenUsers(dce, samDesired = MAXIMUM_ALLOWED):
764 request = OpenUsers()
765 request['ServerName'] = NULL
766 request['samDesired'] = samDesired
767 return dce.request(request)
769def hBaseRegCloseKey(dce, hKey):
770 request = BaseRegCloseKey()
771 request['hKey'] = hKey
772 return dce.request(request)
774def hBaseRegCreateKey(dce, hKey, lpSubKey, lpClass = NULL, dwOptions = 0x00000001, samDesired = MAXIMUM_ALLOWED, lpSecurityAttributes = NULL, lpdwDisposition = REG_CREATED_NEW_KEY):
775 request = BaseRegCreateKey()
776 request['hKey'] = hKey
777 request['lpSubKey'] = checkNullString(lpSubKey)
778 request['lpClass'] = checkNullString(lpClass)
779 request['dwOptions'] = dwOptions
780 request['samDesired'] = samDesired
781 if lpSecurityAttributes == NULL: 781 ↛ 784line 781 didn't jump to line 784, because the condition on line 781 was never false
782 request['lpSecurityAttributes']['RpcSecurityDescriptor']['lpSecurityDescriptor'] = NULL
783 else:
784 request['lpSecurityAttributes'] = lpSecurityAttributes
785 request['lpdwDisposition'] = lpdwDisposition
787 return dce.request(request)
789def hBaseRegDeleteKey(dce, hKey, lpSubKey):
790 request = BaseRegDeleteKey()
791 request['hKey'] = hKey
792 request['lpSubKey'] = checkNullString(lpSubKey)
793 return dce.request(request)
795def hBaseRegEnumKey(dce, hKey, dwIndex, lpftLastWriteTime = NULL):
796 request = BaseRegEnumKey()
797 request['hKey'] = hKey
798 request['dwIndex'] = dwIndex
799 request.fields['lpNameIn'].fields['MaximumLength'] = 1024
800 request.fields['lpNameIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = 1024//2
801 request['lpClassIn'] = ' '* 64
802 request['lpftLastWriteTime'] = lpftLastWriteTime
804 return dce.request(request)
806def hBaseRegEnumValue(dce, hKey, dwIndex, dataLen=256):
807 request = BaseRegEnumValue()
808 request['hKey'] = hKey
809 request['dwIndex'] = dwIndex
810 retries = 1
812 # We need to be aware the size might not be enough, so let's catch ERROR_MORE_DATA exception
813 while True:
814 try:
815 # Only the maximum length field of the lpValueNameIn is used to determine the buffer length to be allocated
816 # by the service. Specify a string with a zero length but maximum length set to the largest buffer size
817 # needed to hold the value names.
818 request.fields['lpValueNameIn'].fields['MaximumLength'] = dataLen*2
819 request.fields['lpValueNameIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = dataLen
821 request['lpData'] = b' ' * dataLen
822 request['lpcbData'] = dataLen
823 request['lpcbLen'] = dataLen
824 resp = dce.request(request)
825 except DCERPCSessionError as e:
826 if retries > 1: 826 ↛ 827line 826 didn't jump to line 827, because the condition on line 826 was never true
827 LOG.debug('Too many retries when calling hBaseRegEnumValue, aborting')
828 raise
829 if e.get_error_code() == system_errors.ERROR_MORE_DATA: 829 ↛ 835line 829 didn't jump to line 835, because the condition on line 829 was never false
830 # We need to adjust the size
831 retries +=1
832 dataLen = e.get_packet()['lpcbData']
833 continue
834 else:
835 raise
836 else:
837 break
839 return resp
841def hBaseRegFlushKey(dce, hKey):
842 request = BaseRegFlushKey()
843 request['hKey'] = hKey
844 return dce.request(request)
846def hBaseRegGetKeySecurity(dce, hKey, securityInformation = OWNER_SECURITY_INFORMATION ):
847 request = BaseRegGetKeySecurity()
848 request['hKey'] = hKey
849 request['SecurityInformation'] = securityInformation
850 request['pRpcSecurityDescriptorIn']['lpSecurityDescriptor'] = NULL
851 request['pRpcSecurityDescriptorIn']['cbInSecurityDescriptor'] = 1024
853 return dce.request(request)
855def hBaseRegLoadKey(dce, hKey, lpSubKey, lpFile):
856 request = BaseRegLoadKey()
857 request['hKey'] = hKey
858 request['lpSubKey'] = checkNullString(lpSubKey)
859 request['lpFile'] = checkNullString(lpFile)
860 return dce.request(request)
862def hBaseRegUnLoadKey(dce, hKey, lpSubKey):
863 request = BaseRegUnLoadKey()
864 request['hKey'] = hKey
865 request['lpSubKey'] = checkNullString(lpSubKey)
866 return dce.request(request)
868def hBaseRegOpenKey(dce, hKey, lpSubKey, dwOptions=0x00000001, samDesired = MAXIMUM_ALLOWED):
869 request = BaseRegOpenKey()
870 request['hKey'] = hKey
871 request['lpSubKey'] = checkNullString(lpSubKey)
872 request['dwOptions'] = dwOptions
873 request['samDesired'] = samDesired
874 return dce.request(request)
876def hBaseRegQueryInfoKey(dce, hKey):
877 request = BaseRegQueryInfoKey()
878 request['hKey'] = hKey
879 # Not the cleanest way, but oh well
880 # Plus, Windows XP needs MaximumCount also set
881 request.fields['lpClassIn'].fields['MaximumLength'] = 1024
882 request.fields['lpClassIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = 1024//2
883 return dce.request(request)
885def hBaseRegQueryValue(dce, hKey, lpValueName, dataLen=512):
886 request = BaseRegQueryValue()
887 request['hKey'] = hKey
888 request['lpValueName'] = checkNullString(lpValueName)
889 retries = 1
891 # We need to be aware the size might not be enough, so let's catch ERROR_MORE_DATA exception
892 while True:
893 try:
894 request['lpData'] =b' ' * dataLen
895 request['lpcbData'] = dataLen
896 request['lpcbLen'] = dataLen
897 resp = dce.request(request)
898 except DCERPCSessionError as e:
899 if retries > 1:
900 LOG.debug('Too many retries when calling hBaseRegQueryValue, aborting')
901 raise
902 if e.get_error_code() == system_errors.ERROR_MORE_DATA:
903 # We need to adjust the size
904 dataLen = e.get_packet()['lpcbData']
905 continue
906 else:
907 raise
908 else:
909 break
911 # Returns
912 # ( dataType, data )
913 return resp['lpType'], unpackValue(resp['lpType'], resp['lpData'])
915def hBaseRegReplaceKey(dce, hKey, lpSubKey, lpNewFile, lpOldFile):
916 request = BaseRegReplaceKey()
917 request['hKey'] = hKey
918 request['lpSubKey'] = checkNullString(lpSubKey)
919 request['lpNewFile'] = checkNullString(lpNewFile)
920 request['lpOldFile'] = checkNullString(lpOldFile)
921 return dce.request(request)
923def hBaseRegRestoreKey(dce, hKey, lpFile, flags=REG_REFRESH_HIVE):
924 request = BaseRegRestoreKey()
925 request['hKey'] = hKey
926 request['lpFile'] = checkNullString(lpFile)
927 request['Flags'] = flags
928 return dce.request(request)
930def hBaseRegSaveKey(dce, hKey, lpFile, pSecurityAttributes = NULL):
931 request = BaseRegSaveKey()
932 request['hKey'] = hKey
933 request['lpFile'] = checkNullString(lpFile)
934 request['pSecurityAttributes'] = pSecurityAttributes
935 return dce.request(request)
937def hBaseRegSetValue(dce, hKey, lpValueName, dwType, lpData):
938 request = BaseRegSetValue()
939 request['hKey'] = hKey
940 request['lpValueName'] = checkNullString(lpValueName)
941 request['dwType'] = dwType
942 request['lpData'] = packValue(dwType,lpData)
943 request['cbData'] = len(request['lpData'])
944 return dce.request(request)
946def hBaseRegGetVersion(dce, hKey):
947 request = BaseRegGetVersion()
948 request['hKey'] = hKey
949 return dce.request(request)
951def hOpenCurrentConfig(dce, samDesired = MAXIMUM_ALLOWED):
952 request = OpenCurrentConfig()
953 request['ServerName'] = NULL
954 request['samDesired'] = samDesired
955 return dce.request(request)
957def hBaseRegQueryMultipleValues(dce, hKey, val_listIn):
958 # ToDo, check the result to see whether we need to
959 # have a bigger buffer for the data to receive
960 request = BaseRegQueryMultipleValues()
961 request['hKey'] = hKey
963 for item in val_listIn:
964 itemn = RVALENT()
965 itemn['ve_valuename'] = checkNullString(item['ValueName'])
966 itemn['ve_valuelen'] = len(itemn['ve_valuename'])
967 itemn['ve_valueptr'] = NULL
968 itemn['ve_type'] = item['ValueType']
969 request['val_listIn'].append(itemn)
971 request['num_vals'] = len(request['val_listIn'])
972 request['lpvalueBuf'] = list(b' '*128)
973 request['ldwTotsize'] = 128
975 resp = dce.request(request)
976 retVal = list()
977 for item in resp['val_listOut']:
978 itemn = dict()
979 itemn['ValueName'] = item['ve_valuename']
980 itemn['ValueData'] = unpackValue(item['ve_type'], resp['lpvalueBuf'][item['ve_valueptr'] : item['ve_valueptr']+item['ve_valuelen']])
981 retVal.append(itemn)
983 return retVal
985def hBaseRegSaveKeyEx(dce, hKey, lpFile, pSecurityAttributes = NULL, flags=1):
986 request = BaseRegSaveKeyEx()
987 request['hKey'] = hKey
988 request['lpFile'] = checkNullString(lpFile)
989 request['pSecurityAttributes'] = pSecurityAttributes
990 request['Flags'] = flags
991 return dce.request(request)
993def hOpenPerformanceText(dce, samDesired = MAXIMUM_ALLOWED):
994 request = OpenPerformanceText()
995 request['ServerName'] = NULL
996 request['samDesired'] = samDesired
997 return dce.request(request)
999def hOpenPerformanceNlsText(dce, samDesired = MAXIMUM_ALLOWED):
1000 request = OpenPerformanceNlsText()
1001 request['ServerName'] = NULL
1002 request['samDesired'] = samDesired
1003 return dce.request(request)
1005def hBaseRegDeleteValue(dce, hKey, lpValueName):
1006 request = BaseRegDeleteValue()
1007 request['hKey'] = hKey
1008 request['lpValueName'] = checkNullString(lpValueName)
1009 return dce.request(request)