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

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

## 489 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# 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#

24

25

26 from struct import unpack, pack

27

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

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

31 from impacket.dcerpc.v5.rpcrt import DCERPCException

32 from impacket import system_errors, LOG

33 from impacket.uuid import uuidtup_to_bin

34

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

36

37 class DCERPCSessionError(DCERPCException):

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

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

40

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

49

50################################################################################

51# CONSTANTS

52################################################################################

53# 2.2.2 PREGISTRY_SERVER_NAME

54 PREGISTRY_SERVER_NAME = PWCHAR

55

56# 2.2.3 error_status_t

57 error_status_t = ULONG

58

59# 2.2.5 RRP_UNICODE_STRING

60 RRP_UNICODE_STRING = RPC_UNICODE_STRING

61 PRRP_UNICODE_STRING = PRPC_UNICODE_STRING

62

63# 2.2.4 REGSAM

64 REGSAM = ULONG

65

66 KEY_QUERY_VALUE = 0x00000001

67 KEY_SET_VALUE = 0x00000002

68 KEY_CREATE_SUB_KEY = 0x00000004

69 KEY_ENUMERATE_SUB_KEYS = 0x00000008

70 KEY_CREATE_LINK = 0x00000020

71 KEY_WOW64_64KEY = 0x00000100

72 KEY_WOW64_32KEY = 0x00000200

73

74 REG_BINARY = 3

75 REG_DWORD = 4

76 REG_DWORD_LITTLE_ENDIAN = 4

77 REG_DWORD_BIG_ENDIAN = 5

78 REG_EXPAND_SZ = 2

79 REG_LINK = 6

80 REG_MULTI_SZ = 7

81 REG_NONE = 0

82 REG_QWORD = 11

83 REG_QWORD_LITTLE_ENDIAN = 11

84 REG_SZ = 1

85

86# 3.1.5.7 BaseRegCreateKey (Opnum 6)

87 REG_CREATED_NEW_KEY = 0x00000001

88 REG_OPENED_EXISTING_KEY = 0x00000002

89

90# 3.1.5.19 BaseRegRestoreKey (Opnum 19)

91# Flags

92 REG_WHOLE_HIVE_VOLATILE = 0x00000001

93 REG_REFRESH_HIVE = 0x00000002

94 REG_NO_LAZY_FLUSH = 0x00000004

95 REG_FORCE_RESTORE = 0x00000008

96

97################################################################################

98# STRUCTURES

99################################################################################

100# 2.2.1 RPC_HKEY

101 class RPC_HKEY(NDRSTRUCT):

102 structure = (

103 ('context_handle_attributes',ULONG),

104 ('context_handle_uuid',UUID),

105 )

106

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

108 NDRSTRUCT.__init__(self, data, isNDR64)

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

110

111 def isNull(self):

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

113

114# 2.2.6 RVALENT

115 class RVALENT(NDRSTRUCT):

116 structure = (

117 ('ve_valuename',PRRP_UNICODE_STRING),

118 ('ve_valuelen',DWORD),

119 ('ve_valueptr',DWORD),

120 ('ve_type',DWORD),

121 )

122

123 class RVALENT_ARRAY(NDRUniConformantVaryingArray):

124 item = RVALENT

125

126# 2.2.9 RPC_SECURITY_DESCRIPTOR

127 class BYTE_ARRAY(NDRUniConformantVaryingArray):

128 pass

129

130 class PBYTE_ARRAY(NDRPOINTER):

131 referent = (

132 ('Data', BYTE_ARRAY),

133 )

134

135 class RPC_SECURITY_DESCRIPTOR(NDRSTRUCT):

136 structure = (

137 ('lpSecurityDescriptor',PBYTE_ARRAY),

138 ('cbInSecurityDescriptor',DWORD),

139 ('cbOutSecurityDescriptor',DWORD),

140 )

141

142# 2.2.8 RPC_SECURITY_ATTRIBUTES

143 class RPC_SECURITY_ATTRIBUTES(NDRSTRUCT):

144 structure = (

145 ('nLength',DWORD),

146 ('RpcSecurityDescriptor',RPC_SECURITY_DESCRIPTOR),

147 ('bInheritHandle',BOOLEAN),

148 )

149

150 class PRPC_SECURITY_ATTRIBUTES(NDRPOINTER):

151 referent = (

152 ('Data', RPC_SECURITY_ATTRIBUTES),

153 )

154

155################################################################################

156# RPC CALLS

157################################################################################

158# 3.1.5.1 OpenClassesRoot (Opnum 0)

159 class OpenClassesRoot(NDRCALL):

160 opnum = 0

161 structure = (

162 ('ServerName', PREGISTRY_SERVER_NAME),

163 ('samDesired', REGSAM),

164 )

165

166 class OpenClassesRootResponse(NDRCALL):

167 structure = (

168 ('phKey', RPC_HKEY),

169 ('ErrorCode', error_status_t),

170 )

171

172# 3.1.5.2 OpenCurrentUser (Opnum 1)

173 class OpenCurrentUser(NDRCALL):

174 opnum = 1

175 structure = (

176 ('ServerName', PREGISTRY_SERVER_NAME),

177 ('samDesired', REGSAM),

178 )

179

180 class OpenCurrentUserResponse(NDRCALL):

181 structure = (

182 ('phKey', RPC_HKEY),

183 ('ErrorCode', error_status_t),

184 )

185

186# 3.1.5.3 OpenLocalMachine (Opnum 2)

187 class OpenLocalMachine(NDRCALL):

188 opnum = 2

189 structure = (

190 ('ServerName', PREGISTRY_SERVER_NAME),

191 ('samDesired', REGSAM),

192 )

193

194 class OpenLocalMachineResponse(NDRCALL):

195 structure = (

196 ('phKey', RPC_HKEY),

197 ('ErrorCode', error_status_t),

198 )

199

200# 3.1.5.4 OpenPerformanceData (Opnum 3)

201 class OpenPerformanceData(NDRCALL):

202 opnum = 3

203 structure = (

204 ('ServerName', PREGISTRY_SERVER_NAME),

205 ('samDesired', REGSAM),

206 )

207

208 class OpenPerformanceDataResponse(NDRCALL):

209 structure = (

210 ('phKey', RPC_HKEY),

211 ('ErrorCode', error_status_t),

212 )

213

214# 3.1.5.5 OpenUsers (Opnum 4)

215 class OpenUsers(NDRCALL):

216 opnum = 4

217 structure = (

218 ('ServerName', PREGISTRY_SERVER_NAME),

219 ('samDesired', REGSAM),

220 )

221

222 class OpenUsersResponse(NDRCALL):

223 structure = (

224 ('phKey', RPC_HKEY),

225 ('ErrorCode', error_status_t),

226 )

227

228# 3.1.5.6 BaseRegCloseKey (Opnum 5)

229 class BaseRegCloseKey(NDRCALL):

230 opnum = 5

231 structure = (

232 ('hKey', RPC_HKEY),

233 )

234

235 class BaseRegCloseKeyResponse(NDRCALL):

236 structure = (

237 ('hKey', RPC_HKEY),

238 ('ErrorCode', error_status_t),

239 )

240

241# 3.1.5.7 BaseRegCreateKey (Opnum 6)

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

253

254 class BaseRegCreateKeyResponse(NDRCALL):

255 structure = (

256 ('phkResult', RPC_HKEY),

257 ('lpdwDisposition', LPULONG),

258 ('ErrorCode', error_status_t),

259 )

260

261# 3.1.5.8 BaseRegDeleteKey (Opnum 7)

262 class BaseRegDeleteKey(NDRCALL):

263 opnum = 7

264 structure = (

265 ('hKey', RPC_HKEY),

266 ('lpSubKey', RRP_UNICODE_STRING),

267 )

268

269 class BaseRegDeleteKeyResponse(NDRCALL):

270 structure = (

271 ('ErrorCode', error_status_t),

272 )

273

274# 3.1.5.9 BaseRegDeleteValue (Opnum 8)

275 class BaseRegDeleteValue(NDRCALL):

276 opnum = 8

277 structure = (

278 ('hKey', RPC_HKEY),

279 ('lpValueName', RRP_UNICODE_STRING),

280 )

281

282 class BaseRegDeleteValueResponse(NDRCALL):

283 structure = (

284 ('ErrorCode', error_status_t),

285 )

286

287# 3.1.5.10 BaseRegEnumKey (Opnum 9)

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

297

298 class BaseRegEnumKeyResponse(NDRCALL):

299 structure = (

300 ('lpNameOut', RRP_UNICODE_STRING),

301 ('lplpClassOut', PRRP_UNICODE_STRING),

302 ('lpftLastWriteTime', PFILETIME),

303 ('ErrorCode', error_status_t),

304 )

305

306# 3.1.5.11 BaseRegEnumValue (Opnum 10)

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

318

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

328

329# 3.1.5.12 BaseRegFlushKey (Opnum 11)

330 class BaseRegFlushKey(NDRCALL):

331 opnum = 11

332 structure = (

333 ('hKey', RPC_HKEY),

334 )

335

336 class BaseRegFlushKeyResponse(NDRCALL):

337 structure = (

338 ('ErrorCode', error_status_t),

339 )

340

341# 3.1.5.13 BaseRegGetKeySecurity (Opnum 12)

342 class BaseRegGetKeySecurity(NDRCALL):

343 opnum = 12

344 structure = (

345 ('hKey', RPC_HKEY),

346 ('SecurityInformation', SECURITY_INFORMATION),

347 ('pRpcSecurityDescriptorIn', RPC_SECURITY_DESCRIPTOR),

348 )

349

350 class BaseRegGetKeySecurityResponse(NDRCALL):

351 structure = (

352 ('pRpcSecurityDescriptorOut', RPC_SECURITY_DESCRIPTOR),

353 ('ErrorCode', error_status_t),

354 )

355

356# 3.1.5.14 BaseRegLoadKey (Opnum 13)

357 class BaseRegLoadKey(NDRCALL):

358 opnum = 13

359 structure = (

360 ('hKey', RPC_HKEY),

361 ('lpSubKey', RRP_UNICODE_STRING),

362 ('lpFile', RRP_UNICODE_STRING),

363 )

364

365 class BaseRegLoadKeyResponse(NDRCALL):

366 structure = (

367 ('ErrorCode', error_status_t),

368 )

369

370# 3.1.5.15 BaseRegOpenKey (Opnum 15)

371 class BaseRegOpenKey(NDRCALL):

372 opnum = 15

373 structure = (

374 ('hKey', RPC_HKEY),

375 ('lpSubKey', RRP_UNICODE_STRING),

376 ('dwOptions', DWORD),

377 ('samDesired', REGSAM),

378 )

379

380 class BaseRegOpenKeyResponse(NDRCALL):

381 structure = (

382 ('phkResult', RPC_HKEY),

383 ('ErrorCode', error_status_t),

384 )

385

386# 3.1.5.16 BaseRegQueryInfoKey (Opnum 16)

387 class BaseRegQueryInfoKey(NDRCALL):

388 opnum = 16

389 structure = (

390 ('hKey', RPC_HKEY),

391 ('lpClassIn', RRP_UNICODE_STRING),

392 )

393

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

407

408# 3.1.5.17 BaseRegQueryValue (Opnum 17)

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

419

420 class BaseRegQueryValueResponse(NDRCALL):

421 structure = (

422 ('lpType', LPULONG),

423 ('lpData', PBYTE_ARRAY),

424 ('lpcbData', LPULONG),

425 ('lpcbLen', LPULONG),

426 ('ErrorCode', error_status_t),

427 )

428

429# 3.1.5.18 BaseRegReplaceKey (Opnum 18)

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

438

439 class BaseRegReplaceKeyResponse(NDRCALL):

440 structure = (

441 ('ErrorCode', error_status_t),

442 )

443

444# 3.1.5.19 BaseRegRestoreKey (Opnum 19)

445 class BaseRegRestoreKey(NDRCALL):

446 opnum = 19

447 structure = (

448 ('hKey', RPC_HKEY),

449 ('lpFile', RRP_UNICODE_STRING),

450 ('Flags', DWORD),

451 )

452

453 class BaseRegRestoreKeyResponse(NDRCALL):

454 structure = (

455 ('ErrorCode', error_status_t),

456 )

457

458# 3.1.5.20 BaseRegSaveKey (Opnum 20)

459 class BaseRegSaveKey(NDRCALL):

460 opnum = 20

461 structure = (

462 ('hKey', RPC_HKEY),

463 ('lpFile', RRP_UNICODE_STRING),

464 ('pSecurityAttributes', PRPC_SECURITY_ATTRIBUTES),

465 )

466

467 class BaseRegSaveKeyResponse(NDRCALL):

468 structure = (

469 ('ErrorCode', error_status_t),

470 )

471

472# 3.1.5.21 BaseRegSetKeySecurity (Opnum 21)

473 class BaseRegSetKeySecurity(NDRCALL):

474 opnum = 21

475 structure = (

476 ('hKey', RPC_HKEY),

477 ('SecurityInformation', SECURITY_INFORMATION),

478 ('pRpcSecurityDescriptor', RPC_SECURITY_DESCRIPTOR),

479 )

480

481 class BaseRegSetKeySecurityResponse(NDRCALL):

482 structure = (

483 ('ErrorCode', error_status_t),

484 )

485

486# 3.1.5.22 BaseRegSetValue (Opnum 22)

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

496

497 class BaseRegSetValueResponse(NDRCALL):

498 structure = (

499 ('ErrorCode', error_status_t),

500 )

501

502# 3.1.5.23 BaseRegUnLoadKey (Opnum 23)

503 class BaseRegUnLoadKey(NDRCALL):

504 opnum = 23

505 structure = (

506 ('hKey', RPC_HKEY),

507 ('lpSubKey', RRP_UNICODE_STRING),

508 )

509

510 class BaseRegUnLoadKeyResponse(NDRCALL):

511 structure = (

512 ('ErrorCode', error_status_t),

513 )

514

515# 3.1.5.24 BaseRegGetVersion (Opnum 26)

516 class BaseRegGetVersion(NDRCALL):

517 opnum = 26

518 structure = (

519 ('hKey', RPC_HKEY),

520 )

521

522 class BaseRegGetVersionResponse(NDRCALL):

523 structure = (

524 ('lpdwVersion', DWORD),

525 ('ErrorCode', error_status_t),

526 )

527

528# 3.1.5.25 OpenCurrentConfig (Opnum 27)

529 class OpenCurrentConfig(NDRCALL):

530 opnum = 27

531 structure = (

532 ('ServerName', PREGISTRY_SERVER_NAME),

533 ('samDesired', REGSAM),

534 )

535

536 class OpenCurrentConfigResponse(NDRCALL):

537 structure = (

538 ('phKey', RPC_HKEY),

539 ('ErrorCode', error_status_t),

540 )

541

542# 3.1.5.26 BaseRegQueryMultipleValues (Opnum 29)

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

552

553 class BaseRegQueryMultipleValuesResponse(NDRCALL):

554 structure = (

555 ('val_listOut', RVALENT_ARRAY),

556 ('lpvalueBuf', PBYTE_ARRAY),

557 ('ldwTotsize', DWORD),

558 ('ErrorCode', error_status_t),

559 )

560

561# 3.1.5.27 BaseRegSaveKeyEx (Opnum 31)

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

570

571 class BaseRegSaveKeyExResponse(NDRCALL):

572 structure = (

573 ('ErrorCode', error_status_t),

574 )

575

576# 3.1.5.28 OpenPerformanceText (Opnum 32)

577 class OpenPerformanceText(NDRCALL):

578 opnum = 32

579 structure = (

580 ('ServerName', PREGISTRY_SERVER_NAME),

581 ('samDesired', REGSAM),

582 )

583

584 class OpenPerformanceTextResponse(NDRCALL):

585 structure = (

586 ('phKey', RPC_HKEY),

587 ('ErrorCode', error_status_t),

588 )

589

590# 3.1.5.29 OpenPerformanceNlsText (Opnum 33)

591 class OpenPerformanceNlsText(NDRCALL):

592 opnum = 33

593 structure = (

594 ('ServerName', PREGISTRY_SERVER_NAME),

595 ('samDesired', REGSAM),

596 )

597

598 class OpenPerformanceNlsTextResponse(NDRCALL):

599 structure = (

600 ('phKey', RPC_HKEY),

601 ('ErrorCode', error_status_t),

602 )

603

604# 3.1.5.30 BaseRegQueryMultipleValues2 (Opnum 34)

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

614

615 class BaseRegQueryMultipleValues2Response(NDRCALL):

616 structure = (

617 ('val_listOut', RVALENT_ARRAY),

618 ('lpvalueBuf', PBYTE_ARRAY),

619 ('ldwRequiredSize', DWORD),

620 ('ErrorCode', error_status_t),

621 )

622

623# 3.1.5.31 BaseRegDeleteKeyEx (Opnum 35)

624 class BaseRegDeleteKeyEx(NDRCALL):

625 opnum = 35

626 structure = (

627 ('hKey', RPC_HKEY),

628 ('lpSubKey', RRP_UNICODE_STRING),

629 ('AccessMask', REGSAM),

630 ('Reserved', DWORD),

631 )

632

633 class BaseRegDeleteKeyExResponse(NDRCALL):

634 structure = (

635 ('ErrorCode', error_status_t),

636 )

637

638################################################################################

639# OPNUMs and their corresponding structures

640################################################################################

641 OPNUMS = {

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

652 10 : (BaseRegEnumValue, BaseRegEnumValueResponse),

653 11 : (BaseRegFlushKey, BaseRegFlushKeyResponse),

654 12 : (BaseRegGetKeySecurity, BaseRegGetKeySecurityResponse),

655 13 : (BaseRegLoadKey, BaseRegLoadKeyResponse),

656 15 : (BaseRegOpenKey, BaseRegOpenKeyResponse),

657 16 : (BaseRegQueryInfoKey, BaseRegQueryInfoKeyResponse),

658 17 : (BaseRegQueryValue, BaseRegQueryValueResponse),

659 18 : (BaseRegReplaceKey, BaseRegReplaceKeyResponse),

660 19 : (BaseRegRestoreKey, BaseRegRestoreKeyResponse),

661 20 : (BaseRegSaveKey, BaseRegSaveKeyResponse),

662 21 : (BaseRegSetKeySecurity, BaseRegSetKeySecurityResponse),

663 22 : (BaseRegSetValue, BaseRegSetValueResponse),

664 23 : (BaseRegUnLoadKey, BaseRegUnLoadKeyResponse),

665 26 : (BaseRegGetVersion, BaseRegGetVersionResponse),

666 27 : (OpenCurrentConfig, OpenCurrentConfigResponse),

667 29 : (BaseRegQueryMultipleValues, BaseRegQueryMultipleValuesResponse),

668 31 : (BaseRegSaveKeyEx, BaseRegSaveKeyExResponse),

669 32 : (OpenPerformanceText, OpenPerformanceTextResponse),

670 33 : (OpenPerformanceNlsText, OpenPerformanceNlsTextResponse),

671 34 : (BaseRegQueryMultipleValues2, BaseRegQueryMultipleValues2Response),

672 35 : (BaseRegDeleteKeyEx, BaseRegDeleteKeyExResponse),

673}

674

675################################################################################

676# HELPER FUNCTIONS

677################################################################################

678 def checkNullString(string):

679 if string == NULL:

680 return string

681

682 if string[-1:] != '\x00': 682 ↛ 683line 682 didn't jump to line 683, because the condition on line 682 was never true

683 return string + '\x00'

684 else:

685 return string

686

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

716

717 return retData

718

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

736

737 return retData

738

739 def hOpenClassesRoot(dce, samDesired = MAXIMUM_ALLOWED):

740 request = OpenClassesRoot()

741 request['ServerName'] = NULL

742 request['samDesired'] = samDesired

743 return dce.request(request)

744

745 def hOpenCurrentUser(dce, samDesired = MAXIMUM_ALLOWED):

746 request = OpenCurrentUser()

747 request['ServerName'] = NULL

748 request['samDesired'] = samDesired

749 return dce.request(request)

750

751 def hOpenLocalMachine(dce, samDesired = MAXIMUM_ALLOWED):

752 request = OpenLocalMachine()

753 request['ServerName'] = NULL

754 request['samDesired'] = samDesired

755 return dce.request(request)

756

757 def hOpenPerformanceData(dce, samDesired = MAXIMUM_ALLOWED):

758 request = OpenPerformanceData()

759 request['ServerName'] = NULL

760 request['samDesired'] = samDesired

761 return dce.request(request)

762

763 def hOpenUsers(dce, samDesired = MAXIMUM_ALLOWED):

764 request = OpenUsers()

765 request['ServerName'] = NULL

766 request['samDesired'] = samDesired

767 return dce.request(request)

768

769 def hBaseRegCloseKey(dce, hKey):

770 request = BaseRegCloseKey()

771 request['hKey'] = hKey

772 return dce.request(request)

773

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

786

787 return dce.request(request)

788

789 def hBaseRegDeleteKey(dce, hKey, lpSubKey):

790 request = BaseRegDeleteKey()

791 request['hKey'] = hKey

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

793 return dce.request(request)

794

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

803

804 return dce.request(request)

805

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

807 request = BaseRegEnumValue()

808 request['hKey'] = hKey

809 request['dwIndex'] = dwIndex

810 retries = 1

811

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

820

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

838

839 return resp

840

841 def hBaseRegFlushKey(dce, hKey):

842 request = BaseRegFlushKey()

843 request['hKey'] = hKey

844 return dce.request(request)

845

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

852

853 return dce.request(request)

854

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

861

862 def hBaseRegUnLoadKey(dce, hKey, lpSubKey):

863 request = BaseRegUnLoadKey()

864 request['hKey'] = hKey

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

866 return dce.request(request)

867

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

875

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

884

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

886 request = BaseRegQueryValue()

887 request['hKey'] = hKey

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

889 retries = 1

890

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

910

911 # Returns

912 # ( dataType, data )

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

914

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

922

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

929

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

936

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

945

946 def hBaseRegGetVersion(dce, hKey):

947 request = BaseRegGetVersion()

948 request['hKey'] = hKey

949 return dce.request(request)

950

951 def hOpenCurrentConfig(dce, samDesired = MAXIMUM_ALLOWED):

952 request = OpenCurrentConfig()

953 request['ServerName'] = NULL

954 request['samDesired'] = samDesired

955 return dce.request(request)

956

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

962

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)

970

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

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

973 request['ldwTotsize'] = 128

974

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)

982

983 return retVal

984

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

992

993 def hOpenPerformanceText(dce, samDesired = MAXIMUM_ALLOWED):

994 request = OpenPerformanceText()

995 request['ServerName'] = NULL

996 request['samDesired'] = samDesired

997 return dce.request(request)

998

999 def hOpenPerformanceNlsText(dce, samDesired = MAXIMUM_ALLOWED):

1000 request = OpenPerformanceNlsText()

1001 request['ServerName'] = NULL

1002 request['samDesired'] = samDesired

1003 return dce.request(request)

1004

1005 def hBaseRegDeleteValue(dce, hKey, lpValueName):

1006 request = BaseRegDeleteValue()

1007 request['hKey'] = hKey

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

1009 return dce.request(request)