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

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

## 487 statements

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#

21

22

23 from struct import unpack, pack

24

25 from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRPOINTER, NDRUniConformantVaryingArray, NDRUniConformantArray

26 from 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

28 from impacket.dcerpc.v5.rpcrt import DCERPCException

29 from impacket import system_errors, LOG

30 from impacket.uuid import uuidtup_to_bin

31

32 MSRPC_UUID_RRP = uuidtup_to_bin(('338CD001-2244-31F1-AAAA-900038001003', '1.0'))

33

34 class DCERPCSessionError(DCERPCException):

35 def __init__(self, error_string=None, error_code=None, packet=None):

36 DCERPCException.__init__(self, error_string, error_code, packet)

37

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

46

47################################################################################

48# CONSTANTS

49################################################################################

50# 2.2.2 PREGISTRY_SERVER_NAME

51 PREGISTRY_SERVER_NAME = PWCHAR

52

53# 2.2.3 error_status_t

54 error_status_t = ULONG

55

56# 2.2.5 RRP_UNICODE_STRING

57 RRP_UNICODE_STRING = RPC_UNICODE_STRING

58 PRRP_UNICODE_STRING = PRPC_UNICODE_STRING

59

60# 2.2.4 REGSAM

61 REGSAM = ULONG

62

63 KEY_QUERY_VALUE = 0x00000001

64 KEY_SET_VALUE = 0x00000002

65 KEY_CREATE_SUB_KEY = 0x00000004

66 KEY_ENUMERATE_SUB_KEYS = 0x00000008

67 KEY_CREATE_LINK = 0x00000020

68 KEY_WOW64_64KEY = 0x00000100

69 KEY_WOW64_32KEY = 0x00000200

70

71 REG_BINARY = 3

72 REG_DWORD = 4

73 REG_DWORD_LITTLE_ENDIAN = 4

74 REG_DWORD_BIG_ENDIAN = 5

75 REG_EXPAND_SZ = 2

76 REG_LINK = 6

77 REG_MULTI_SZ = 7

78 REG_NONE = 0

79 REG_QWORD = 11

80 REG_QWORD_LITTLE_ENDIAN = 11

81 REG_SZ = 1

82

83# 3.1.5.7 BaseRegCreateKey (Opnum 6)

84 REG_CREATED_NEW_KEY = 0x00000001

85 REG_OPENED_EXISTING_KEY = 0x00000002

86

87# 3.1.5.19 BaseRegRestoreKey (Opnum 19)

88# Flags

89 REG_WHOLE_HIVE_VOLATILE = 0x00000001

90 REG_REFRESH_HIVE = 0x00000002

91 REG_NO_LAZY_FLUSH = 0x00000004

92 REG_FORCE_RESTORE = 0x00000008

93

94################################################################################

95# STRUCTURES

96################################################################################

97# 2.2.1 RPC_HKEY

98 class RPC_HKEY(NDRSTRUCT):

99 structure = (

100 ('context_handle_attributes',ULONG),

101 ('context_handle_uuid',UUID),

102 )

103

104 def __init__(self, data=None, isNDR64=False):

105 NDRSTRUCT.__init__(self, data, isNDR64)

106 self['context_handle_uuid'] = b'\x00'*16

107

108 def isNull(self):

109 return self['context_handle_uuid'] == b'\x00'*16

110

111# 2.2.6 RVALENT

112 class RVALENT(NDRSTRUCT):

113 structure = (

114 ('ve_valuename',PRRP_UNICODE_STRING),

115 ('ve_valuelen',DWORD),

116 ('ve_valueptr',DWORD),

117 ('ve_type',DWORD),

118 )

119

120 class RVALENT_ARRAY(NDRUniConformantVaryingArray):

121 item = RVALENT

122

123# 2.2.9 RPC_SECURITY_DESCRIPTOR

124 class BYTE_ARRAY(NDRUniConformantVaryingArray):

125 pass

126

127 class PBYTE_ARRAY(NDRPOINTER):

128 referent = (

129 ('Data', BYTE_ARRAY),

130 )

131

132 class RPC_SECURITY_DESCRIPTOR(NDRSTRUCT):

133 structure = (

134 ('lpSecurityDescriptor',PBYTE_ARRAY),

135 ('cbInSecurityDescriptor',DWORD),

136 ('cbOutSecurityDescriptor',DWORD),

137 )

138

139# 2.2.8 RPC_SECURITY_ATTRIBUTES

140 class RPC_SECURITY_ATTRIBUTES(NDRSTRUCT):

141 structure = (

142 ('nLength',DWORD),

143 ('RpcSecurityDescriptor',RPC_SECURITY_DESCRIPTOR),

144 ('bInheritHandle',BOOLEAN),

145 )

146

147 class PRPC_SECURITY_ATTRIBUTES(NDRPOINTER):

148 referent = (

149 ('Data', RPC_SECURITY_ATTRIBUTES),

150 )

151

152################################################################################

153# RPC CALLS

154################################################################################

155# 3.1.5.1 OpenClassesRoot (Opnum 0)

156 class OpenClassesRoot(NDRCALL):

157 opnum = 0

158 structure = (

159 ('ServerName', PREGISTRY_SERVER_NAME),

160 ('samDesired', REGSAM),

161 )

162

163 class OpenClassesRootResponse(NDRCALL):

164 structure = (

165 ('phKey', RPC_HKEY),

166 ('ErrorCode', error_status_t),

167 )

168

169# 3.1.5.2 OpenCurrentUser (Opnum 1)

170 class OpenCurrentUser(NDRCALL):

171 opnum = 1

172 structure = (

173 ('ServerName', PREGISTRY_SERVER_NAME),

174 ('samDesired', REGSAM),

175 )

176

177 class OpenCurrentUserResponse(NDRCALL):

178 structure = (

179 ('phKey', RPC_HKEY),

180 ('ErrorCode', error_status_t),

181 )

182

183# 3.1.5.3 OpenLocalMachine (Opnum 2)

184 class OpenLocalMachine(NDRCALL):

185 opnum = 2

186 structure = (

187 ('ServerName', PREGISTRY_SERVER_NAME),

188 ('samDesired', REGSAM),

189 )

190

191 class OpenLocalMachineResponse(NDRCALL):

192 structure = (

193 ('phKey', RPC_HKEY),

194 ('ErrorCode', error_status_t),

195 )

196

197# 3.1.5.4 OpenPerformanceData (Opnum 3)

198 class OpenPerformanceData(NDRCALL):

199 opnum = 3

200 structure = (

201 ('ServerName', PREGISTRY_SERVER_NAME),

202 ('samDesired', REGSAM),

203 )

204

205 class OpenPerformanceDataResponse(NDRCALL):

206 structure = (

207 ('phKey', RPC_HKEY),

208 ('ErrorCode', error_status_t),

209 )

210

211# 3.1.5.5 OpenUsers (Opnum 4)

212 class OpenUsers(NDRCALL):

213 opnum = 4

214 structure = (

215 ('ServerName', PREGISTRY_SERVER_NAME),

216 ('samDesired', REGSAM),

217 )

218

219 class OpenUsersResponse(NDRCALL):

220 structure = (

221 ('phKey', RPC_HKEY),

222 ('ErrorCode', error_status_t),

223 )

224

225# 3.1.5.6 BaseRegCloseKey (Opnum 5)

226 class BaseRegCloseKey(NDRCALL):

227 opnum = 5

228 structure = (

229 ('hKey', RPC_HKEY),

230 )

231

232 class BaseRegCloseKeyResponse(NDRCALL):

233 structure = (

234 ('hKey', RPC_HKEY),

235 ('ErrorCode', error_status_t),

236 )

237

238# 3.1.5.7 BaseRegCreateKey (Opnum 6)

239 class 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 )

250

251 class BaseRegCreateKeyResponse(NDRCALL):

252 structure = (

253 ('phkResult', RPC_HKEY),

254 ('lpdwDisposition', LPULONG),

255 ('ErrorCode', error_status_t),

256 )

257

258# 3.1.5.8 BaseRegDeleteKey (Opnum 7)

259 class BaseRegDeleteKey(NDRCALL):

260 opnum = 7

261 structure = (

262 ('hKey', RPC_HKEY),

263 ('lpSubKey', RRP_UNICODE_STRING),

264 )

265

266 class BaseRegDeleteKeyResponse(NDRCALL):

267 structure = (

268 ('ErrorCode', error_status_t),

269 )

270

271# 3.1.5.9 BaseRegDeleteValue (Opnum 8)

272 class BaseRegDeleteValue(NDRCALL):

273 opnum = 8

274 structure = (

275 ('hKey', RPC_HKEY),

276 ('lpValueName', RRP_UNICODE_STRING),

277 )

278

279 class BaseRegDeleteValueResponse(NDRCALL):

280 structure = (

281 ('ErrorCode', error_status_t),

282 )

283

284# 3.1.5.10 BaseRegEnumKey (Opnum 9)

285 class 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 )

294

295 class BaseRegEnumKeyResponse(NDRCALL):

296 structure = (

297 ('lpNameOut', RRP_UNICODE_STRING),

298 ('lplpClassOut', PRRP_UNICODE_STRING),

299 ('lpftLastWriteTime', PFILETIME),

300 ('ErrorCode', error_status_t),

301 )

302

303# 3.1.5.11 BaseRegEnumValue (Opnum 10)

304 class 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 )

315

316 class 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 )

325

326# 3.1.5.12 BaseRegFlushKey (Opnum 11)

327 class BaseRegFlushKey(NDRCALL):

328 opnum = 11

329 structure = (

330 ('hKey', RPC_HKEY),

331 )

332

333 class BaseRegFlushKeyResponse(NDRCALL):

334 structure = (

335 ('ErrorCode', error_status_t),

336 )

337

338# 3.1.5.13 BaseRegGetKeySecurity (Opnum 12)

339 class BaseRegGetKeySecurity(NDRCALL):

340 opnum = 12

341 structure = (

342 ('hKey', RPC_HKEY),

343 ('SecurityInformation', SECURITY_INFORMATION),

344 ('pRpcSecurityDescriptorIn', RPC_SECURITY_DESCRIPTOR),

345 )

346

347 class BaseRegGetKeySecurityResponse(NDRCALL):

348 structure = (

349 ('pRpcSecurityDescriptorOut', RPC_SECURITY_DESCRIPTOR),

350 ('ErrorCode', error_status_t),

351 )

352

353# 3.1.5.14 BaseRegLoadKey (Opnum 13)

354 class BaseRegLoadKey(NDRCALL):

355 opnum = 13

356 structure = (

357 ('hKey', RPC_HKEY),

358 ('lpSubKey', RRP_UNICODE_STRING),

359 ('lpFile', RRP_UNICODE_STRING),

360 )

361

362 class BaseRegLoadKeyResponse(NDRCALL):

363 structure = (

364 ('ErrorCode', error_status_t),

365 )

366

367# 3.1.5.15 BaseRegOpenKey (Opnum 15)

368 class BaseRegOpenKey(NDRCALL):

369 opnum = 15

370 structure = (

371 ('hKey', RPC_HKEY),

372 ('lpSubKey', RRP_UNICODE_STRING),

373 ('dwOptions', DWORD),

374 ('samDesired', REGSAM),

375 )

376

377 class BaseRegOpenKeyResponse(NDRCALL):

378 structure = (

379 ('phkResult', RPC_HKEY),

380 ('ErrorCode', error_status_t),

381 )

382

383# 3.1.5.16 BaseRegQueryInfoKey (Opnum 16)

384 class BaseRegQueryInfoKey(NDRCALL):

385 opnum = 16

386 structure = (

387 ('hKey', RPC_HKEY),

388 ('lpClassIn', RRP_UNICODE_STRING),

389 )

390

391 class 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 )

404

405# 3.1.5.17 BaseRegQueryValue (Opnum 17)

406 class 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 )

416

417 class BaseRegQueryValueResponse(NDRCALL):

418 structure = (

419 ('lpType', LPULONG),

420 ('lpData', PBYTE_ARRAY),

421 ('lpcbData', LPULONG),

422 ('lpcbLen', LPULONG),

423 ('ErrorCode', error_status_t),

424 )

425

426# 3.1.5.18 BaseRegReplaceKey (Opnum 18)

427 class 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 )

435

436 class BaseRegReplaceKeyResponse(NDRCALL):

437 structure = (

438 ('ErrorCode', error_status_t),

439 )

440

441# 3.1.5.19 BaseRegRestoreKey (Opnum 19)

442 class BaseRegRestoreKey(NDRCALL):

443 opnum = 19

444 structure = (

445 ('hKey', RPC_HKEY),

446 ('lpFile', RRP_UNICODE_STRING),

447 ('Flags', DWORD),

448 )

449

450 class BaseRegRestoreKeyResponse(NDRCALL):

451 structure = (

452 ('ErrorCode', error_status_t),

453 )

454

455# 3.1.5.20 BaseRegSaveKey (Opnum 20)

456 class BaseRegSaveKey(NDRCALL):

457 opnum = 20

458 structure = (

459 ('hKey', RPC_HKEY),

460 ('lpFile', RRP_UNICODE_STRING),

461 ('pSecurityAttributes', PRPC_SECURITY_ATTRIBUTES),

462 )

463

464 class BaseRegSaveKeyResponse(NDRCALL):

465 structure = (

466 ('ErrorCode', error_status_t),

467 )

468

469# 3.1.5.21 BaseRegSetKeySecurity (Opnum 21)

470 class BaseRegSetKeySecurity(NDRCALL):

471 opnum = 21

472 structure = (

473 ('hKey', RPC_HKEY),

474 ('SecurityInformation', SECURITY_INFORMATION),

475 ('pRpcSecurityDescriptor', RPC_SECURITY_DESCRIPTOR),

476 )

477

478 class BaseRegSetKeySecurityResponse(NDRCALL):

479 structure = (

480 ('ErrorCode', error_status_t),

481 )

482

483# 3.1.5.22 BaseRegSetValue (Opnum 22)

484 class 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 )

493

494 class BaseRegSetValueResponse(NDRCALL):

495 structure = (

496 ('ErrorCode', error_status_t),

497 )

498

499# 3.1.5.23 BaseRegUnLoadKey (Opnum 23)

500 class BaseRegUnLoadKey(NDRCALL):

501 opnum = 23

502 structure = (

503 ('hKey', RPC_HKEY),

504 ('lpSubKey', RRP_UNICODE_STRING),

505 )

506

507 class BaseRegUnLoadKeyResponse(NDRCALL):

508 structure = (

509 ('ErrorCode', error_status_t),

510 )

511

512# 3.1.5.24 BaseRegGetVersion (Opnum 26)

513 class BaseRegGetVersion(NDRCALL):

514 opnum = 26

515 structure = (

516 ('hKey', RPC_HKEY),

517 )

518

519 class BaseRegGetVersionResponse(NDRCALL):

520 structure = (

521 ('lpdwVersion', DWORD),

522 ('ErrorCode', error_status_t),

523 )

524

525# 3.1.5.25 OpenCurrentConfig (Opnum 27)

526 class OpenCurrentConfig(NDRCALL):

527 opnum = 27

528 structure = (

529 ('ServerName', PREGISTRY_SERVER_NAME),

530 ('samDesired', REGSAM),

531 )

532

533 class OpenCurrentConfigResponse(NDRCALL):

534 structure = (

535 ('phKey', RPC_HKEY),

536 ('ErrorCode', error_status_t),

537 )

538

539# 3.1.5.26 BaseRegQueryMultipleValues (Opnum 29)

540 class 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 )

549

550 class BaseRegQueryMultipleValuesResponse(NDRCALL):

551 structure = (

552 ('val_listOut', RVALENT_ARRAY),

553 ('lpvalueBuf', PBYTE_ARRAY),

554 ('ldwTotsize', DWORD),

555 ('ErrorCode', error_status_t),

556 )

557

558# 3.1.5.27 BaseRegSaveKeyEx (Opnum 31)

559 class 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 )

567

568 class BaseRegSaveKeyExResponse(NDRCALL):

569 structure = (

570 ('ErrorCode', error_status_t),

571 )

572

573# 3.1.5.28 OpenPerformanceText (Opnum 32)

574 class OpenPerformanceText(NDRCALL):

575 opnum = 32

576 structure = (

577 ('ServerName', PREGISTRY_SERVER_NAME),

578 ('samDesired', REGSAM),

579 )

580

581 class OpenPerformanceTextResponse(NDRCALL):

582 structure = (

583 ('phKey', RPC_HKEY),

584 ('ErrorCode', error_status_t),

585 )

586

587# 3.1.5.29 OpenPerformanceNlsText (Opnum 33)

588 class OpenPerformanceNlsText(NDRCALL):

589 opnum = 33

590 structure = (

591 ('ServerName', PREGISTRY_SERVER_NAME),

592 ('samDesired', REGSAM),

593 )

594

595 class OpenPerformanceNlsTextResponse(NDRCALL):

596 structure = (

597 ('phKey', RPC_HKEY),

598 ('ErrorCode', error_status_t),

599 )

600

601# 3.1.5.30 BaseRegQueryMultipleValues2 (Opnum 34)

602 class 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 )

611

612 class BaseRegQueryMultipleValues2Response(NDRCALL):

613 structure = (

614 ('val_listOut', RVALENT_ARRAY),

615 ('lpvalueBuf', PBYTE_ARRAY),

616 ('ldwRequiredSize', DWORD),

617 ('ErrorCode', error_status_t),

618 )

619

620# 3.1.5.31 BaseRegDeleteKeyEx (Opnum 35)

621 class BaseRegDeleteKeyEx(NDRCALL):

622 opnum = 35

623 structure = (

624 ('hKey', RPC_HKEY),

625 ('lpSubKey', RRP_UNICODE_STRING),

626 ('AccessMask', REGSAM),

627 ('Reserved', DWORD),

628 )

629

630 class BaseRegDeleteKeyExResponse(NDRCALL):

631 structure = (

632 ('ErrorCode', error_status_t),

633 )

634

635################################################################################

636# OPNUMs and their corresponding structures

637################################################################################

638 OPNUMS = {

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),

649 10 : (BaseRegEnumValue, BaseRegEnumValueResponse),

650 11 : (BaseRegFlushKey, BaseRegFlushKeyResponse),

651 12 : (BaseRegGetKeySecurity, BaseRegGetKeySecurityResponse),

652 13 : (BaseRegLoadKey, BaseRegLoadKeyResponse),

653 15 : (BaseRegOpenKey, BaseRegOpenKeyResponse),

654 16 : (BaseRegQueryInfoKey, BaseRegQueryInfoKeyResponse),

655 17 : (BaseRegQueryValue, BaseRegQueryValueResponse),

656 18 : (BaseRegReplaceKey, BaseRegReplaceKeyResponse),

657 19 : (BaseRegRestoreKey, BaseRegRestoreKeyResponse),

658 20 : (BaseRegSaveKey, BaseRegSaveKeyResponse),

659 21 : (BaseRegSetKeySecurity, BaseRegSetKeySecurityResponse),

660 22 : (BaseRegSetValue, BaseRegSetValueResponse),

661 23 : (BaseRegUnLoadKey, BaseRegUnLoadKeyResponse),

662 26 : (BaseRegGetVersion, BaseRegGetVersionResponse),

663 27 : (OpenCurrentConfig, OpenCurrentConfigResponse),

664 29 : (BaseRegQueryMultipleValues, BaseRegQueryMultipleValuesResponse),

665 31 : (BaseRegSaveKeyEx, BaseRegSaveKeyExResponse),

666 32 : (OpenPerformanceText, OpenPerformanceTextResponse),

667 33 : (OpenPerformanceNlsText, OpenPerformanceNlsTextResponse),

668 34 : (BaseRegQueryMultipleValues2, BaseRegQueryMultipleValues2Response),

669 35 : (BaseRegDeleteKeyEx, BaseRegDeleteKeyExResponse),

670}

671

672################################################################################

673# HELPER FUNCTIONS

674################################################################################

675 def checkNullString(string):

676 if string == NULL:

677 return string

678

679 if string[-1:] != '\x00':

680 return string + '\x00'

681 else:

682 return string

683

684 def 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

713

714 return retData

715

716 def 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)

733

734 return retData

735

736 def hOpenClassesRoot(dce, samDesired = MAXIMUM_ALLOWED):

737 request = OpenClassesRoot()

738 request['ServerName'] = NULL

739 request['samDesired'] = samDesired

740 return dce.request(request)

741

742 def hOpenCurrentUser(dce, samDesired = MAXIMUM_ALLOWED):

743 request = OpenCurrentUser()

744 request['ServerName'] = NULL

745 request['samDesired'] = samDesired

746 return dce.request(request)

747

748 def hOpenLocalMachine(dce, samDesired = MAXIMUM_ALLOWED):

749 request = OpenLocalMachine()

750 request['ServerName'] = NULL

751 request['samDesired'] = samDesired

752 return dce.request(request)

753

754 def hOpenPerformanceData(dce, samDesired = MAXIMUM_ALLOWED):

755 request = OpenPerformanceData()

756 request['ServerName'] = NULL

757 request['samDesired'] = samDesired

758 return dce.request(request)

759

760 def hOpenUsers(dce, samDesired = MAXIMUM_ALLOWED):

761 request = OpenUsers()

762 request['ServerName'] = NULL

763 request['samDesired'] = samDesired

764 return dce.request(request)

765

766 def hBaseRegCloseKey(dce, hKey):

767 request = BaseRegCloseKey()

768 request['hKey'] = hKey

769 return dce.request(request)

770

771 def 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

783

784 return dce.request(request)

785

786 def hBaseRegDeleteKey(dce, hKey, lpSubKey):

787 request = BaseRegDeleteKey()

788 request['hKey'] = hKey

789 request['lpSubKey'] = checkNullString(lpSubKey)

790 return dce.request(request)

791

792 def 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

800

801 return dce.request(request)

802

803 def hBaseRegEnumValue(dce, hKey, dwIndex, dataLen=256):

804 request = BaseRegEnumValue()

805 request['hKey'] = hKey

806 request['dwIndex'] = dwIndex

807 retries = 1

808

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

817

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

835

836 return resp

837

838 def hBaseRegFlushKey(dce, hKey):

839 request = BaseRegFlushKey()

840 request['hKey'] = hKey

841 return dce.request(request)

842

843 def 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

849

850 return dce.request(request)

851

852 def 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)

858

859 def hBaseRegUnLoadKey(dce, hKey, lpSubKey):

860 request = BaseRegUnLoadKey()

861 request['hKey'] = hKey

862 request['lpSubKey'] = checkNullString(lpSubKey)

863 return dce.request(request)

864

865 def 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)

872

873 def 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)

881

882 def hBaseRegQueryValue(dce, hKey, lpValueName, dataLen=512):

883 request = BaseRegQueryValue()

884 request['hKey'] = hKey

885 request['lpValueName'] = checkNullString(lpValueName)

886 retries = 1

887

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

907

908 # Returns

909 # ( dataType, data )

910 return resp['lpType'], unpackValue(resp['lpType'], resp['lpData'])

911

912 def 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)

919

920 def 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)

926

927 def 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)

933

934 def 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)

942

943 def hBaseRegGetVersion(dce, hKey):

944 request = BaseRegGetVersion()

945 request['hKey'] = hKey

946 return dce.request(request)

947

948 def hOpenCurrentConfig(dce, samDesired = MAXIMUM_ALLOWED):

949 request = OpenCurrentConfig()

950 request['ServerName'] = NULL

951 request['samDesired'] = samDesired

952 return dce.request(request)

953

954 def 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

959

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)

967

968 request['num_vals'] = len(request['val_listIn'])

969 request['lpvalueBuf'] = list(b' '*128)

970 request['ldwTotsize'] = 128

971

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)

979

980 return retVal

981

982 def 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)

989

990 def hOpenPerformanceText(dce, samDesired = MAXIMUM_ALLOWED):

991 request = OpenPerformanceText()

992 request['ServerName'] = NULL

993 request['samDesired'] = samDesired

994 return dce.request(request)

995

996 def hOpenPerformanceNlsText(dce, samDesired = MAXIMUM_ALLOWED):

997 request = OpenPerformanceNlsText()

998 request['ServerName'] = NULL

999 request['samDesired'] = samDesired

1000 return dce.request(request)

1001

1002 def hBaseRegDeleteValue(dce, hKey, lpValueName):

1003 request = BaseRegDeleteValue()

1004 request['hKey'] = hKey

1005 request['lpValueName'] = checkNullString(lpValueName)

1006 return dce.request(request)