Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

921 lines
27 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. sddump.c
  5. Abstract:
  6. Debugger Extension Api
  7. Author:
  8. Baskar Kothandaraman (baskark) 26-Jan-1998
  9. Environment:
  10. Kernel Mode
  11. Revision History:
  12. Kshitiz K. Sharma (kksharma)
  13. Using debugger type info : SID and ACL have exactly same type definitions on
  14. all platforms - No change.
  15. --*/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. /*
  19. +-------------------------------------------------------------------+
  20. NAME: sid_successfully_read
  21. FUNCTION: Tries to read in a SID from the specified address.
  22. It first reads in the minimal structure, then
  23. allocates a buffer big enough to hold the whole sid
  24. & reads in the whole SID....
  25. ARGS: Address -- Address from which to read it from
  26. sid_buffer -- variable to receive the ptr to the
  27. allocated buffer with the SID.
  28. RETURN: TRUE on success, FALSE otherwise.
  29. NOTE***: The caller has to call free(*sid_buffer) to free
  30. up the memory upon a successful call to this
  31. function.
  32. +-------------------------------------------------------------------+
  33. */
  34. BOOLEAN sid_successfully_read(
  35. ULONG64 Address,
  36. PSID *sid_buffer
  37. )
  38. {
  39. ULONG result;
  40. SID minimum; /* minimum we need to read to get the details */
  41. *sid_buffer = NULL;
  42. if ( !ReadMemory( Address,
  43. &minimum,
  44. sizeof(minimum),
  45. &result) )
  46. {
  47. dprintf("%08p: Unable to get MIN SID header\n", Address);
  48. return FALSE;
  49. }
  50. /* Now of read-in any extra sub-authorities necessary */
  51. if (minimum.SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)
  52. {
  53. dprintf("SID has an invalid sub-authority_count, 0x%x\n", minimum.SubAuthorityCount);
  54. return FALSE;
  55. }
  56. else
  57. {
  58. ULONG size_to_read = RtlLengthRequiredSid(minimum.SubAuthorityCount);
  59. *sid_buffer = malloc(size_to_read);
  60. if (! *sid_buffer)
  61. {
  62. dprintf("SID: can't allocate memory to read\n");
  63. return FALSE;
  64. }
  65. if ( !ReadMemory( Address,
  66. *sid_buffer,
  67. size_to_read,
  68. &result) )
  69. {
  70. dprintf("%08p: Unable to get The Whole SID\n", Address);
  71. free(*sid_buffer);
  72. *sid_buffer = NULL;
  73. return FALSE;
  74. }
  75. if (! RtlValidSid(*sid_buffer))
  76. {
  77. dprintf("%08p: SID pointed to by this address is invalid\n", Address);
  78. free(*sid_buffer);
  79. *sid_buffer = NULL;
  80. return FALSE;
  81. }
  82. }
  83. return TRUE;
  84. }
  85. /*
  86. +-------------------------------------------------------------------+
  87. NAME: acl_successfully_read
  88. FUNCTION: Tries to read in a ACL from the specified address.
  89. It first reads in the minimal structure, then
  90. allocates a buffer big enough to hold the whole acl
  91. & reads in the whole ACL....
  92. ARGS: Address -- Address from which to read it from
  93. acl_buffer -- variable to receive the ptr to the
  94. allocated buffer with the ACL.
  95. RETURN: TRUE on success, FALSE otherwise.
  96. NOTE***: The caller has to call free(*acl_buffer) to free
  97. up the memory upon a successful call to this
  98. function.
  99. +-------------------------------------------------------------------+
  100. */
  101. BOOLEAN acl_successfully_read(
  102. ULONG64 Address,
  103. PACL *acl_buffer
  104. )
  105. {
  106. ULONG result;
  107. ACL minimum; /* minimum we need to read to get the details */
  108. *acl_buffer = NULL;
  109. if ( !ReadMemory( Address,
  110. &minimum,
  111. sizeof(minimum),
  112. &result) )
  113. {
  114. dprintf("%08p: Unable to get MIN ACL header\n", Address);
  115. return FALSE;
  116. }
  117. *acl_buffer = malloc(minimum.AclSize);
  118. if (! *acl_buffer)
  119. {
  120. dprintf("ACL: can't allocate memory to read\n");
  121. return FALSE;
  122. }
  123. if ( !ReadMemory( Address,
  124. *acl_buffer,
  125. minimum.AclSize,
  126. &result) )
  127. {
  128. dprintf("%08p: Unable to get The Whole ACL\n", Address);
  129. free(*acl_buffer);
  130. *acl_buffer = NULL;
  131. return FALSE;
  132. }
  133. if (! RtlValidAcl(*acl_buffer))
  134. {
  135. dprintf("%08p: ACL pointed to by this address is invalid\n", Address);
  136. free(*acl_buffer);
  137. *acl_buffer = NULL;
  138. return FALSE;
  139. }
  140. return TRUE;
  141. }
  142. /*
  143. +-------------------------------------------------------------------+
  144. NAME: DumpSID
  145. FUNCTION: Prints out a SID, with the padding provided.
  146. ARGS: pad -- Padding to print before the SID.
  147. sid_to_dump -- Pointer to the SID to print.
  148. Flag -- To control options.
  149. RETURN: N/A
  150. NOTE***: It right now, doesn't lookup the sid.
  151. In future, you might want ot use the Flag
  152. parameter to make that optional.
  153. +-------------------------------------------------------------------+
  154. */
  155. VOID DumpSID(
  156. CHAR *pad,
  157. PSID sid_to_dump,
  158. ULONG Flag
  159. )
  160. {
  161. NTSTATUS ntstatus;
  162. UNICODE_STRING us;
  163. if (sid_to_dump)
  164. {
  165. ntstatus = RtlConvertSidToUnicodeString(&us, sid_to_dump, TRUE);
  166. if (NT_SUCCESS(ntstatus))
  167. {
  168. dprintf("%s%wZ\n", pad, &us);
  169. RtlFreeUnicodeString(&us);
  170. }
  171. else
  172. {
  173. dprintf("0x%08lx: Can't Convert SID to UnicodeString\n", ntstatus);
  174. }
  175. }
  176. else
  177. {
  178. dprintf("%s is NULL\n", pad);
  179. }
  180. }
  181. /*
  182. +-------------------------------------------------------------------+
  183. NAME: DumpACL
  184. FUNCTION: Prints out a ACL, with the padding provided.
  185. ARGS: pad -- Padding to print before the ACL.
  186. acl_to_dump -- Pointer to the ACL to print.
  187. Flag -- To control options.
  188. Start -- Actual start address of the Acl
  189. RETURN: N/A
  190. +-------------------------------------------------------------------+
  191. */
  192. BOOL
  193. DumpACL (
  194. IN char *pad,
  195. IN ACL *pacl,
  196. IN ULONG Flags,
  197. IN ULONG64 Start
  198. )
  199. {
  200. USHORT x;
  201. if (pacl == NULL)
  202. {
  203. dprintf("%s is NULL\n", pad);
  204. return FALSE;
  205. }
  206. dprintf("%s\n", pad);
  207. dprintf("%s->AclRevision: 0x%x\n", pad, pacl->AclRevision);
  208. dprintf("%s->Sbz1 : 0x%x\n", pad, pacl->Sbz1);
  209. dprintf("%s->AclSize : 0x%x\n", pad, pacl->AclSize);
  210. dprintf("%s->AceCount : 0x%x\n", pad, pacl->AceCount);
  211. dprintf("%s->Sbz2 : 0x%x\n", pad, pacl->Sbz2);
  212. for (x = 0; x < pacl->AceCount; x ++)
  213. {
  214. PACE_HEADER ace;
  215. CHAR temp_pad[MAX_PATH];
  216. NTSTATUS result;
  217. sprintf(temp_pad, "%s->Ace[%u]: ", pad, x);
  218. result = RtlGetAce(pacl, x, &ace);
  219. if (! NT_SUCCESS(result))
  220. {
  221. dprintf("%sCan't GetAce, 0x%08lx\n", temp_pad, result);
  222. return FALSE;
  223. }
  224. dprintf("%s->AceType: ", temp_pad);
  225. #define BRANCH_AND_PRINT(x) case x: dprintf(#x "\n"); break
  226. switch (ace->AceType)
  227. {
  228. BRANCH_AND_PRINT(ACCESS_ALLOWED_ACE_TYPE);
  229. BRANCH_AND_PRINT(ACCESS_DENIED_ACE_TYPE);
  230. BRANCH_AND_PRINT(SYSTEM_AUDIT_ACE_TYPE);
  231. BRANCH_AND_PRINT(SYSTEM_ALARM_ACE_TYPE);
  232. BRANCH_AND_PRINT(ACCESS_ALLOWED_COMPOUND_ACE_TYPE);
  233. BRANCH_AND_PRINT(ACCESS_ALLOWED_OBJECT_ACE_TYPE);
  234. BRANCH_AND_PRINT(ACCESS_DENIED_OBJECT_ACE_TYPE);
  235. BRANCH_AND_PRINT(SYSTEM_AUDIT_OBJECT_ACE_TYPE);
  236. BRANCH_AND_PRINT(SYSTEM_ALARM_OBJECT_ACE_TYPE);
  237. BRANCH_AND_PRINT(ACCESS_ALLOWED_CALLBACK_ACE_TYPE);
  238. BRANCH_AND_PRINT(ACCESS_DENIED_CALLBACK_ACE_TYPE);
  239. BRANCH_AND_PRINT(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE);
  240. BRANCH_AND_PRINT(ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE);
  241. BRANCH_AND_PRINT(SYSTEM_AUDIT_CALLBACK_ACE_TYPE);
  242. BRANCH_AND_PRINT(SYSTEM_ALARM_CALLBACK_ACE_TYPE);
  243. BRANCH_AND_PRINT(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE);
  244. BRANCH_AND_PRINT(SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE);
  245. default:
  246. dprintf("0x%08lx <-- *** Unknown AceType\n", ace->AceType);
  247. continue; // With the next ace
  248. }
  249. #undef BRANCH_AND_PRINT
  250. dprintf("%s->AceFlags: 0x%x\n", temp_pad, ace->AceFlags);
  251. #define BRANCH_AND_PRINT(x) if (ace->AceFlags & x){ dprintf("%s %s\n", temp_pad, #x); }
  252. BRANCH_AND_PRINT(OBJECT_INHERIT_ACE)
  253. BRANCH_AND_PRINT(CONTAINER_INHERIT_ACE)
  254. BRANCH_AND_PRINT(NO_PROPAGATE_INHERIT_ACE)
  255. BRANCH_AND_PRINT(INHERIT_ONLY_ACE)
  256. BRANCH_AND_PRINT(INHERITED_ACE)
  257. BRANCH_AND_PRINT(SUCCESSFUL_ACCESS_ACE_FLAG)
  258. BRANCH_AND_PRINT(FAILED_ACCESS_ACE_FLAG)
  259. #undef BRANCH_AND_PRINT
  260. dprintf("%s->AceSize: 0x%x\n", temp_pad, ace->AceSize);
  261. /*
  262. From now on it is ace specific stuff.
  263. Fortunately ACEs can be split into 3 groups,
  264. with the ACE structure being the same within the group
  265. Added 8 more ace types for callback support.
  266. */
  267. switch (ace->AceType)
  268. {
  269. case ACCESS_ALLOWED_ACE_TYPE:
  270. case ACCESS_DENIED_ACE_TYPE:
  271. case SYSTEM_AUDIT_ACE_TYPE:
  272. case SYSTEM_ALARM_ACE_TYPE:
  273. {
  274. CHAR more_pad[MAX_PATH];
  275. SYSTEM_AUDIT_ACE *tace = (SYSTEM_AUDIT_ACE *) ace;
  276. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  277. sprintf(more_pad, "%s->SID: ", temp_pad);
  278. DumpSID(more_pad, &(tace->SidStart), Flags);
  279. }
  280. break;
  281. case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
  282. case ACCESS_DENIED_CALLBACK_ACE_TYPE:
  283. case SYSTEM_AUDIT_CALLBACK_ACE_TYPE:
  284. case SYSTEM_ALARM_CALLBACK_ACE_TYPE:
  285. {
  286. CHAR more_pad[MAX_PATH];
  287. SYSTEM_AUDIT_ACE *tace = (SYSTEM_AUDIT_ACE *) ace;
  288. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  289. sprintf(more_pad, "%s->SID: ", temp_pad);
  290. DumpSID(more_pad, &(tace->SidStart), Flags);
  291. dprintf("%s->Address : %08p\n", temp_pad, Start + (ULONG) (((PUCHAR) ace) - ((PUCHAR) pacl)));
  292. }
  293. break;
  294. case ACCESS_ALLOWED_COMPOUND_ACE_TYPE:
  295. {
  296. CHAR more_pad[MAX_PATH];
  297. COMPOUND_ACCESS_ALLOWED_ACE *tace = (COMPOUND_ACCESS_ALLOWED_ACE *) ace;
  298. PBYTE ptr;
  299. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  300. dprintf("%s->CompoundAceType : 0x%08lx\n", temp_pad, tace->CompoundAceType);
  301. dprintf("%s->Reserved : 0x%08lx\n", temp_pad, tace->Reserved);
  302. sprintf(more_pad, "%s->SID(1) : ", temp_pad);
  303. DumpSID(more_pad, &(tace->SidStart), Flags);
  304. ptr = (PBYTE)&(tace->SidStart);
  305. ptr += RtlLengthSid((PSID)ptr); /* Skip this & get to next sid */
  306. sprintf(more_pad, "%s->SID(2) : ", temp_pad);
  307. DumpSID(more_pad, ptr, Flags);
  308. }
  309. break;
  310. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  311. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  312. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  313. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  314. {
  315. CHAR more_pad[MAX_PATH];
  316. ACCESS_ALLOWED_OBJECT_ACE *tace = (ACCESS_ALLOWED_OBJECT_ACE *) ace;
  317. PBYTE ptr;
  318. GUID *obj_guid = NULL, *inh_obj_guid = NULL;
  319. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  320. dprintf("%s->Flags : 0x%08lx\n", temp_pad, tace->Flags);
  321. ptr = (PBYTE)&(tace->ObjectType);
  322. if (tace->Flags & ACE_OBJECT_TYPE_PRESENT)
  323. {
  324. dprintf("%s : ACE_OBJECT_TYPE_PRESENT\n", temp_pad);
  325. obj_guid = &(tace->ObjectType);
  326. ptr = (PBYTE)&(tace->InheritedObjectType);
  327. }
  328. if (tace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  329. {
  330. dprintf("%s : ACE_INHERITED_OBJECT_TYPE_PRESENT\n", temp_pad);
  331. inh_obj_guid = &(tace->InheritedObjectType);
  332. ptr = (PBYTE)&(tace->SidStart);
  333. }
  334. if (obj_guid)
  335. {
  336. dprintf("%s->ObjectType : (in HEX)", temp_pad);
  337. dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n",
  338. obj_guid->Data1,
  339. obj_guid->Data2,
  340. obj_guid->Data3,
  341. obj_guid->Data4[0],
  342. obj_guid->Data4[1],
  343. obj_guid->Data4[2],
  344. obj_guid->Data4[3],
  345. obj_guid->Data4[4],
  346. obj_guid->Data4[5],
  347. obj_guid->Data4[6],
  348. obj_guid->Data4[7]
  349. );
  350. }
  351. if (inh_obj_guid)
  352. {
  353. dprintf("%s->InhObjTYpe : (in HEX)", temp_pad);
  354. dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n",
  355. inh_obj_guid->Data1,
  356. inh_obj_guid->Data2,
  357. inh_obj_guid->Data3,
  358. inh_obj_guid->Data4[0],
  359. inh_obj_guid->Data4[1],
  360. inh_obj_guid->Data4[2],
  361. inh_obj_guid->Data4[3],
  362. inh_obj_guid->Data4[4],
  363. inh_obj_guid->Data4[5],
  364. inh_obj_guid->Data4[6],
  365. inh_obj_guid->Data4[7]
  366. );
  367. }
  368. sprintf(more_pad, "%s->SID : ", temp_pad);
  369. DumpSID(more_pad, ptr, Flags);
  370. }
  371. break;
  372. case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
  373. case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
  374. case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE:
  375. case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE:
  376. {
  377. CHAR more_pad[MAX_PATH];
  378. ACCESS_ALLOWED_OBJECT_ACE *tace = (ACCESS_ALLOWED_OBJECT_ACE *) ace;
  379. PBYTE ptr;
  380. GUID *obj_guid = NULL, *inh_obj_guid = NULL;
  381. dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
  382. dprintf("%s->Flags : 0x%08lx\n", temp_pad, tace->Flags);
  383. ptr = (PBYTE)&(tace->ObjectType);
  384. if (tace->Flags & ACE_OBJECT_TYPE_PRESENT)
  385. {
  386. dprintf("%s : ACE_OBJECT_TYPE_PRESENT\n", temp_pad);
  387. obj_guid = &(tace->ObjectType);
  388. ptr = (PBYTE)&(tace->InheritedObjectType);
  389. }
  390. if (tace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)
  391. {
  392. dprintf("%s : ACE_INHERITED_OBJECT_TYPE_PRESENT\n", temp_pad);
  393. inh_obj_guid = &(tace->InheritedObjectType);
  394. ptr = (PBYTE)&(tace->SidStart);
  395. }
  396. if (obj_guid)
  397. {
  398. dprintf("%s->ObjectType : (in HEX)", temp_pad);
  399. dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n",
  400. obj_guid->Data1,
  401. obj_guid->Data2,
  402. obj_guid->Data3,
  403. obj_guid->Data4[0],
  404. obj_guid->Data4[1],
  405. obj_guid->Data4[2],
  406. obj_guid->Data4[3],
  407. obj_guid->Data4[4],
  408. obj_guid->Data4[5],
  409. obj_guid->Data4[6],
  410. obj_guid->Data4[7]
  411. );
  412. }
  413. if (inh_obj_guid)
  414. {
  415. dprintf("%s->InhObjTYpe : (in HEX)", temp_pad);
  416. dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n",
  417. inh_obj_guid->Data1,
  418. inh_obj_guid->Data2,
  419. inh_obj_guid->Data3,
  420. inh_obj_guid->Data4[0],
  421. inh_obj_guid->Data4[1],
  422. inh_obj_guid->Data4[2],
  423. inh_obj_guid->Data4[3],
  424. inh_obj_guid->Data4[4],
  425. inh_obj_guid->Data4[5],
  426. inh_obj_guid->Data4[6],
  427. inh_obj_guid->Data4[7]
  428. );
  429. }
  430. sprintf(more_pad, "%s->SID : ", temp_pad);
  431. DumpSID(more_pad, ptr, Flags);
  432. dprintf("%s->Address : %08p\n", temp_pad, Start + (ULONG) (((PUCHAR) ace) - ((PUCHAR) pacl)));
  433. }
  434. break;
  435. }
  436. dprintf("\n");
  437. }
  438. return TRUE;
  439. }
  440. /*
  441. +-------------------------------------------------------------------+
  442. NAME: DumpSD
  443. FUNCTION: Prints out a Security Descriptor,
  444. with the padding provided.
  445. ARGS: pad -- Padding to print before the ACL.
  446. sd_to_dump -- Pointer to the ACL to print.
  447. owner -- Ptr to Owner SID
  448. group -- Ptr to Group SID
  449. dacl -- Ptr to DACL
  450. sacl -- Ptr to SACL
  451. Flag -- To control options.
  452. dacl_address -- Actual start address of the dacl
  453. sacl_address -- Actual start address of the sacl
  454. RETURN: N/A
  455. +-------------------------------------------------------------------+
  456. */
  457. BOOL
  458. DumpSD (
  459. IN char *pad,
  460. IN ULONG64 sd_to_dump,
  461. IN PSID owner,
  462. IN PSID group,
  463. IN PACL dacl,
  464. IN PACL sacl,
  465. IN ULONG Flags,
  466. IN ULONG64 dacl_address,
  467. IN ULONG64 sacl_address
  468. )
  469. {
  470. ULONG Control;
  471. InitTypeRead(sd_to_dump, SECURITY_DESCRIPTOR);
  472. Control = (ULONG) ReadField(Control);
  473. #define CHECK_SD_CONTROL_FOR(x)\
  474. if (Control & x)\
  475. {\
  476. dprintf("%s %s\n", pad, #x);\
  477. }\
  478. dprintf("%s->Revision: 0x%x\n", pad, (ULONG) ReadField(Revision));
  479. dprintf("%s->Sbz1 : 0x%x\n", pad, (ULONG) ReadField(Sbz1));
  480. dprintf("%s->Control : 0x%x\n", pad, (ULONG) ReadField(Control));
  481. CHECK_SD_CONTROL_FOR(SE_OWNER_DEFAULTED)
  482. CHECK_SD_CONTROL_FOR(SE_GROUP_DEFAULTED)
  483. CHECK_SD_CONTROL_FOR(SE_DACL_PRESENT)
  484. CHECK_SD_CONTROL_FOR(SE_DACL_DEFAULTED)
  485. CHECK_SD_CONTROL_FOR(SE_SACL_PRESENT)
  486. CHECK_SD_CONTROL_FOR(SE_SACL_DEFAULTED)
  487. CHECK_SD_CONTROL_FOR(SE_DACL_UNTRUSTED)
  488. CHECK_SD_CONTROL_FOR(SE_SERVER_SECURITY)
  489. CHECK_SD_CONTROL_FOR(SE_DACL_AUTO_INHERIT_REQ)
  490. CHECK_SD_CONTROL_FOR(SE_SACL_AUTO_INHERIT_REQ)
  491. CHECK_SD_CONTROL_FOR(SE_DACL_AUTO_INHERITED)
  492. CHECK_SD_CONTROL_FOR(SE_SACL_AUTO_INHERITED)
  493. CHECK_SD_CONTROL_FOR(SE_DACL_PROTECTED)
  494. CHECK_SD_CONTROL_FOR(SE_SACL_PROTECTED)
  495. CHECK_SD_CONTROL_FOR(SE_SELF_RELATIVE)
  496. {
  497. CHAR temp_pad[MAX_PATH];
  498. sprintf(temp_pad, "%s->Owner : ", pad);
  499. DumpSID(temp_pad, owner, Flags);
  500. sprintf(temp_pad, "%s->Group : ", pad);
  501. DumpSID(temp_pad, group, Flags);
  502. sprintf(temp_pad, "%s->Dacl : ", pad);
  503. DumpACL(temp_pad, dacl, Flags, dacl_address);
  504. sprintf(temp_pad, "%s->Sacl : ", pad);
  505. DumpACL(temp_pad, sacl, Flags, sacl_address);
  506. }
  507. #undef CHECK_SD_CONTROL_FOR
  508. return TRUE;
  509. }
  510. /*
  511. +-------------------------------------------------------------------+
  512. NAME: sd
  513. FUNCTION: Reads in & prints the security descriptor, from
  514. the address specified. !sd command's workhorse.
  515. ARGS: Standard Debugger extensions, refer to DECLARE_API
  516. macro in the header files.
  517. +-------------------------------------------------------------------+
  518. */
  519. DECLARE_API( sd )
  520. {
  521. ULONG64 Address;
  522. ULONG Flags;
  523. ULONG result;
  524. PACL dacl = NULL, sacl = NULL;
  525. ULONG64 dacl_address;
  526. ULONG64 sacl_address;
  527. // SECURITY_DESCRIPTOR sd_to_dump;
  528. PSID owner_sid = NULL, group_sid = NULL;
  529. ULONG Control;
  530. Address = 0;
  531. Flags = 6;
  532. sscanf(args,"%lx %lx",&Address,&Flags);
  533. Address = GetExpression(args);
  534. if (Address == 0) {
  535. dprintf("usage: !sd <SecurityDescriptor-address>\n");
  536. goto CLEANUP;
  537. }
  538. if ( GetFieldValue( Address,
  539. "SECURITY_DESCRIPTOR",
  540. "Control",
  541. Control) ) {
  542. dprintf("%08p: Unable to get SD contents\n", Address);
  543. goto CLEANUP;
  544. }
  545. if (Control & SE_SELF_RELATIVE)
  546. {
  547. ULONG dacl_offset, sacl_offset;
  548. InitTypeRead(Address, SECURITY_DESCRIPTOR_RELATIVE);
  549. dacl_offset = (ULONG) ReadField(Dacl);
  550. sacl_offset = (ULONG) ReadField(Sacl);
  551. if (!(Control & SE_OWNER_DEFAULTED)) /* read in the owner */
  552. {
  553. ULONG owner_offset = (ULONG) ReadField(Owner);
  554. ULONG64 owner_address = Address + owner_offset;
  555. if (! sid_successfully_read(owner_address, & owner_sid))
  556. {
  557. dprintf("%08p: Unable to read in Owner in SD\n", owner_address);
  558. goto CLEANUP;
  559. }
  560. }
  561. if (!(Control & SE_GROUP_DEFAULTED)) /* read in the group */
  562. {
  563. ULONG group_offset = (ULONG) ReadField(Group);
  564. ULONG64 group_address = Address + group_offset;
  565. if (! sid_successfully_read(group_address, & group_sid))
  566. {
  567. dprintf("%08p: Unable to read in Group in SD\n", group_address);
  568. goto CLEANUP;
  569. }
  570. }
  571. if ((Control & SE_DACL_PRESENT) &&
  572. (dacl_offset != 0))
  573. {
  574. dacl_address = Address + dacl_offset;
  575. if (! acl_successfully_read(dacl_address, & dacl))
  576. {
  577. dprintf("%08p: Unable to read in Dacl in SD\n", dacl_address);
  578. goto CLEANUP;
  579. }
  580. }
  581. if ((Control & SE_SACL_PRESENT) &&
  582. (sacl_offset != 0))
  583. {
  584. sacl_address = Address + sacl_offset;
  585. if (! acl_successfully_read(sacl_address, & sacl))
  586. {
  587. dprintf("%08p: Unable to read in Sacl in SD\n", sacl_address);
  588. goto CLEANUP;
  589. }
  590. }
  591. }
  592. else
  593. {
  594. ULONG64 Dacl, Sacl;
  595. InitTypeRead(Address, SECURITY_DESCRIPTOR);
  596. Dacl = ReadField(Dacl);
  597. Sacl = ReadField(Sacl);
  598. if (!(Control & SE_OWNER_DEFAULTED)) /* read in the owner */
  599. {
  600. ULONG64 owner_address = ReadField(Owner);
  601. if (! sid_successfully_read(owner_address, & owner_sid))
  602. {
  603. dprintf("%08p: Unable to read in Owner in SD\n", owner_address);
  604. goto CLEANUP;
  605. }
  606. }
  607. if (!(Control & SE_GROUP_DEFAULTED)) /* read in the group */
  608. {
  609. ULONG64 group_address = ReadField(Group);
  610. if (! sid_successfully_read(group_address, & group_sid))
  611. {
  612. dprintf("%08p: Unable to read in Group in SD\n", group_address);
  613. goto CLEANUP;
  614. }
  615. }
  616. if ((Control & SE_DACL_PRESENT) &&
  617. (Dacl != 0))
  618. {
  619. dacl_address = Dacl;
  620. if (! acl_successfully_read(dacl_address, & dacl))
  621. {
  622. dprintf("%08p: Unable to read in Dacl in SD\n", dacl_address);
  623. goto CLEANUP;
  624. }
  625. }
  626. if ((Control & SE_SACL_PRESENT) &&
  627. (Sacl != 0))
  628. {
  629. sacl_address = (Sacl);
  630. if (! acl_successfully_read(sacl_address, & sacl))
  631. {
  632. dprintf("%08p: Unable to read in Sacl in SD\n", sacl_address);
  633. goto CLEANUP;
  634. }
  635. }
  636. }
  637. DumpSD("", Address, owner_sid, group_sid, dacl, sacl, Flags, dacl_address, sacl_address);
  638. CLEANUP:
  639. if (owner_sid)
  640. {
  641. free(owner_sid);
  642. }
  643. if (group_sid)
  644. {
  645. free(group_sid);
  646. }
  647. if (dacl)
  648. {
  649. free(dacl);
  650. }
  651. if (sacl)
  652. {
  653. free(sacl);
  654. }
  655. return S_OK;
  656. }
  657. /*
  658. +-------------------------------------------------------------------+
  659. NAME: sid
  660. FUNCTION: Reads in & prints the SID, from
  661. the address specified. !sid command's workhorse.
  662. ARGS: Standard Debugger extensions, refer to DECLARE_API
  663. macro in the header files.
  664. +-------------------------------------------------------------------+
  665. */
  666. DECLARE_API( sid )
  667. {
  668. ULONG64 Address;
  669. ULONG Flags;
  670. ULONG result;
  671. PSID sid_to_dump;
  672. NTSTATUS ntstatus;
  673. UNICODE_STRING us;
  674. Address = 0;
  675. Flags = 6;
  676. sscanf(args,"%lx %lx",&Address,&Flags);
  677. Address = GetExpression(args);
  678. if (Address == 0) {
  679. dprintf("usage: !sid <SID-address>\n");
  680. return E_INVALIDARG;
  681. }
  682. if (! sid_successfully_read(Address, & sid_to_dump))
  683. {
  684. dprintf("%08p: Unable to read in SID\n", Address);
  685. return E_INVALIDARG;
  686. }
  687. DumpSID("SID is: ", sid_to_dump, Flags);
  688. return S_OK;
  689. }
  690. /*
  691. +-------------------------------------------------------------------+
  692. NAME: acl
  693. FUNCTION: Reads in & prints the ACL, from
  694. the address specified. !acl command's workhorse.
  695. ARGS: Standard Debugger extensions, refer to DECLARE_API
  696. macro in the header files.
  697. +-------------------------------------------------------------------+
  698. */
  699. DECLARE_API( acl )
  700. {
  701. ULONG64 Address;
  702. ULONG Flags;
  703. ULONG result;
  704. PACL acl_to_dump;
  705. NTSTATUS ntstatus;
  706. UNICODE_STRING us;
  707. Address = 0;
  708. Flags = 6;
  709. sscanf(args,"%lx %lx",&Address,&Flags);
  710. Address = GetExpression (args);
  711. if (Address == 0) {
  712. dprintf("usage: !acl <ACL-address>\n");
  713. return E_INVALIDARG;
  714. }
  715. if (! acl_successfully_read(Address, & acl_to_dump))
  716. {
  717. dprintf("%08p: Unable to read in ACL\n", Address);
  718. return E_INVALIDARG;
  719. }
  720. DumpACL("ACL is: ", acl_to_dump, Flags, Address);
  721. return S_OK;
  722. }