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# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
2#
3# This software is provided under under a slightly modified version
4# of the Apache Software License. See the accompanying LICENSE file
5# for more information.
6#
7# Author: Alberto Solino (@agsolino)
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#
23from struct import unpack, pack
25from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantVaryingArray, NDRUniConformantArray
26from impacket.dcerpc.v5.dtypes import DWORD, UUID, ULONG, LPULONG, BOOLEAN, SECURITY_INFORMATION, PFILETIME, \
27 RPC_UNICODE_STRING, FILETIME, NULL, MAXIMUM_ALLOWED, OWNER_SECURITY_INFORMATION, PWCHAR, PRPC_UNICODE_STRING
28from impacket.dcerpc.v5.rpcrt import DCERPCException
29from impacket import system_errors, LOG
30from impacket.uuid import uuidtup_to_bin
32MSRPC_UUID_RRP = uuidtup_to_bin(('338CD001-2244-31F1-AAAA-900038001003', '1.0'))
34class DCERPCSessionError(DCERPCException):
35 def __init__(self, error_string=None, error_code=None, packet=None):
36 DCERPCException.__init__(self, error_string, error_code, packet)
38 def __str__( self ):
39 key = self.error_code
40 if key in system_errors.ERROR_MESSAGES: 40 ↛ 45line 40 didn't jump to line 45, because the condition on line 40 was never false
41 error_msg_short = system_errors.ERROR_MESSAGES[key][0]
42 error_msg_verbose = system_errors.ERROR_MESSAGES[key][1]
43 return 'RRP SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
44 else:
45 return 'RRP SessionError: unknown error code: 0x%x' % self.error_code
47################################################################################
48# CONSTANTS
49################################################################################
50# 2.2.2 PREGISTRY_SERVER_NAME
51PREGISTRY_SERVER_NAME = PWCHAR
53# 2.2.3 error_status_t
54error_status_t = ULONG
56# 2.2.5 RRP_UNICODE_STRING
57RRP_UNICODE_STRING = RPC_UNICODE_STRING
58PRRP_UNICODE_STRING = PRPC_UNICODE_STRING
60# 2.2.4 REGSAM
61REGSAM = ULONG
63KEY_QUERY_VALUE = 0x00000001
64KEY_SET_VALUE = 0x00000002
65KEY_CREATE_SUB_KEY = 0x00000004
66KEY_ENUMERATE_SUB_KEYS = 0x00000008
67KEY_CREATE_LINK = 0x00000020
68KEY_WOW64_64KEY = 0x00000100
69KEY_WOW64_32KEY = 0x00000200
71REG_BINARY = 3
72REG_DWORD = 4
73REG_DWORD_LITTLE_ENDIAN = 4
74REG_DWORD_BIG_ENDIAN = 5
75REG_EXPAND_SZ = 2
76REG_LINK = 6
77REG_MULTI_SZ = 7
78REG_NONE = 0
79REG_QWORD = 11
80REG_QWORD_LITTLE_ENDIAN = 11
81REG_SZ = 1
83# 3.1.5.7 BaseRegCreateKey (Opnum 6)
84REG_CREATED_NEW_KEY = 0x00000001
85REG_OPENED_EXISTING_KEY = 0x00000002
87# 3.1.5.19 BaseRegRestoreKey (Opnum 19)
88# Flags
89REG_WHOLE_HIVE_VOLATILE = 0x00000001
90REG_REFRESH_HIVE = 0x00000002
91REG_NO_LAZY_FLUSH = 0x00000004
92REG_FORCE_RESTORE = 0x00000008
94################################################################################
95# STRUCTURES
96################################################################################
97# 2.2.1 RPC_HKEY
98class RPC_HKEY(NDRSTRUCT):
99 structure = (
100 ('context_handle_attributes',ULONG),
101 ('context_handle_uuid',UUID),
102 )
104 def __init__(self, data=None, isNDR64=False):
105 NDRSTRUCT.__init__(self, data, isNDR64)
106 self['context_handle_uuid'] = b'\x00'*16
108 def isNull(self):
109 return self['context_handle_uuid'] == b'\x00'*16
111# 2.2.6 RVALENT
112class RVALENT(NDRSTRUCT):
113 structure = (
114 ('ve_valuename',PRRP_UNICODE_STRING),
115 ('ve_valuelen',DWORD),
116 ('ve_valueptr',DWORD),
117 ('ve_type',DWORD),
118 )
120class RVALENT_ARRAY(NDRUniConformantVaryingArray):
121 item = RVALENT
123# 2.2.9 RPC_SECURITY_DESCRIPTOR
124class BYTE_ARRAY(NDRUniConformantVaryingArray):
125 pass
127class PBYTE_ARRAY(NDRPOINTER):
128 referent = (
129 ('Data', BYTE_ARRAY),
130 )
132class RPC_SECURITY_DESCRIPTOR(NDRSTRUCT):
133 structure = (
134 ('lpSecurityDescriptor',PBYTE_ARRAY),
135 ('cbInSecurityDescriptor',DWORD),
136 ('cbOutSecurityDescriptor',DWORD),
137 )
139# 2.2.8 RPC_SECURITY_ATTRIBUTES
140class RPC_SECURITY_ATTRIBUTES(NDRSTRUCT):
141 structure = (
142 ('nLength',DWORD),
143 ('RpcSecurityDescriptor',RPC_SECURITY_DESCRIPTOR),
144 ('bInheritHandle',BOOLEAN),
145 )
147class PRPC_SECURITY_ATTRIBUTES(NDRPOINTER):
148 referent = (
149 ('Data', RPC_SECURITY_ATTRIBUTES),
150 )
152################################################################################
153# RPC CALLS
154################################################################################
155# 3.1.5.1 OpenClassesRoot (Opnum 0)
156class OpenClassesRoot(NDRCALL):
157 opnum = 0
158 structure = (
159 ('ServerName', PREGISTRY_SERVER_NAME),
160 ('samDesired', REGSAM),
161 )
163class OpenClassesRootResponse(NDRCALL):
164 structure = (
165 ('phKey', RPC_HKEY),
166 ('ErrorCode', error_status_t),
167 )
169# 3.1.5.2 OpenCurrentUser (Opnum 1)
170class OpenCurrentUser(NDRCALL):
171 opnum = 1
172 structure = (
173 ('ServerName', PREGISTRY_SERVER_NAME),
174 ('samDesired', REGSAM),
175 )
177class OpenCurrentUserResponse(NDRCALL):
178 structure = (
179 ('phKey', RPC_HKEY),
180 ('ErrorCode', error_status_t),
181 )
183# 3.1.5.3 OpenLocalMachine (Opnum 2)
184class OpenLocalMachine(NDRCALL):
185 opnum = 2
186 structure = (
187 ('ServerName', PREGISTRY_SERVER_NAME),
188 ('samDesired', REGSAM),
189 )
191class OpenLocalMachineResponse(NDRCALL):
192 structure = (
193 ('phKey', RPC_HKEY),
194 ('ErrorCode', error_status_t),
195 )
197# 3.1.5.4 OpenPerformanceData (Opnum 3)
198class OpenPerformanceData(NDRCALL):
199 opnum = 3
200 structure = (
201 ('ServerName', PREGISTRY_SERVER_NAME),
202 ('samDesired', REGSAM),
203 )
205class OpenPerformanceDataResponse(NDRCALL):
206 structure = (
207 ('phKey', RPC_HKEY),
208 ('ErrorCode', error_status_t),
209 )
211# 3.1.5.5 OpenUsers (Opnum 4)
212class OpenUsers(NDRCALL):
213 opnum = 4
214 structure = (
215 ('ServerName', PREGISTRY_SERVER_NAME),
216 ('samDesired', REGSAM),
217 )
219class OpenUsersResponse(NDRCALL):
220 structure = (
221 ('phKey', RPC_HKEY),
222 ('ErrorCode', error_status_t),
223 )
225# 3.1.5.6 BaseRegCloseKey (Opnum 5)
226class BaseRegCloseKey(NDRCALL):
227 opnum = 5
228 structure = (
229 ('hKey', RPC_HKEY),
230 )
232class BaseRegCloseKeyResponse(NDRCALL):
233 structure = (
234 ('hKey', RPC_HKEY),
235 ('ErrorCode', error_status_t),
236 )
238# 3.1.5.7 BaseRegCreateKey (Opnum 6)
239class BaseRegCreateKey(NDRCALL):
240 opnum = 6
241 structure = (
242 ('hKey', RPC_HKEY),
243 ('lpSubKey', RRP_UNICODE_STRING),
244 ('lpClass', RRP_UNICODE_STRING),
245 ('dwOptions', DWORD),
246 ('samDesired', REGSAM),
247 ('lpSecurityAttributes', PRPC_SECURITY_ATTRIBUTES),
248 ('lpdwDisposition', LPULONG),
249 )
251class BaseRegCreateKeyResponse(NDRCALL):
252 structure = (
253 ('phkResult', RPC_HKEY),
254 ('lpdwDisposition', LPULONG),
255 ('ErrorCode', error_status_t),
256 )
258# 3.1.5.8 BaseRegDeleteKey (Opnum 7)
259class BaseRegDeleteKey(NDRCALL):
260 opnum = 7
261 structure = (
262 ('hKey', RPC_HKEY),
263 ('lpSubKey', RRP_UNICODE_STRING),
264 )
266class BaseRegDeleteKeyResponse(NDRCALL):
267 structure = (
268 ('ErrorCode', error_status_t),
269 )
271# 3.1.5.9 BaseRegDeleteValue (Opnum 8)
272class BaseRegDeleteValue(NDRCALL):
273 opnum = 8
274 structure = (
275 ('hKey', RPC_HKEY),
276 ('lpValueName', RRP_UNICODE_STRING),
277 )
279class BaseRegDeleteValueResponse(NDRCALL):
280 structure = (
281 ('ErrorCode', error_status_t),
282 )
284# 3.1.5.10 BaseRegEnumKey (Opnum 9)
285class BaseRegEnumKey(NDRCALL):
286 opnum = 9
287 structure = (
288 ('hKey', RPC_HKEY),
289 ('dwIndex', DWORD),
290 ('lpNameIn', RRP_UNICODE_STRING),
291 ('lpClassIn', PRRP_UNICODE_STRING),
292 ('lpftLastWriteTime', PFILETIME),
293 )
295class BaseRegEnumKeyResponse(NDRCALL):
296 structure = (
297 ('lpNameOut', RRP_UNICODE_STRING),
298 ('lplpClassOut', PRRP_UNICODE_STRING),
299 ('lpftLastWriteTime', PFILETIME),
300 ('ErrorCode', error_status_t),
301 )
303# 3.1.5.11 BaseRegEnumValue (Opnum 10)
304class BaseRegEnumValue(NDRCALL):
305 opnum = 10
306 structure = (
307 ('hKey', RPC_HKEY),
308 ('dwIndex', DWORD),
309 ('lpValueNameIn', RRP_UNICODE_STRING),
310 ('lpType', LPULONG),
311 ('lpData', PBYTE_ARRAY),
312 ('lpcbData', LPULONG),
313 ('lpcbLen', LPULONG),
314 )
316class BaseRegEnumValueResponse(NDRCALL):
317 structure = (
318 ('lpValueNameOut', RRP_UNICODE_STRING),
319 ('lpType', LPULONG),
320 ('lpData', PBYTE_ARRAY),
321 ('lpcbData', LPULONG),
322 ('lpcbLen', LPULONG),
323 ('ErrorCode', error_status_t),
324 )
326# 3.1.5.12 BaseRegFlushKey (Opnum 11)
327class BaseRegFlushKey(NDRCALL):
328 opnum = 11
329 structure = (
330 ('hKey', RPC_HKEY),
331 )
333class BaseRegFlushKeyResponse(NDRCALL):
334 structure = (
335 ('ErrorCode', error_status_t),
336 )
338# 3.1.5.13 BaseRegGetKeySecurity (Opnum 12)
339class BaseRegGetKeySecurity(NDRCALL):
340 opnum = 12
341 structure = (
342 ('hKey', RPC_HKEY),
343 ('SecurityInformation', SECURITY_INFORMATION),
344 ('pRpcSecurityDescriptorIn', RPC_SECURITY_DESCRIPTOR),
345 )
347class BaseRegGetKeySecurityResponse(NDRCALL):
348 structure = (
349 ('pRpcSecurityDescriptorOut', RPC_SECURITY_DESCRIPTOR),
350 ('ErrorCode', error_status_t),
351 )
353# 3.1.5.14 BaseRegLoadKey (Opnum 13)
354class BaseRegLoadKey(NDRCALL):
355 opnum = 13
356 structure = (
357 ('hKey', RPC_HKEY),
358 ('lpSubKey', RRP_UNICODE_STRING),
359 ('lpFile', RRP_UNICODE_STRING),
360 )
362class BaseRegLoadKeyResponse(NDRCALL):
363 structure = (
364 ('ErrorCode', error_status_t),
365 )
367# 3.1.5.15 BaseRegOpenKey (Opnum 15)
368class BaseRegOpenKey(NDRCALL):
369 opnum = 15
370 structure = (
371 ('hKey', RPC_HKEY),
372 ('lpSubKey', RRP_UNICODE_STRING),
373 ('dwOptions', DWORD),
374 ('samDesired', REGSAM),
375 )
377class BaseRegOpenKeyResponse(NDRCALL):
378 structure = (
379 ('phkResult', RPC_HKEY),
380 ('ErrorCode', error_status_t),
381 )
383# 3.1.5.16 BaseRegQueryInfoKey (Opnum 16)
384class BaseRegQueryInfoKey(NDRCALL):
385 opnum = 16
386 structure = (
387 ('hKey', RPC_HKEY),
388 ('lpClassIn', RRP_UNICODE_STRING),
389 )
391class BaseRegQueryInfoKeyResponse(NDRCALL):
392 structure = (
393 ('lpClassOut', RPC_UNICODE_STRING),
394 ('lpcSubKeys', DWORD),
395 ('lpcbMaxSubKeyLen', DWORD),
396 ('lpcbMaxClassLen', DWORD),
397 ('lpcValues', DWORD),
398 ('lpcbMaxValueNameLen', DWORD),
399 ('lpcbMaxValueLen', DWORD),
400 ('lpcbSecurityDescriptor', DWORD),
401 ('lpftLastWriteTime', FILETIME),
402 ('ErrorCode', error_status_t),
403 )
405# 3.1.5.17 BaseRegQueryValue (Opnum 17)
406class BaseRegQueryValue(NDRCALL):
407 opnum = 17
408 structure = (
409 ('hKey', RPC_HKEY),
410 ('lpValueName', RRP_UNICODE_STRING),
411 ('lpType', LPULONG),
412 ('lpData', PBYTE_ARRAY),
413 ('lpcbData', LPULONG),
414 ('lpcbLen', LPULONG),
415 )
417class BaseRegQueryValueResponse(NDRCALL):
418 structure = (
419 ('lpType', LPULONG),
420 ('lpData', PBYTE_ARRAY),
421 ('lpcbData', LPULONG),
422 ('lpcbLen', LPULONG),
423 ('ErrorCode', error_status_t),
424 )
426# 3.1.5.18 BaseRegReplaceKey (Opnum 18)
427class BaseRegReplaceKey(NDRCALL):
428 opnum = 18
429 structure = (
430 ('hKey', RPC_HKEY),
431 ('lpSubKey', RRP_UNICODE_STRING),
432 ('lpNewFile', RRP_UNICODE_STRING),
433 ('lpOldFile', RRP_UNICODE_STRING),
434 )
436class BaseRegReplaceKeyResponse(NDRCALL):
437 structure = (
438 ('ErrorCode', error_status_t),
439 )
441# 3.1.5.19 BaseRegRestoreKey (Opnum 19)
442class BaseRegRestoreKey(NDRCALL):
443 opnum = 19
444 structure = (
445 ('hKey', RPC_HKEY),
446 ('lpFile', RRP_UNICODE_STRING),
447 ('Flags', DWORD),
448 )
450class BaseRegRestoreKeyResponse(NDRCALL):
451 structure = (
452 ('ErrorCode', error_status_t),
453 )
455# 3.1.5.20 BaseRegSaveKey (Opnum 20)
456class BaseRegSaveKey(NDRCALL):
457 opnum = 20
458 structure = (
459 ('hKey', RPC_HKEY),
460 ('lpFile', RRP_UNICODE_STRING),
461 ('pSecurityAttributes', PRPC_SECURITY_ATTRIBUTES),
462 )
464class BaseRegSaveKeyResponse(NDRCALL):
465 structure = (
466 ('ErrorCode', error_status_t),
467 )
469# 3.1.5.21 BaseRegSetKeySecurity (Opnum 21)
470class BaseRegSetKeySecurity(NDRCALL):
471 opnum = 21
472 structure = (
473 ('hKey', RPC_HKEY),
474 ('SecurityInformation', SECURITY_INFORMATION),
475 ('pRpcSecurityDescriptor', RPC_SECURITY_DESCRIPTOR),
476 )
478class BaseRegSetKeySecurityResponse(NDRCALL):
479 structure = (
480 ('ErrorCode', error_status_t),
481 )
483# 3.1.5.22 BaseRegSetValue (Opnum 22)
484class BaseRegSetValue(NDRCALL):
485 opnum = 22
486 structure = (
487 ('hKey', RPC_HKEY),
488 ('lpValueName', RRP_UNICODE_STRING),
489 ('dwType', DWORD),
490 ('lpData', NDRUniConformantArray),
491 ('cbData', DWORD),
492 )
494class BaseRegSetValueResponse(NDRCALL):
495 structure = (
496 ('ErrorCode', error_status_t),
497 )
499# 3.1.5.23 BaseRegUnLoadKey (Opnum 23)
500class BaseRegUnLoadKey(NDRCALL):
501 opnum = 23
502 structure = (
503 ('hKey', RPC_HKEY),
504 ('lpSubKey', RRP_UNICODE_STRING),
505 )
507class BaseRegUnLoadKeyResponse(NDRCALL):
508 structure = (
509 ('ErrorCode', error_status_t),
510 )
512# 3.1.5.24 BaseRegGetVersion (Opnum 26)
513class BaseRegGetVersion(NDRCALL):
514 opnum = 26
515 structure = (
516 ('hKey', RPC_HKEY),
517 )
519class BaseRegGetVersionResponse(NDRCALL):
520 structure = (
521 ('lpdwVersion', DWORD),
522 ('ErrorCode', error_status_t),
523 )
525# 3.1.5.25 OpenCurrentConfig (Opnum 27)
526class OpenCurrentConfig(NDRCALL):
527 opnum = 27
528 structure = (
529 ('ServerName', PREGISTRY_SERVER_NAME),
530 ('samDesired', REGSAM),
531 )
533class OpenCurrentConfigResponse(NDRCALL):
534 structure = (
535 ('phKey', RPC_HKEY),
536 ('ErrorCode', error_status_t),
537 )
539# 3.1.5.26 BaseRegQueryMultipleValues (Opnum 29)
540class BaseRegQueryMultipleValues(NDRCALL):
541 opnum = 29
542 structure = (
543 ('hKey', RPC_HKEY),
544 ('val_listIn', RVALENT_ARRAY),
545 ('num_vals', DWORD),
546 ('lpvalueBuf', PBYTE_ARRAY),
547 ('ldwTotsize', DWORD),
548 )
550class BaseRegQueryMultipleValuesResponse(NDRCALL):
551 structure = (
552 ('val_listOut', RVALENT_ARRAY),
553 ('lpvalueBuf', PBYTE_ARRAY),
554 ('ldwTotsize', DWORD),
555 ('ErrorCode', error_status_t),
556 )
558# 3.1.5.27 BaseRegSaveKeyEx (Opnum 31)
559class BaseRegSaveKeyEx(NDRCALL):
560 opnum = 31
561 structure = (
562 ('hKey', RPC_HKEY),
563 ('lpFile', RRP_UNICODE_STRING),
564 ('pSecurityAttributes', PRPC_SECURITY_ATTRIBUTES),
565 ('Flags', DWORD),
566 )
568class BaseRegSaveKeyExResponse(NDRCALL):
569 structure = (
570 ('ErrorCode', error_status_t),
571 )
573# 3.1.5.28 OpenPerformanceText (Opnum 32)
574class OpenPerformanceText(NDRCALL):
575 opnum = 32
576 structure = (
577 ('ServerName', PREGISTRY_SERVER_NAME),
578 ('samDesired', REGSAM),
579 )
581class OpenPerformanceTextResponse(NDRCALL):
582 structure = (
583 ('phKey', RPC_HKEY),
584 ('ErrorCode', error_status_t),
585 )
587# 3.1.5.29 OpenPerformanceNlsText (Opnum 33)
588class OpenPerformanceNlsText(NDRCALL):
589 opnum = 33
590 structure = (
591 ('ServerName', PREGISTRY_SERVER_NAME),
592 ('samDesired', REGSAM),
593 )
595class OpenPerformanceNlsTextResponse(NDRCALL):
596 structure = (
597 ('phKey', RPC_HKEY),
598 ('ErrorCode', error_status_t),
599 )
601# 3.1.5.30 BaseRegQueryMultipleValues2 (Opnum 34)
602class BaseRegQueryMultipleValues2(NDRCALL):
603 opnum = 34
604 structure = (
605 ('hKey', RPC_HKEY),
606 ('val_listIn', RVALENT_ARRAY),
607 ('num_vals', DWORD),
608 ('lpvalueBuf', PBYTE_ARRAY),
609 ('ldwTotsize', DWORD),
610 )
612class BaseRegQueryMultipleValues2Response(NDRCALL):
613 structure = (
614 ('val_listOut', RVALENT_ARRAY),
615 ('lpvalueBuf', PBYTE_ARRAY),
616 ('ldwRequiredSize', DWORD),
617 ('ErrorCode', error_status_t),
618 )
620# 3.1.5.31 BaseRegDeleteKeyEx (Opnum 35)
621class BaseRegDeleteKeyEx(NDRCALL):
622 opnum = 35
623 structure = (
624 ('hKey', RPC_HKEY),
625 ('lpSubKey', RRP_UNICODE_STRING),
626 ('AccessMask', REGSAM),
627 ('Reserved', DWORD),
628 )
630class BaseRegDeleteKeyExResponse(NDRCALL):
631 structure = (
632 ('ErrorCode', error_status_t),
633 )
635################################################################################
636# OPNUMs and their corresponding structures
637################################################################################
638OPNUMS = {
639 0 : (OpenClassesRoot, OpenClassesRootResponse),
640 1 : (OpenCurrentUser, OpenCurrentUserResponse),
641 2 : (OpenLocalMachine, OpenLocalMachineResponse),
642 3 : (OpenPerformanceData, OpenPerformanceDataResponse),
643 4 : (OpenUsers, OpenUsersResponse),
644 5 : (BaseRegCloseKey, BaseRegCloseKeyResponse),
645 6 : (BaseRegCreateKey, BaseRegCreateKeyResponse),
646 7 : (BaseRegDeleteKey, BaseRegDeleteKeyResponse),
647 8 : (BaseRegDeleteValue, BaseRegDeleteValueResponse),
648 9 : (BaseRegEnumKey, BaseRegEnumKeyResponse),
64910 : (BaseRegEnumValue, BaseRegEnumValueResponse),
65011 : (BaseRegFlushKey, BaseRegFlushKeyResponse),
65112 : (BaseRegGetKeySecurity, BaseRegGetKeySecurityResponse),
65213 : (BaseRegLoadKey, BaseRegLoadKeyResponse),
65315 : (BaseRegOpenKey, BaseRegOpenKeyResponse),
65416 : (BaseRegQueryInfoKey, BaseRegQueryInfoKeyResponse),
65517 : (BaseRegQueryValue, BaseRegQueryValueResponse),
65618 : (BaseRegReplaceKey, BaseRegReplaceKeyResponse),
65719 : (BaseRegRestoreKey, BaseRegRestoreKeyResponse),
65820 : (BaseRegSaveKey, BaseRegSaveKeyResponse),
65921 : (BaseRegSetKeySecurity, BaseRegSetKeySecurityResponse),
66022 : (BaseRegSetValue, BaseRegSetValueResponse),
66123 : (BaseRegUnLoadKey, BaseRegUnLoadKeyResponse),
66226 : (BaseRegGetVersion, BaseRegGetVersionResponse),
66327 : (OpenCurrentConfig, OpenCurrentConfigResponse),
66429 : (BaseRegQueryMultipleValues, BaseRegQueryMultipleValuesResponse),
66531 : (BaseRegSaveKeyEx, BaseRegSaveKeyExResponse),
66632 : (OpenPerformanceText, OpenPerformanceTextResponse),
66733 : (OpenPerformanceNlsText, OpenPerformanceNlsTextResponse),
66834 : (BaseRegQueryMultipleValues2, BaseRegQueryMultipleValues2Response),
66935 : (BaseRegDeleteKeyEx, BaseRegDeleteKeyExResponse),
670}
672################################################################################
673# HELPER FUNCTIONS
674################################################################################
675def checkNullString(string):
676 if string == NULL:
677 return string
679 if string[-1:] != '\x00':
680 return string + '\x00'
681 else:
682 return string
684def packValue(valueType, value):
685 if valueType == REG_DWORD: 685 ↛ 686line 685 didn't jump to line 686, because the condition on line 685 was never true
686 retData = pack('<L', value)
687 elif valueType == REG_DWORD_BIG_ENDIAN: 687 ↛ 688line 687 didn't jump to line 688, because the condition on line 687 was never true
688 retData = pack('>L', value)
689 elif valueType == REG_EXPAND_SZ: 689 ↛ 690line 689 didn't jump to line 690, because the condition on line 689 was never true
690 try:
691 retData = value.encode('utf-16le')
692 except UnicodeDecodeError:
693 import sys
694 retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le')
695 elif valueType == REG_MULTI_SZ: 695 ↛ 696line 695 didn't jump to line 696, because the condition on line 695 was never true
696 try:
697 retData = value.encode('utf-16le')
698 except UnicodeDecodeError:
699 import sys
700 retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le')
701 elif valueType == REG_QWORD: 701 ↛ 702line 701 didn't jump to line 702, because the condition on line 701 was never true
702 retData = pack('<Q', value)
703 elif valueType == REG_QWORD_LITTLE_ENDIAN: 703 ↛ 704line 703 didn't jump to line 704, because the condition on line 703 was never true
704 retData = pack('>Q', value)
705 elif valueType == REG_SZ: 705 ↛ 712line 705 didn't jump to line 712, because the condition on line 705 was never false
706 try:
707 retData = value.encode('utf-16le')
708 except UnicodeDecodeError:
709 import sys
710 retData = value.decode(sys.getfilesystemencoding()).encode('utf-16le')
711 else:
712 retData = value
714 return retData
716def unpackValue(valueType, value):
717 if valueType == REG_DWORD:
718 retData = unpack('<L', b''.join(value))[0]
719 elif valueType == REG_DWORD_BIG_ENDIAN: 719 ↛ 720line 719 didn't jump to line 720, because the condition on line 719 was never true
720 retData = unpack('>L', b''.join(value))[0]
721 elif valueType == REG_EXPAND_SZ: 721 ↛ 722line 721 didn't jump to line 722, because the condition on line 721 was never true
722 retData = b''.join(value).decode('utf-16le')
723 elif valueType == REG_MULTI_SZ: 723 ↛ 724line 723 didn't jump to line 724, because the condition on line 723 was never true
724 retData = b''.join(value).decode('utf-16le')
725 elif valueType == REG_QWORD: 725 ↛ 726line 725 didn't jump to line 726, because the condition on line 725 was never true
726 retData = unpack('<Q', b''.join(value))[0]
727 elif valueType == REG_QWORD_LITTLE_ENDIAN: 727 ↛ 728line 727 didn't jump to line 728, because the condition on line 727 was never true
728 retData = unpack('>Q', b''.join(value))[0]
729 elif valueType == REG_SZ: 729 ↛ 732line 729 didn't jump to line 732, because the condition on line 729 was never false
730 retData = b''.join(value).decode('utf-16le')
731 else:
732 retData = b''.join(value)
734 return retData
736def hOpenClassesRoot(dce, samDesired = MAXIMUM_ALLOWED):
737 request = OpenClassesRoot()
738 request['ServerName'] = NULL
739 request['samDesired'] = samDesired
740 return dce.request(request)
742def hOpenCurrentUser(dce, samDesired = MAXIMUM_ALLOWED):
743 request = OpenCurrentUser()
744 request['ServerName'] = NULL
745 request['samDesired'] = samDesired
746 return dce.request(request)
748def hOpenLocalMachine(dce, samDesired = MAXIMUM_ALLOWED):
749 request = OpenLocalMachine()
750 request['ServerName'] = NULL
751 request['samDesired'] = samDesired
752 return dce.request(request)
754def hOpenPerformanceData(dce, samDesired = MAXIMUM_ALLOWED):
755 request = OpenPerformanceData()
756 request['ServerName'] = NULL
757 request['samDesired'] = samDesired
758 return dce.request(request)
760def hOpenUsers(dce, samDesired = MAXIMUM_ALLOWED):
761 request = OpenUsers()
762 request['ServerName'] = NULL
763 request['samDesired'] = samDesired
764 return dce.request(request)
766def hBaseRegCloseKey(dce, hKey):
767 request = BaseRegCloseKey()
768 request['hKey'] = hKey
769 return dce.request(request)
771def hBaseRegCreateKey(dce, hKey, lpSubKey, lpClass = NULL, dwOptions = 0x00000001, samDesired = MAXIMUM_ALLOWED, lpSecurityAttributes = NULL, lpdwDisposition = REG_CREATED_NEW_KEY):
772 request = BaseRegCreateKey()
773 request['hKey'] = hKey
774 request['lpSubKey'] = checkNullString(lpSubKey)
775 request['lpClass'] = checkNullString(lpClass)
776 request['dwOptions'] = dwOptions
777 request['samDesired'] = samDesired
778 if lpSecurityAttributes == NULL: 778 ↛ 781line 778 didn't jump to line 781, because the condition on line 778 was never false
779 request['lpSecurityAttributes']['RpcSecurityDescriptor']['lpSecurityDescriptor'] = NULL
780 else:
781 request['lpSecurityAttributes'] = lpSecurityAttributes
782 request['lpdwDisposition'] = lpdwDisposition
784 return dce.request(request)
786def hBaseRegDeleteKey(dce, hKey, lpSubKey):
787 request = BaseRegDeleteKey()
788 request['hKey'] = hKey
789 request['lpSubKey'] = checkNullString(lpSubKey)
790 return dce.request(request)
792def hBaseRegEnumKey(dce, hKey, dwIndex, lpftLastWriteTime = NULL):
793 request = BaseRegEnumKey()
794 request['hKey'] = hKey
795 request['dwIndex'] = dwIndex
796 request.fields['lpNameIn'].fields['MaximumLength'] = 1024
797 request.fields['lpNameIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = 1024//2
798 request['lpClassIn'] = ' '* 64
799 request['lpftLastWriteTime'] = lpftLastWriteTime
801 return dce.request(request)
803def hBaseRegEnumValue(dce, hKey, dwIndex, dataLen=256):
804 request = BaseRegEnumValue()
805 request['hKey'] = hKey
806 request['dwIndex'] = dwIndex
807 retries = 1
809 # We need to be aware the size might not be enough, so let's catch ERROR_MORE_DATA exception
810 while True:
811 try:
812 # Only the maximum length field of the lpValueNameIn is used to determine the buffer length to be allocated
813 # by the service. Specify a string with a zero length but maximum length set to the largest buffer size
814 # needed to hold the value names.
815 request.fields['lpValueNameIn'].fields['MaximumLength'] = dataLen*2
816 request.fields['lpValueNameIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = dataLen
818 request['lpData'] = b' ' * dataLen
819 request['lpcbData'] = dataLen
820 request['lpcbLen'] = dataLen
821 resp = dce.request(request)
822 except DCERPCSessionError as e:
823 if retries > 1: 823 ↛ 824line 823 didn't jump to line 824, because the condition on line 823 was never true
824 LOG.debug('Too many retries when calling hBaseRegEnumValue, aborting')
825 raise
826 if e.get_error_code() == system_errors.ERROR_MORE_DATA: 826 ↛ 832line 826 didn't jump to line 832, because the condition on line 826 was never false
827 # We need to adjust the size
828 retries +=1
829 dataLen = e.get_packet()['lpcbData']
830 continue
831 else:
832 raise
833 else:
834 break
836 return resp
838def hBaseRegFlushKey(dce, hKey):
839 request = BaseRegFlushKey()
840 request['hKey'] = hKey
841 return dce.request(request)
843def hBaseRegGetKeySecurity(dce, hKey, securityInformation = OWNER_SECURITY_INFORMATION ):
844 request = BaseRegGetKeySecurity()
845 request['hKey'] = hKey
846 request['SecurityInformation'] = securityInformation
847 request['pRpcSecurityDescriptorIn']['lpSecurityDescriptor'] = NULL
848 request['pRpcSecurityDescriptorIn']['cbInSecurityDescriptor'] = 1024
850 return dce.request(request)
852def hBaseRegLoadKey(dce, hKey, lpSubKey, lpFile):
853 request = BaseRegLoadKey()
854 request['hKey'] = hKey
855 request['lpSubKey'] = checkNullString(lpSubKey)
856 request['lpFile'] = checkNullString(lpFile)
857 return dce.request(request)
859def hBaseRegUnLoadKey(dce, hKey, lpSubKey):
860 request = BaseRegUnLoadKey()
861 request['hKey'] = hKey
862 request['lpSubKey'] = checkNullString(lpSubKey)
863 return dce.request(request)
865def hBaseRegOpenKey(dce, hKey, lpSubKey, dwOptions=0x00000001, samDesired = MAXIMUM_ALLOWED):
866 request = BaseRegOpenKey()
867 request['hKey'] = hKey
868 request['lpSubKey'] = checkNullString(lpSubKey)
869 request['dwOptions'] = dwOptions
870 request['samDesired'] = samDesired
871 return dce.request(request)
873def hBaseRegQueryInfoKey(dce, hKey):
874 request = BaseRegQueryInfoKey()
875 request['hKey'] = hKey
876 # Not the cleanest way, but oh well
877 # Plus, Windows XP needs MaximumCount also set
878 request.fields['lpClassIn'].fields['MaximumLength'] = 1024
879 request.fields['lpClassIn'].fields['Data'].fields['Data'].fields['MaximumCount'] = 1024//2
880 return dce.request(request)
882def hBaseRegQueryValue(dce, hKey, lpValueName, dataLen=512):
883 request = BaseRegQueryValue()
884 request['hKey'] = hKey
885 request['lpValueName'] = checkNullString(lpValueName)
886 retries = 1
888 # We need to be aware the size might not be enough, so let's catch ERROR_MORE_DATA exception
889 while True:
890 try:
891 request['lpData'] =b' ' * dataLen
892 request['lpcbData'] = dataLen
893 request['lpcbLen'] = dataLen
894 resp = dce.request(request)
895 except DCERPCSessionError as e:
896 if retries > 1:
897 LOG.debug('Too many retries when calling hBaseRegQueryValue, aborting')
898 raise
899 if e.get_error_code() == system_errors.ERROR_MORE_DATA:
900 # We need to adjust the size
901 dataLen = e.get_packet()['lpcbData']
902 continue
903 else:
904 raise
905 else:
906 break
908 # Returns
909 # ( dataType, data )
910 return resp['lpType'], unpackValue(resp['lpType'], resp['lpData'])
912def hBaseRegReplaceKey(dce, hKey, lpSubKey, lpNewFile, lpOldFile):
913 request = BaseRegReplaceKey()
914 request['hKey'] = hKey
915 request['lpSubKey'] = checkNullString(lpSubKey)
916 request['lpNewFile'] = checkNullString(lpNewFile)
917 request['lpOldFile'] = checkNullString(lpOldFile)
918 return dce.request(request)
920def hBaseRegRestoreKey(dce, hKey, lpFile, flags=REG_REFRESH_HIVE):
921 request = BaseRegRestoreKey()
922 request['hKey'] = hKey
923 request['lpFile'] = checkNullString(lpFile)
924 request['Flags'] = flags
925 return dce.request(request)
927def hBaseRegSaveKey(dce, hKey, lpFile, pSecurityAttributes = NULL):
928 request = BaseRegSaveKey()
929 request['hKey'] = hKey
930 request['lpFile'] = checkNullString(lpFile)
931 request['pSecurityAttributes'] = pSecurityAttributes
932 return dce.request(request)
934def hBaseRegSetValue(dce, hKey, lpValueName, dwType, lpData):
935 request = BaseRegSetValue()
936 request['hKey'] = hKey
937 request['lpValueName'] = checkNullString(lpValueName)
938 request['dwType'] = dwType
939 request['lpData'] = packValue(dwType,lpData)
940 request['cbData'] = len(request['lpData'])
941 return dce.request(request)
943def hBaseRegGetVersion(dce, hKey):
944 request = BaseRegGetVersion()
945 request['hKey'] = hKey
946 return dce.request(request)
948def hOpenCurrentConfig(dce, samDesired = MAXIMUM_ALLOWED):
949 request = OpenCurrentConfig()
950 request['ServerName'] = NULL
951 request['samDesired'] = samDesired
952 return dce.request(request)
954def hBaseRegQueryMultipleValues(dce, hKey, val_listIn):
955 # ToDo, check the result to see whether we need to
956 # have a bigger buffer for the data to receive
957 request = BaseRegQueryMultipleValues()
958 request['hKey'] = hKey
960 for item in val_listIn:
961 itemn = RVALENT()
962 itemn['ve_valuename'] = checkNullString(item['ValueName'])
963 itemn['ve_valuelen'] = len(itemn['ve_valuename'])
964 itemn['ve_valueptr'] = NULL
965 itemn['ve_type'] = item['ValueType']
966 request['val_listIn'].append(itemn)
968 request['num_vals'] = len(request['val_listIn'])
969 request['lpvalueBuf'] = list(b' '*128)
970 request['ldwTotsize'] = 128
972 resp = dce.request(request)
973 retVal = list()
974 for item in resp['val_listOut']:
975 itemn = dict()
976 itemn['ValueName'] = item['ve_valuename']
977 itemn['ValueData'] = unpackValue(item['ve_type'], resp['lpvalueBuf'][item['ve_valueptr'] : item['ve_valueptr']+item['ve_valuelen']])
978 retVal.append(itemn)
980 return retVal
982def hBaseRegSaveKeyEx(dce, hKey, lpFile, pSecurityAttributes = NULL, flags=1):
983 request = BaseRegSaveKeyEx()
984 request['hKey'] = hKey
985 request['lpFile'] = checkNullString(lpFile)
986 request['pSecurityAttributes'] = pSecurityAttributes
987 request['Flags'] = flags
988 return dce.request(request)
990def hOpenPerformanceText(dce, samDesired = MAXIMUM_ALLOWED):
991 request = OpenPerformanceText()
992 request['ServerName'] = NULL
993 request['samDesired'] = samDesired
994 return dce.request(request)
996def hOpenPerformanceNlsText(dce, samDesired = MAXIMUM_ALLOWED):
997 request = OpenPerformanceNlsText()
998 request['ServerName'] = NULL
999 request['samDesired'] = samDesired
1000 return dce.request(request)
1002def hBaseRegDeleteValue(dce, hKey, lpValueName):
1003 request = BaseRegDeleteValue()
1004 request['hKey'] = hKey
1005 request['lpValueName'] = checkNullString(lpValueName)
1006 return dce.request(request)