|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
sddump.c
Abstract:
Debugger Extension Api
Author:
Baskar Kothandaraman (baskark) 26-Jan-1998
Environment:
Kernel Mode
Revision History:
Kshitiz K. Sharma (kksharma)
Using debugger type info : SID and ACL have exactly same type definitions on all platforms - No change.
--*/
#include "precomp.h"
#pragma hdrstop
/*
+-------------------------------------------------------------------+
NAME: sid_successfully_read
FUNCTION: Tries to read in a SID from the specified address. It first reads in the minimal structure, then allocates a buffer big enough to hold the whole sid & reads in the whole SID....
ARGS: Address -- Address from which to read it from sid_buffer -- variable to receive the ptr to the allocated buffer with the SID.
RETURN: TRUE on success, FALSE otherwise.
NOTE***: The caller has to call free(*sid_buffer) to free up the memory upon a successful call to this function.
+-------------------------------------------------------------------+ */
BOOLEAN sid_successfully_read( ULONG64 Address, PSID *sid_buffer ) { ULONG result; SID minimum; /* minimum we need to read to get the details */
*sid_buffer = NULL;
if ( !ReadMemory( Address, &minimum, sizeof(minimum), &result) ) { dprintf("%08p: Unable to get MIN SID header\n", Address); return FALSE; }
/* Now of read-in any extra sub-authorities necessary */
if (minimum.SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { dprintf("SID has an invalid sub-authority_count, 0x%x\n", minimum.SubAuthorityCount); return FALSE; } else { ULONG size_to_read = RtlLengthRequiredSid(minimum.SubAuthorityCount);
*sid_buffer = malloc(size_to_read);
if (! *sid_buffer) { dprintf("SID: can't allocate memory to read\n"); return FALSE; }
if ( !ReadMemory( Address, *sid_buffer, size_to_read, &result) ) { dprintf("%08p: Unable to get The Whole SID\n", Address); free(*sid_buffer); *sid_buffer = NULL; return FALSE; }
if (! RtlValidSid(*sid_buffer)) { dprintf("%08p: SID pointed to by this address is invalid\n", Address); free(*sid_buffer); *sid_buffer = NULL; return FALSE; }
}
return TRUE; }
/*
+-------------------------------------------------------------------+
NAME: acl_successfully_read
FUNCTION: Tries to read in a ACL from the specified address. It first reads in the minimal structure, then allocates a buffer big enough to hold the whole acl & reads in the whole ACL....
ARGS: Address -- Address from which to read it from acl_buffer -- variable to receive the ptr to the allocated buffer with the ACL.
RETURN: TRUE on success, FALSE otherwise.
NOTE***: The caller has to call free(*acl_buffer) to free up the memory upon a successful call to this function.
+-------------------------------------------------------------------+ */
BOOLEAN acl_successfully_read( ULONG64 Address, PACL *acl_buffer ) { ULONG result; ACL minimum; /* minimum we need to read to get the details */
*acl_buffer = NULL;
if ( !ReadMemory( Address, &minimum, sizeof(minimum), &result) ) { dprintf("%08p: Unable to get MIN ACL header\n", Address); return FALSE; }
*acl_buffer = malloc(minimum.AclSize);
if (! *acl_buffer) { dprintf("ACL: can't allocate memory to read\n"); return FALSE; }
if ( !ReadMemory( Address, *acl_buffer, minimum.AclSize, &result) ) { dprintf("%08p: Unable to get The Whole ACL\n", Address); free(*acl_buffer); *acl_buffer = NULL; return FALSE; }
if (! RtlValidAcl(*acl_buffer)) { dprintf("%08p: ACL pointed to by this address is invalid\n", Address); free(*acl_buffer); *acl_buffer = NULL; return FALSE; }
return TRUE; }
/*
+-------------------------------------------------------------------+
NAME: DumpSID
FUNCTION: Prints out a SID, with the padding provided.
ARGS: pad -- Padding to print before the SID. sid_to_dump -- Pointer to the SID to print. Flag -- To control options.
RETURN: N/A
NOTE***: It right now, doesn't lookup the sid. In future, you might want ot use the Flag parameter to make that optional.
+-------------------------------------------------------------------+ */
VOID DumpSID( CHAR *pad, PSID sid_to_dump, ULONG Flag ) { NTSTATUS ntstatus; UNICODE_STRING us;
if (sid_to_dump) { ntstatus = RtlConvertSidToUnicodeString(&us, sid_to_dump, TRUE);
if (NT_SUCCESS(ntstatus)) { dprintf("%s%wZ", pad, &us); RtlFreeUnicodeString(&us); } else { dprintf("0x%08lx: Can't Convert SID to UnicodeString", ntstatus); } } else { dprintf("%s is NULL", pad); } if (Flag & 1) { PCSTR pszStr;
dprintf(" ");
pszStr = ConvertSidToFriendlyName(sid_to_dump, "(%s: %s\\%s)");
if (pszStr && *pszStr) {
dprintf(pszStr); } } dprintf("\n");
}
/*
+-------------------------------------------------------------------+
NAME: DumpACL
FUNCTION: Prints out a ACL, with the padding provided.
ARGS: pad -- Padding to print before the ACL. acl_to_dump -- Pointer to the ACL to print. Flag -- To control options. Start -- Actual start address of the Acl
RETURN: N/A
+-------------------------------------------------------------------+ */
BOOL DumpACL ( IN char *pad, IN ACL *pacl, IN ULONG Flags, IN ULONG64 Start ) { USHORT x;
if (pacl == NULL) { dprintf("%s is NULL\n", pad); return FALSE; }
dprintf("%s\n", pad); dprintf("%s->AclRevision: 0x%x\n", pad, pacl->AclRevision); dprintf("%s->Sbz1 : 0x%x\n", pad, pacl->Sbz1); dprintf("%s->AclSize : 0x%x\n", pad, pacl->AclSize); dprintf("%s->AceCount : 0x%x\n", pad, pacl->AceCount); dprintf("%s->Sbz2 : 0x%x\n", pad, pacl->Sbz2);
for (x = 0; x < pacl->AceCount; x ++) { PACE_HEADER ace; CHAR temp_pad[MAX_PATH]; NTSTATUS result;
_snprintf(temp_pad, sizeof(temp_pad), "%s->Ace[%u]: ", pad, x);
result = RtlGetAce(pacl, x, &ace); if (! NT_SUCCESS(result)) { dprintf("%sCan't GetAce, 0x%08lx\n", temp_pad, result); return FALSE; }
dprintf("%s->AceType: ", temp_pad);
#define BRANCH_AND_PRINT(x) case x: dprintf(#x "\n"); break
switch (ace->AceType) { BRANCH_AND_PRINT(ACCESS_ALLOWED_ACE_TYPE); BRANCH_AND_PRINT(ACCESS_DENIED_ACE_TYPE); BRANCH_AND_PRINT(SYSTEM_AUDIT_ACE_TYPE); BRANCH_AND_PRINT(SYSTEM_ALARM_ACE_TYPE); BRANCH_AND_PRINT(ACCESS_ALLOWED_COMPOUND_ACE_TYPE); BRANCH_AND_PRINT(ACCESS_ALLOWED_OBJECT_ACE_TYPE); BRANCH_AND_PRINT(ACCESS_DENIED_OBJECT_ACE_TYPE); BRANCH_AND_PRINT(SYSTEM_AUDIT_OBJECT_ACE_TYPE); BRANCH_AND_PRINT(SYSTEM_ALARM_OBJECT_ACE_TYPE);
BRANCH_AND_PRINT(ACCESS_ALLOWED_CALLBACK_ACE_TYPE); BRANCH_AND_PRINT(ACCESS_DENIED_CALLBACK_ACE_TYPE); BRANCH_AND_PRINT(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE); BRANCH_AND_PRINT(ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE); BRANCH_AND_PRINT(SYSTEM_AUDIT_CALLBACK_ACE_TYPE); BRANCH_AND_PRINT(SYSTEM_ALARM_CALLBACK_ACE_TYPE); BRANCH_AND_PRINT(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE); BRANCH_AND_PRINT(SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE);
default: dprintf("0x%08lx <-- *** Unknown AceType\n", ace->AceType); continue; // With the next ace
}
#undef BRANCH_AND_PRINT
dprintf("%s->AceFlags: 0x%x\n", temp_pad, ace->AceFlags);
#define BRANCH_AND_PRINT(x) if (ace->AceFlags & x){ dprintf("%s %s\n", temp_pad, #x); }
BRANCH_AND_PRINT(OBJECT_INHERIT_ACE) BRANCH_AND_PRINT(CONTAINER_INHERIT_ACE) BRANCH_AND_PRINT(NO_PROPAGATE_INHERIT_ACE) BRANCH_AND_PRINT(INHERIT_ONLY_ACE) BRANCH_AND_PRINT(INHERITED_ACE) BRANCH_AND_PRINT(SUCCESSFUL_ACCESS_ACE_FLAG) BRANCH_AND_PRINT(FAILED_ACCESS_ACE_FLAG)
#undef BRANCH_AND_PRINT
dprintf("%s->AceSize: 0x%x\n", temp_pad, ace->AceSize);
/*
From now on it is ace specific stuff. Fortunately ACEs can be split into 3 groups, with the ACE structure being the same within the group
Added 8 more ace types for callback support. */
switch (ace->AceType) { case ACCESS_ALLOWED_ACE_TYPE: case ACCESS_DENIED_ACE_TYPE: case SYSTEM_AUDIT_ACE_TYPE: case SYSTEM_ALARM_ACE_TYPE: { CHAR more_pad[MAX_PATH]; SYSTEM_AUDIT_ACE *tace = (SYSTEM_AUDIT_ACE *) ace;
dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
_snprintf(more_pad, sizeof(more_pad), "%s->SID: ", temp_pad); DumpSID(more_pad, &(tace->SidStart), Flags); } break;
case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: case ACCESS_DENIED_CALLBACK_ACE_TYPE: case SYSTEM_AUDIT_CALLBACK_ACE_TYPE: case SYSTEM_ALARM_CALLBACK_ACE_TYPE:
{ CHAR more_pad[MAX_PATH]; SYSTEM_AUDIT_ACE *tace = (SYSTEM_AUDIT_ACE *) ace;
dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask);
_snprintf(more_pad, sizeof(more_pad), "%s->SID: ", temp_pad); DumpSID(more_pad, &(tace->SidStart), Flags); dprintf("%s->Address : %08p\n", temp_pad, Start + (ULONG) (((PUCHAR) ace) - ((PUCHAR) pacl))); } break;
case ACCESS_ALLOWED_COMPOUND_ACE_TYPE: { CHAR more_pad[MAX_PATH]; COMPOUND_ACCESS_ALLOWED_ACE *tace = (COMPOUND_ACCESS_ALLOWED_ACE *) ace; PBYTE ptr;
dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask); dprintf("%s->CompoundAceType : 0x%08lx\n", temp_pad, tace->CompoundAceType); dprintf("%s->Reserved : 0x%08lx\n", temp_pad, tace->Reserved);
_snprintf(more_pad, sizeof(more_pad), "%s->SID(1) : ", temp_pad); DumpSID(more_pad, &(tace->SidStart), Flags);
ptr = (PBYTE)&(tace->SidStart); ptr += RtlLengthSid((PSID)ptr); /* Skip this & get to next sid */
_snprintf(more_pad, sizeof(more_pad), "%s->SID(2) : ", temp_pad); DumpSID(more_pad, ptr, Flags); } break;
case ACCESS_ALLOWED_OBJECT_ACE_TYPE: case ACCESS_DENIED_OBJECT_ACE_TYPE: case SYSTEM_AUDIT_OBJECT_ACE_TYPE: case SYSTEM_ALARM_OBJECT_ACE_TYPE: { CHAR more_pad[MAX_PATH]; ACCESS_ALLOWED_OBJECT_ACE *tace = (ACCESS_ALLOWED_OBJECT_ACE *) ace; PBYTE ptr; GUID *obj_guid = NULL, *inh_obj_guid = NULL;
dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask); dprintf("%s->Flags : 0x%08lx\n", temp_pad, tace->Flags);
ptr = (PBYTE)&(tace->ObjectType);
if (tace->Flags & ACE_OBJECT_TYPE_PRESENT) { dprintf("%s : ACE_OBJECT_TYPE_PRESENT\n", temp_pad); obj_guid = &(tace->ObjectType); ptr = (PBYTE)&(tace->InheritedObjectType); }
if (tace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { dprintf("%s : ACE_INHERITED_OBJECT_TYPE_PRESENT\n", temp_pad); inh_obj_guid = &(tace->InheritedObjectType); ptr = (PBYTE)&(tace->SidStart); }
if (obj_guid) { dprintf("%s->ObjectType : (in HEX)", temp_pad); dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n", obj_guid->Data1, obj_guid->Data2, obj_guid->Data3, obj_guid->Data4[0], obj_guid->Data4[1], obj_guid->Data4[2], obj_guid->Data4[3], obj_guid->Data4[4], obj_guid->Data4[5], obj_guid->Data4[6], obj_guid->Data4[7] ); }
if (inh_obj_guid) { dprintf("%s->InhObjTYpe : (in HEX)", temp_pad); dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n", inh_obj_guid->Data1, inh_obj_guid->Data2, inh_obj_guid->Data3, inh_obj_guid->Data4[0], inh_obj_guid->Data4[1], inh_obj_guid->Data4[2], inh_obj_guid->Data4[3], inh_obj_guid->Data4[4], inh_obj_guid->Data4[5], inh_obj_guid->Data4[6], inh_obj_guid->Data4[7] ); }
_snprintf(more_pad, sizeof(more_pad), "%s->SID : ", temp_pad); DumpSID(more_pad, ptr, Flags); } break;
case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE: { CHAR more_pad[MAX_PATH]; ACCESS_ALLOWED_OBJECT_ACE *tace = (ACCESS_ALLOWED_OBJECT_ACE *) ace; PBYTE ptr; GUID *obj_guid = NULL, *inh_obj_guid = NULL;
dprintf("%s->Mask : 0x%08lx\n", temp_pad, tace->Mask); dprintf("%s->Flags : 0x%08lx\n", temp_pad, tace->Flags);
ptr = (PBYTE)&(tace->ObjectType);
if (tace->Flags & ACE_OBJECT_TYPE_PRESENT) { dprintf("%s : ACE_OBJECT_TYPE_PRESENT\n", temp_pad); obj_guid = &(tace->ObjectType); ptr = (PBYTE)&(tace->InheritedObjectType); }
if (tace->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { dprintf("%s : ACE_INHERITED_OBJECT_TYPE_PRESENT\n", temp_pad); inh_obj_guid = &(tace->InheritedObjectType); ptr = (PBYTE)&(tace->SidStart); }
if (obj_guid) { dprintf("%s->ObjectType : (in HEX)", temp_pad); dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n", obj_guid->Data1, obj_guid->Data2, obj_guid->Data3, obj_guid->Data4[0], obj_guid->Data4[1], obj_guid->Data4[2], obj_guid->Data4[3], obj_guid->Data4[4], obj_guid->Data4[5], obj_guid->Data4[6], obj_guid->Data4[7] ); }
if (inh_obj_guid) { dprintf("%s->InhObjTYpe : (in HEX)", temp_pad); dprintf("(%08lx-%04x-%04x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)\n", inh_obj_guid->Data1, inh_obj_guid->Data2, inh_obj_guid->Data3, inh_obj_guid->Data4[0], inh_obj_guid->Data4[1], inh_obj_guid->Data4[2], inh_obj_guid->Data4[3], inh_obj_guid->Data4[4], inh_obj_guid->Data4[5], inh_obj_guid->Data4[6], inh_obj_guid->Data4[7] ); }
_snprintf(more_pad, sizeof(more_pad), "%s->SID : ", temp_pad); DumpSID(more_pad, ptr, Flags); dprintf("%s->Address : %08p\n", temp_pad, Start + (ULONG) (((PUCHAR) ace) - ((PUCHAR) pacl))); } break; } dprintf("\n"); }
return TRUE; }
/*
+-------------------------------------------------------------------+
NAME: DumpSD
FUNCTION: Prints out a Security Descriptor, with the padding provided.
ARGS: pad -- Padding to print before the ACL. sd_to_dump -- Pointer to the ACL to print. owner -- Ptr to Owner SID group -- Ptr to Group SID dacl -- Ptr to DACL sacl -- Ptr to SACL Flag -- To control options. dacl_address -- Actual start address of the dacl sacl_address -- Actual start address of the sacl
RETURN: N/A
+-------------------------------------------------------------------+ */
BOOL DumpSD ( IN char *pad, IN ULONG64 sd_to_dump, IN PSID owner, IN PSID group, IN PACL dacl, IN PACL sacl, IN ULONG Flags, IN ULONG64 dacl_address, IN ULONG64 sacl_address ) { ULONG Control;
InitTypeRead(sd_to_dump, SECURITY_DESCRIPTOR); Control = (ULONG) ReadField(Control);
#define CHECK_SD_CONTROL_FOR(x)\
if (Control & x)\ {\ dprintf("%s %s\n", pad, #x);\ }\
dprintf("%s->Revision: 0x%x\n", pad, (ULONG) ReadField(Revision)); dprintf("%s->Sbz1 : 0x%x\n", pad, (ULONG) ReadField(Sbz1)); dprintf("%s->Control : 0x%x\n", pad, (ULONG) ReadField(Control));
CHECK_SD_CONTROL_FOR(SE_OWNER_DEFAULTED) CHECK_SD_CONTROL_FOR(SE_GROUP_DEFAULTED) CHECK_SD_CONTROL_FOR(SE_DACL_PRESENT) CHECK_SD_CONTROL_FOR(SE_DACL_DEFAULTED) CHECK_SD_CONTROL_FOR(SE_SACL_PRESENT) CHECK_SD_CONTROL_FOR(SE_SACL_DEFAULTED) CHECK_SD_CONTROL_FOR(SE_DACL_UNTRUSTED) CHECK_SD_CONTROL_FOR(SE_SERVER_SECURITY) CHECK_SD_CONTROL_FOR(SE_DACL_AUTO_INHERIT_REQ) CHECK_SD_CONTROL_FOR(SE_SACL_AUTO_INHERIT_REQ) CHECK_SD_CONTROL_FOR(SE_DACL_AUTO_INHERITED) CHECK_SD_CONTROL_FOR(SE_SACL_AUTO_INHERITED) CHECK_SD_CONTROL_FOR(SE_DACL_PROTECTED) CHECK_SD_CONTROL_FOR(SE_SACL_PROTECTED) CHECK_SD_CONTROL_FOR(SE_SELF_RELATIVE)
{ CHAR temp_pad[MAX_PATH];
_snprintf(temp_pad, sizeof(temp_pad), "%s->Owner : ", pad);
DumpSID(temp_pad, owner, Flags);
_snprintf(temp_pad, sizeof(temp_pad), "%s->Group : ", pad);
DumpSID(temp_pad, group, Flags);
_snprintf(temp_pad, sizeof(temp_pad), "%s->Dacl : ", pad);
DumpACL(temp_pad, dacl, Flags, dacl_address);
_snprintf(temp_pad, sizeof(temp_pad), "%s->Sacl : ", pad);
DumpACL(temp_pad, sacl, Flags, sacl_address); }
#undef CHECK_SD_CONTROL_FOR
return TRUE; }
/*
+-------------------------------------------------------------------+
NAME: sd
FUNCTION: Reads in & prints the security descriptor, from the address specified. !sd command's workhorse.
ARGS: Standard Debugger extensions, refer to DECLARE_API macro in the header files.
+-------------------------------------------------------------------+ */
DECLARE_API( sd ) { ULONG64 Address; ULONG Flags; ULONG result; PACL dacl = NULL, sacl = NULL; ULONG64 dacl_address; ULONG64 sacl_address; // SECURITY_DESCRIPTOR sd_to_dump;
PSID owner_sid = NULL, group_sid = NULL; ULONG Control;
Address = 0; Flags = 6; GetExpressionEx(args, &Address, &args); if (args && *args) Flags = (ULONG) GetExpression(args);
if (Address == 0) { dprintf("usage: !sd <SecurityDescriptor-address>\n"); goto CLEANUP; }
if ( GetFieldValue( Address, "SECURITY_DESCRIPTOR", "Control", Control) ) { dprintf("%08p: Unable to get SD contents\n", Address); goto CLEANUP; }
if (Control & SE_SELF_RELATIVE) { ULONG dacl_offset, sacl_offset;
InitTypeRead(Address, SECURITY_DESCRIPTOR_RELATIVE);
dacl_offset = (ULONG) ReadField(Dacl); sacl_offset = (ULONG) ReadField(Sacl);
if (!(Control & SE_OWNER_DEFAULTED)) /* read in the owner */ { ULONG owner_offset = (ULONG) ReadField(Owner);
if (owner_offset != 0) { ULONG64 owner_address = Address + owner_offset; if (! sid_successfully_read(owner_address, & owner_sid)) { dprintf("%08p: Unable to read in Owner in SD\n", owner_address); goto CLEANUP; } } }
if (!(Control & SE_GROUP_DEFAULTED)) /* read in the group */ { ULONG group_offset = (ULONG) ReadField(Group);
if (group_offset != 0) { ULONG64 group_address = Address + group_offset;
if (! sid_successfully_read(group_address, & group_sid)) { dprintf("%08p: Unable to read in Group in SD\n", group_address); goto CLEANUP; } } }
if ((Control & SE_DACL_PRESENT) && (dacl_offset != 0)) { dacl_address = Address + dacl_offset;
if (! acl_successfully_read(dacl_address, & dacl)) { dprintf("%08p: Unable to read in Dacl in SD\n", dacl_address); goto CLEANUP; } }
if ((Control & SE_SACL_PRESENT) && (sacl_offset != 0)) { sacl_address = Address + sacl_offset;
if (! acl_successfully_read(sacl_address, & sacl)) { dprintf("%08p: Unable to read in Sacl in SD\n", sacl_address); goto CLEANUP; } } } else { ULONG64 Dacl, Sacl; InitTypeRead(Address, SECURITY_DESCRIPTOR);
Dacl = ReadField(Dacl); Sacl = ReadField(Sacl);
if (!(Control & SE_OWNER_DEFAULTED)) /* read in the owner */ { ULONG64 owner_address = ReadField(Owner);
if (owner_address != 0 && ! sid_successfully_read(owner_address, & owner_sid)) { dprintf("%08p: Unable to read in Owner in SD\n", owner_address); goto CLEANUP; } }
if (!(Control & SE_GROUP_DEFAULTED)) /* read in the group */ { ULONG64 group_address = ReadField(Group);
if (group_address != 0 && ! sid_successfully_read(group_address, & group_sid)) { dprintf("%08p: Unable to read in Group in SD\n", group_address); goto CLEANUP; } }
if ((Control & SE_DACL_PRESENT) && (Dacl != 0)) { dacl_address = Dacl;
if (! acl_successfully_read(dacl_address, & dacl)) { dprintf("%08p: Unable to read in Dacl in SD\n", dacl_address); goto CLEANUP; } }
if ((Control & SE_SACL_PRESENT) && (Sacl != 0)) { sacl_address = (Sacl);
if (! acl_successfully_read(sacl_address, & sacl)) { dprintf("%08p: Unable to read in Sacl in SD\n", sacl_address); goto CLEANUP; } } }
DumpSD("", Address, owner_sid, group_sid, dacl, sacl, Flags, dacl_address, sacl_address);
CLEANUP:
if (owner_sid) { free(owner_sid); }
if (group_sid) { free(group_sid); }
if (dacl) { free(dacl); }
if (sacl) { free(sacl); } return S_OK; }
PSTR g_SidAttrType = "nt!_SID_AND_ATTRIBUTES";
ULONG64 GetSidAddr(ULONG64 BaseAddress) { ULONG64 Addr; if (GetFieldValue(BaseAddress, g_SidAttrType, "Sid", Addr)) { dprintf("Cannot read %s.Sid @ %p\n", g_SidAttrType, BaseAddress); return 0; } return Addr; }
ULONG GetSidAttributes(ULONG64 BaseAddress) { ULONG Attributes;
if (GetFieldValue(BaseAddress, g_SidAttrType, "Attributes", Attributes)) { dprintf("Cannot read %s.Attributes @%p\n", g_SidAttrType, BaseAddress); return 0; } return Attributes; }
typedef BOOL (* PFuncLookupAccountSidA)( IN LPCSTR lpSystemName, IN PSID Sid, OUT LPSTR Name, IN OUT LPDWORD cbName, OUT LPSTR ReferencedDomainName, IN OUT LPDWORD cbReferencedDomainName, OUT PSID_NAME_USE peUse );
BOOL WINAPI LsaLookupAccountSidA( IN LPCSTR lpSystemName, IN PSID Sid, OUT LPSTR Name, IN OUT LPDWORD cbName, OUT LPSTR ReferencedDomainName, IN OUT LPDWORD cbReferencedDomainName, OUT PSID_NAME_USE peUse ) { PFuncLookupAccountSidA pFuncLookupAccountSidA = NULL; BOOL bRetval = FALSE;
HMODULE hLib = LoadLibrary("advapi32.dll"); if (hLib) { pFuncLookupAccountSidA = (PFuncLookupAccountSidA) GetProcAddress(hLib, "LookupAccountSidA");
if (pFuncLookupAccountSidA) { bRetval = pFuncLookupAccountSidA(lpSystemName, Sid, Name, cbName, ReferencedDomainName, cbReferencedDomainName, peUse); }
FreeLibrary(hLib); }
return bRetval;
}
PCSTR GetSidTypeStr(IN SID_NAME_USE eUse) { static PCSTR acszSidTypeStr[] = { "Invalid", "User", "Group", "Domain", "Alias", "Well Known Group", "Deleted Account", "Invalid", "Unknown", "Computer", };
if (eUse < SidTypeUser || eUse > SidTypeComputer) { dprintf( "Unrecognized SID"); return NULL; }
return acszSidTypeStr[eUse]; }
PCSTR ConvertSidToFriendlyName(IN SID* pSid, IN PCSTR pszFmt) { HRESULT hRetval = E_FAIL;
static CHAR szSid[MAX_PATH] = {0};
CHAR szName[MAX_PATH] = {0}; CHAR szDomainName[MAX_PATH] ={0}; SID_NAME_USE eUse = SidTypeInvalid; DWORD cbName = sizeof(szName) - 1; DWORD cbDomainName = sizeof(szDomainName) - 1; PCSTR pszSidTypeStr;
if (CheckControlC()) { return NULL; }
//
// null terminates szSid
//
szSid[0] = 0;
hRetval = LsaLookupAccountSidA(NULL, pSid, szName, &cbName, szDomainName, &cbDomainName, &eUse) ? S_OK : GetLastError() + 0x80000000;
if (SUCCEEDED(hRetval)) {
pszSidTypeStr = GetSidTypeStr(eUse); if (!pszSidTypeStr) { return NULL; } hRetval = _snprintf(szSid, sizeof(szSid) -1, pszFmt, pszSidTypeStr, *szDomainName ? szDomainName : "localhost", szName) >= 0 ? S_OK : HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
if (FAILED(hRetval) && (ERROR_NONE_MAPPED != HRESULT_CODE(hRetval))) {
dprintf("ConvertSidToFriendlyName on failed with error code %#x\n", hRetval);
return NULL; }
//
// Indicate none mapped if so
//
if (!*szSid) {
_snprintf(szSid, sizeof(szSid) - 1, "(no name mapped)"); }
return szSid; }
void ShowSid(IN PCSTR pszPad, IN ULONG64 addrSid, IN ULONG fOptions) { PSID sid_to_dump = NULL; if (!addrSid) {
dprintf("%s(null)\n", pszPad); return; }
if (! sid_successfully_read(addrSid, & sid_to_dump)) { dprintf("%s%08p: Unable to read in SID\n", pszPad,addrSid); return ; }
DumpSID((PCHAR) pszPad, sid_to_dump, fOptions);
if (sid_to_dump) { free (sid_to_dump); } }
/*
+-------------------------------------------------------------------+
NAME: sid
FUNCTION: Reads in & prints the SID, from the address specified. !sid command's workhorse.
ARGS: Standard Debugger extensions, refer to DECLARE_API macro in the header files.
+-------------------------------------------------------------------+ */
DECLARE_API( sid ) { ULONG64 Address; ULONG Flags; ULONG result; PSID sid_to_dump = NULL; NTSTATUS ntstatus; UNICODE_STRING us;
Address = 0; Flags = 6; GetExpressionEx(args, &Address, &args); if (args && *args) Flags = (ULONG) GetExpression(args);
if (Address == 0) { dprintf("usage: !sid <SID-address>\n"); return E_INVALIDARG; }
if (! sid_successfully_read(Address, & sid_to_dump)) { dprintf("%08p: Unable to read in SID\n", Address); return E_INVALIDARG; }
DumpSID("SID is: ", sid_to_dump, Flags);
if (sid_to_dump) { free (sid_to_dump); } return S_OK; }
/*
+-------------------------------------------------------------------+
NAME: acl
FUNCTION: Reads in & prints the ACL, from the address specified. !acl command's workhorse.
ARGS: Standard Debugger extensions, refer to DECLARE_API macro in the header files.
+-------------------------------------------------------------------+ */
DECLARE_API( acl ) { ULONG64 Address; ULONG Flags; ULONG result; PACL acl_to_dump; NTSTATUS ntstatus; UNICODE_STRING us;
Address = 0; Flags = 6; GetExpressionEx(args, &Address, &args); if (args && *args) Flags = (ULONG) GetExpression(args); if (Address == 0) { dprintf("usage: !acl <ACL-address>\n"); return E_INVALIDARG; }
if (! acl_successfully_read(Address, & acl_to_dump)) { dprintf("%08p: Unable to read in ACL\n", Address); return E_INVALIDARG; }
DumpACL("ACL is: ", acl_to_dump, Flags, Address);
return S_OK; }
|