Last active
December 23, 2015 04:09
-
-
Save murachue/6578201 to your computer and use it in GitHub Desktop.
本日の6時間半に及ぶ非生産的活動の成果、またの名を「http://msdn.microsoft.com/en-us/library/aa379570(v=vs.85).aspx の出力みたいなのを求めるプログラムあるんですか」
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <tchar.h> | |
#include <sddl.h> | |
#include <stdio.h> | |
#include <string> | |
#include <vector> | |
#include <iostream> | |
#include <sstream> | |
#include <iomanip> | |
#include <strsafe.h> | |
/* | |
#include <varargs.h> | |
#include <strsafe.h> | |
void print(LPCTSTR fmt, ...) { | |
va_list va; | |
TCHAR buf[256]; | |
LPTSTR ep; | |
va_start(va, fmt); | |
StringCchVPrintfEx(buf, _countof(buf), &ep, NULL, 0, fmt, va); | |
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), buf, ep - buf, NULL, NULL); | |
} | |
*/ | |
struct tMasks { | |
DWORD mask; | |
LPCTSTR str; | |
}; | |
struct tEnums { | |
DWORD index; | |
LPCTSTR str; | |
}; | |
#define DEFITEM(d) {(d), _T(#d)} | |
struct tMasks SecurityDescriptorControl[] = { | |
DEFITEM(SE_DACL_AUTO_INHERIT_REQ), | |
DEFITEM(SE_DACL_AUTO_INHERITED), | |
DEFITEM(SE_DACL_DEFAULTED), | |
DEFITEM(SE_DACL_PRESENT), | |
DEFITEM(SE_DACL_PROTECTED), | |
DEFITEM(SE_GROUP_DEFAULTED), | |
DEFITEM(SE_OWNER_DEFAULTED), | |
DEFITEM(SE_RM_CONTROL_VALID), | |
DEFITEM(SE_SACL_AUTO_INHERIT_REQ), | |
DEFITEM(SE_SACL_AUTO_INHERITED), | |
DEFITEM(SE_SACL_DEFAULTED), | |
DEFITEM(SE_SACL_PRESENT), | |
DEFITEM(SE_SACL_PROTECTED), | |
DEFITEM(SE_SELF_RELATIVE), | |
{0, NULL} | |
}; | |
struct tMasks AccessRights[] = { | |
DEFITEM(GENERIC_ALL), | |
DEFITEM(GENERIC_READ), | |
DEFITEM(GENERIC_WRITE), | |
DEFITEM(GENERIC_EXECUTE), | |
DEFITEM(READ_CONTROL), | |
DEFITEM(DELETE), | |
DEFITEM(WRITE_DAC), | |
DEFITEM(WRITE_OWNER), | |
/* | |
Iads.h | |
typedef /* [public] * / | |
enum __MIDL___MIDL_itf_ads_0001_0048_0001 | |
{ | |
ADS_RIGHT_DELETE = 0x10000, | |
ADS_RIGHT_READ_CONTROL = 0x20000, | |
ADS_RIGHT_WRITE_DAC = 0x40000, | |
ADS_RIGHT_WRITE_OWNER = 0x80000, | |
ADS_RIGHT_SYNCHRONIZE = 0x100000, | |
ADS_RIGHT_ACCESS_SYSTEM_SECURITY = 0x1000000, | |
ADS_RIGHT_GENERIC_READ = 0x80000000, | |
ADS_RIGHT_GENERIC_WRITE = 0x40000000, | |
ADS_RIGHT_GENERIC_EXECUTE = 0x20000000, | |
ADS_RIGHT_GENERIC_ALL = 0x10000000, | |
ADS_RIGHT_DS_CREATE_CHILD = 0x1, | |
ADS_RIGHT_DS_DELETE_CHILD = 0x2, | |
ADS_RIGHT_ACTRL_DS_LIST = 0x4, | |
ADS_RIGHT_DS_SELF = 0x8, | |
ADS_RIGHT_DS_READ_PROP = 0x10, | |
ADS_RIGHT_DS_WRITE_PROP = 0x20, | |
ADS_RIGHT_DS_DELETE_TREE = 0x40, | |
ADS_RIGHT_DS_LIST_OBJECT = 0x80, | |
ADS_RIGHT_DS_CONTROL_ACCESS = 0x100 | |
} ADS_RIGHTS_ENUM; | |
*/ | |
/* | |
DEFITEM(ADS_RIGHT_DS_READ_PROP), | |
DEFITEM(ADS_RIGHT_DS_WRITE_PROP), | |
DEFITEM(ADS_RIGHT_DS_CREATE_CHILD), | |
DEFITEM(ADS_RIGHT_DS_DELETE_CHILD), | |
DEFITEM(ADS_RIGHT_ACTRL_DS_LIST), | |
DEFITEM(ADS_RIGHT_DS_SELF), | |
DEFITEM(ADS_RIGHT_DS_LIST_OBJECT), | |
DEFITEM(ADS_RIGHT_DS_DELETE_TREE), | |
DEFITEM(ADS_RIGHT_DS_CONTROL_ACCESS), | |
*/ | |
DEFITEM(SYNCHRONIZE), | |
/* | |
#define FILE_READ_DATA ( 0x0001 ) // file & pipe | |
#define FILE_LIST_DIRECTORY ( 0x0001 ) // directory | |
#define FILE_WRITE_DATA ( 0x0002 ) // file & pipe | |
#define FILE_ADD_FILE ( 0x0002 ) // directory | |
#define FILE_APPEND_DATA ( 0x0004 ) // file | |
#define FILE_ADD_SUBDIRECTORY ( 0x0004 ) // directory | |
#define FILE_CREATE_PIPE_INSTANCE ( 0x0004 ) // named pipe | |
#define FILE_READ_EA ( 0x0008 ) // file & directory | |
#define FILE_WRITE_EA ( 0x0010 ) // file & directory | |
#define FILE_EXECUTE ( 0x0020 ) // file | |
#define FILE_TRAVERSE ( 0x0020 ) // directory | |
#define FILE_DELETE_CHILD ( 0x0040 ) // directory | |
#define FILE_READ_ATTRIBUTES ( 0x0080 ) // all | |
#define FILE_WRITE_ATTRIBUTES ( 0x0100 ) // all | |
#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) | |
*/ | |
{FILE_READ_DATA, _T("FILE_READ_DATA/FILE_LIST_DIRECTORY/KEY_QUERY_VALUE/SYSTEM_MANDATORY_LABEL_NO_WRITE_UP/ADS_RIGHT_DS_CREATE_CHILD")}, | |
{FILE_WRITE_DATA, _T("FILE_WRITE_DATA/FILE_ADD_FILE/KEY_SET_VALUE/SYSTEM_MANDATORY_LABEL_NO_WRITE_UP/ADS_RIGHT_DS_DELETE_CHILD")}, | |
{FILE_APPEND_DATA, _T("FILE_APPEND_DATA/FILE_ADD_SUBDIRECTORY/CREATE_PIPE_INSTANCE/KEY_CREATE_SUB_KEY/SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP/ADS_RIGHT_ACTRL_DS_LIST")}, | |
{FILE_READ_EA, _T("FILE_READ_EA/ENUMERATE_SUB_KEYS/ADS_RIGHT_DS_SELF")}, | |
{FILE_WRITE_EA, _T("FILE_WRITE_EA/KEY_NOTIFY/ADS_RIGHT_DS_READ_PROP")}, | |
{FILE_EXECUTE, _T("FILE_EXECUTE/FILE_TRAVERSE/KEY_CREATE_LINK/ADS_RIGHT_DS_WRITE_PROP")}, | |
{FILE_DELETE_CHILD, _T("FILE_DELETE_CHILD/ADS_RIGHT_DS_DELETE_TREE")}, | |
{FILE_READ_ATTRIBUTES, _T("FILE_READ_ATTRIBUTES/ADS_RIGHT_DS_LIST_OBJECT")}, | |
{FILE_WRITE_ATTRIBUTES, _T("FILE_WRITE_ATTRIBUTES/ADS_RIGHT_DS_CONTROL_ACCESS")}, | |
/* | |
DEFITEM(FILE_ALL_ACCESS), // STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF | |
DEFITEM(FILE_GENERIC_READ), // STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE | |
DEFITEM(FILE_GENERIC_WRITE), // STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE | |
DEFITEM(FILE_GENERIC_EXECUTE), // STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE | |
*/ | |
/* | |
#define KEY_QUERY_VALUE (0x0001) | |
#define KEY_SET_VALUE (0x0002) | |
#define KEY_CREATE_SUB_KEY (0x0004) | |
#define KEY_ENUMERATE_SUB_KEYS (0x0008) | |
#define KEY_NOTIFY (0x0010) | |
#define KEY_CREATE_LINK (0x0020) | |
#define KEY_WOW64_32KEY (0x0200) | |
#define KEY_WOW64_64KEY (0x0100) | |
#define KEY_WOW64_RES (0x0300) | |
*/ | |
/* | |
DEFITEM(KEY_ALL_ACCESS), // (STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK) & (~SYNCHRONIZE) | |
DEFITEM(KEY_READ), // (STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & (~SYNCHRONIZE) | |
DEFITEM(KEY_WRITE), // (STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE) | |
DEFITEM(KEY_EXECUTE), // (KEY_READ) & (~SYNCHRONIZE) | |
*/ | |
/* | |
#define SYSTEM_MANDATORY_LABEL_NO_WRITE_UP 0x1 | |
#define SYSTEM_MANDATORY_LABEL_NO_READ_UP 0x2 | |
#define SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP 0x4 | |
*/ | |
/* | |
DEFITEM(SYSTEM_MANDATORY_LABEL_NO_READ_UP), | |
DEFITEM(SYSTEM_MANDATORY_LABEL_NO_WRITE_UP), | |
DEFITEM(SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP), | |
*/ | |
{0, NULL} | |
}; | |
struct tEnums AceType[] = { | |
DEFITEM(ACCESS_ALLOWED_ACE_TYPE), | |
DEFITEM(ACCESS_ALLOWED_CALLBACK_ACE_TYPE), | |
DEFITEM(ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE), | |
DEFITEM(ACCESS_ALLOWED_COMPOUND_ACE_TYPE), | |
DEFITEM(ACCESS_ALLOWED_OBJECT_ACE_TYPE), | |
DEFITEM(ACCESS_DENIED_ACE_TYPE), | |
DEFITEM(ACCESS_DENIED_CALLBACK_ACE_TYPE), | |
DEFITEM(ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE), | |
DEFITEM(ACCESS_DENIED_OBJECT_ACE_TYPE), | |
DEFITEM(ACCESS_MAX_MS_ACE_TYPE), | |
DEFITEM(ACCESS_MAX_MS_V2_ACE_TYPE), | |
DEFITEM(ACCESS_MAX_MS_V3_ACE_TYPE), | |
DEFITEM(ACCESS_MAX_MS_V4_ACE_TYPE), | |
DEFITEM(ACCESS_MAX_MS_OBJECT_ACE_TYPE), | |
DEFITEM(ACCESS_MIN_MS_ACE_TYPE), | |
DEFITEM(ACCESS_MIN_MS_OBJECT_ACE_TYPE), | |
DEFITEM(SYSTEM_ALARM_ACE_TYPE), | |
DEFITEM(SYSTEM_ALARM_CALLBACK_ACE_TYPE), | |
DEFITEM(SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE), | |
DEFITEM(SYSTEM_ALARM_OBJECT_ACE_TYPE), | |
DEFITEM(SYSTEM_AUDIT_ACE_TYPE), | |
DEFITEM(SYSTEM_AUDIT_CALLBACK_ACE_TYPE), | |
DEFITEM(SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE), | |
DEFITEM(SYSTEM_AUDIT_OBJECT_ACE_TYPE), | |
DEFITEM(SYSTEM_MANDATORY_LABEL_ACE_TYPE), | |
{0, NULL} | |
}; | |
struct tEnums SidNameUse[] = { | |
DEFITEM(SidTypeUser), | |
DEFITEM(SidTypeGroup), | |
DEFITEM(SidTypeDomain), | |
DEFITEM(SidTypeAlias), | |
DEFITEM(SidTypeWellKnownGroup), | |
DEFITEM(SidTypeDeletedAccount), | |
DEFITEM(SidTypeInvalid), | |
DEFITEM(SidTypeUnknown), | |
DEFITEM(SidTypeComputer), | |
DEFITEM(SidTypeLabel), | |
{0, NULL} | |
}; | |
// WTF! | |
typedef std::basic_string<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR>> tstring; | |
typedef std::basic_stringstream<TCHAR, std::char_traits<TCHAR>, std::allocator<TCHAR>> tstringstream; | |
void parseMask(std::vector<tstring> &res, struct tMasks *masks, DWORD value) { | |
res.clear(); | |
for(; masks->str; masks++) { | |
if(value & masks->mask) { | |
res.push_back(tstring(masks->str)); | |
value &= ~masks->mask; | |
} | |
} | |
if(value != 0) { | |
tstringstream ss; | |
ss << _T("Other(") << std::hex << value << _T(")"); | |
res.push_back(ss.str()); | |
} | |
} | |
void joinVector(tstring &res, tstring &delim, std::vector<tstring> vec) { | |
res.erase(); | |
for(auto it = vec.begin(); it != vec.end(); it++) { | |
if(!res.empty()) | |
res.append(delim); | |
res.append(*it); | |
} | |
} | |
BOOL parseEnum(tstring &res, struct tEnums *enums, DWORD value) { | |
for(; enums->str; enums++) { | |
if(value == enums->index) { | |
res.assign(enums->str); | |
return TRUE; | |
} | |
} | |
res.assign(_T("<unknown>")); | |
return FALSE; | |
} | |
void printSDControl(PSECURITY_DESCRIPTOR secdesc) { | |
SECURITY_DESCRIPTOR_CONTROL sdc; | |
DWORD sdcrev; | |
if(!GetSecurityDescriptorControl(secdesc, &sdc, &sdcrev)) { | |
_tprintf(_T("GetSecurityDescriptorControl failed; hr=%08x\n"), GetLastError()); | |
} else { | |
std::vector<tstring> flags; | |
parseMask(flags, SecurityDescriptorControl, sdc); | |
tstring flagstr; | |
joinVector(flagstr, tstring(_T(", ")), flags); | |
_tprintf(_T("Control rev=%d, Control=0x%x(%s)\n"), sdcrev, sdc, flagstr.c_str()); | |
} | |
} | |
LPTSTR sidToStringSid(PSID sid) { | |
LPTSTR sidstr; | |
if(sid) { | |
if(!ConvertSidToStringSid(sid, &sidstr)) { | |
_tprintf(_T("ConvertSidToStringSid failed; hr=%08x\n"), GetLastError()); | |
return NULL; | |
} | |
tstring sidname; | |
do { | |
SID_NAME_USE snu; | |
DWORD cchname = 0, cchrefdom = 0; | |
if(!LookupAccountSid(NULL, sid, NULL, &cchname, NULL, &cchrefdom, &snu)) { | |
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | |
_tprintf(_T("LookupAccountSid(measure) failed; hr=%08x\n"), GetLastError()); | |
break; | |
} | |
} | |
LPTSTR name, refdom; | |
name = (LPTSTR)LocalAlloc(LPTR, (cchname + 1) * sizeof(TCHAR)); | |
refdom = (LPTSTR)LocalAlloc(LPTR, (cchrefdom + 1) * sizeof(TCHAR)); | |
if(!LookupAccountSid(NULL, sid, name, &cchname, refdom, &cchrefdom, &snu)) { | |
_tprintf(_T("LookupAccountSid(final) failed; hr=%08x\n"), GetLastError()); | |
} else { | |
// isn't there "basic_string<...>.operator<<" ? | |
sidname.assign(sidstr); | |
sidname.append(_T(" (")); | |
sidname.append(refdom); | |
sidname.append(_T("\\")); | |
sidname.append(name); | |
sidname.append(_T(" ")); | |
tstring snustr; | |
parseEnum(snustr, SidNameUse, snu); | |
sidname.append(snustr); | |
sidname.append(_T(")")); | |
LocalFree(sidstr); | |
sidstr = (LPTSTR)LocalAlloc(LPTR, (sidname.length() + 1) * sizeof(TCHAR)); | |
StringCchCopy(sidstr, sidname.length() + 1, sidname.c_str()); | |
} | |
LocalFree(name); | |
LocalFree(refdom); | |
} while(0); | |
} else { | |
static const TCHAR nullsidstr[] = _T("<null>"); | |
sidstr = (LPTSTR)LocalAlloc(LPTR, sizeof(nullsidstr)); | |
lstrcpy(sidstr, nullsidstr); | |
} | |
return sidstr; | |
} | |
void __printSDSID(BOOL (__stdcall *getter)(PSECURITY_DESCRIPTOR, PSID *, LPBOOL), LPCTSTR gettername, LPCTSTR desc, PSECURITY_DESCRIPTOR secdesc) { | |
PSID sid; | |
BOOL defaulted; | |
if(!getter(secdesc, &sid, &defaulted)) { | |
_tprintf(_T("%s failed; hr=%08x\n"), gettername, GetLastError()); | |
return; | |
} else { | |
LPTSTR sidstr = sidToStringSid(sid); | |
if(sidstr == NULL) { | |
// error message already shown. | |
return; | |
} | |
_tprintf(_T("%s: %s, defaulted=%s\n"), desc, sidstr, defaulted ? _T("TRUE") : _T("FALSE")); | |
LocalFree(sidstr); | |
} | |
} | |
#define _printSDSID(f, d, s) __printSDSID(f, _T(#f), d, s) | |
#define printSDSID(t, s) _printSDSID(GetSecurityDescriptor##t, _T(#t), s) | |
void printSDAccessMask(ACCESS_MASK mask) { | |
std::vector<tstring> flags; | |
parseMask(flags, AccessRights, mask); | |
/* | |
tstring flagstr; | |
joinVector(flagstr, tstring(_T(", ")), flags); | |
_tprintf(_T("\t\tAccessMask=0x%x(%s)\n"), mask, flagstr.c_str()); | |
*/ | |
_tprintf(_T("\t\tAccessMask=0x%x\n"), mask); | |
for(auto it = flags.begin(); it != flags.end(); it++) { | |
_tprintf(_T("\t\t\t%s\n"), it->c_str()); | |
} | |
} | |
BOOL printSDStringSID(PSID sid) { | |
LPTSTR sidstr = sidToStringSid(sid); | |
if(sidstr == NULL) { | |
// error message already shown. | |
return FALSE; | |
} | |
_tprintf(_T("\t\tSID=%s\n"), sidstr); | |
LocalFree(sidstr); | |
return TRUE; | |
} | |
void printHexdump(LPCBYTE pbyte, INT_PTR len) { | |
int i; | |
_tprintf(_T("\t\tExtra bytes: 0x%x\n"), len); | |
for(i = 0; i < len; i++) { | |
if(i % 16 == 0) { | |
_tprintf(_T("\t\t\t")); | |
} | |
_tprintf(_T("%02X"), pbyte[i]); | |
if(i % 8 != 7) { | |
_tprintf(_T(" ")); | |
} else if(i % 16 == 7 && i != len - 1) { | |
_tprintf(_T("-")); | |
} else if(i % 16 == 15) { | |
_tprintf(_T(" ")); | |
for(int j = i / 16 * 16; j < i; j++) { | |
_tprintf(_T("%c"), isprint(pbyte[j]) ? pbyte[j] : _T('.')); | |
} | |
_tprintf(_T("\n")); | |
} | |
} | |
if(i % 16 != 0) { | |
for(int j = i; j % 16 != 0; j++) { | |
_tprintf(_T(" ")); | |
} | |
_tprintf(_T(" ")); // a space was already printed. | |
for(int j = i / 16 * 16; j < i; j++) { | |
_tprintf(_T("%c"), isprint(pbyte[j]) ? pbyte[j] : _T('.')); | |
} | |
_tprintf(_T("\n")); | |
} | |
} | |
// Pass "&ACE->StartSID" as startsid, and "ACE->Size - offsetof(ACETYPE, StartSID)"=cbLengthSID+cbExtra as size. | |
void printExtraAndPossibleSID(PSID startsid, INT_PTR size) { | |
if(size < 0) { | |
_tprintf(_T("*** Something wrong!! (size = %d)\n"), size); | |
} else if(size == 0) { | |
_tprintf(_T("\t\tNo SID and extra bytes...\n")); | |
} else { | |
if(!IsValidSid((PSID)startsid)) { | |
_tprintf(_T("\t\t*** invalid SID; dumping SID and extra if exist\n")); | |
printHexdump((LPCBYTE)startsid, size); | |
} else { | |
INT_PTR endsid = GetLengthSid(startsid); | |
INT_PTR extra = size - endsid; | |
if(endsid < 0 || extra < 0) { | |
_tprintf(_T("*** Something wrong!! (endsid = %d, extra = %d)\n"), endsid, extra); | |
} else if(extra > 0) { | |
printHexdump((LPCBYTE)startsid + endsid, extra); | |
} | |
} | |
} | |
} | |
void printSDAceMaskSID(PACE_HEADER aceh) { | |
PACCESS_ALLOWED_ACE aaace = (PACCESS_ALLOWED_ACE)aceh; | |
printSDAccessMask(aaace->Mask); | |
printSDStringSID(&aaace->SidStart); // continue even if error. | |
printExtraAndPossibleSID(&aaace->SidStart, aceh->AceSize - offsetof(ACCESS_ALLOWED_ACE, SidStart)); | |
/* | |
INT_PTR endsid = (sizeof(*aaace) - sizeof(aaace->SidStart)) + GetLengthSid(&aaace->SidStart); | |
INT_PTR extra = aceh->AceSize - endsid; | |
if(endsid < 0 || extra < 0) { | |
_tprintf(_T("*** Something wrong!! (endsid = %d, extra = %d)\n"), endsid, extra); | |
} else if(extra > 0) { | |
printHexdump((LPCBYTE)aceh + endsid, extra); | |
} | |
*/ | |
} | |
void formatGUIDtotstring(tstring &res, GUID &guid) { | |
tstringstream ss; | |
ss << std::hex << std::uppercase << std::setfill(_T('0')) << std::right; | |
ss << std::setw(8) << guid.Data1 << _T("-"); | |
ss << std::setw(4) << guid.Data2 << _T("-"); | |
ss << std::setw(4) << guid.Data3 << _T("-"); | |
for(int i = 0; i < 2; i++) { | |
ss << std::setw(2) << guid.Data4[i]; | |
} | |
ss << _T("-"); | |
ss << std::setw(2); | |
for(int i = 2; i < 8; i++) { | |
ss << std::setw(2) << guid.Data4[i]; | |
} | |
res = ss.str(); | |
} | |
void printSDAceMaskObjSID(PACE_HEADER aceh) { | |
PACCESS_ALLOWED_OBJECT_ACE aaoace = (PACCESS_ALLOWED_OBJECT_ACE)aceh; | |
printSDAccessMask(aaoace->Mask); | |
_tprintf(_T("\t\tFlags=0x%x\n"), aaoace->Flags); | |
tstring guidstr; | |
formatGUIDtotstring(guidstr, aaoace->ObjectType); | |
_tprintf(_T("\t\tObjectType={%s}\n"), guidstr.c_str()); | |
formatGUIDtotstring(guidstr, aaoace->InheritedObjectType); | |
_tprintf(_T("\t\tInheritedObjectType={%s}\n"), guidstr.c_str()); | |
printSDStringSID(&aaoace->SidStart); // continue even if error. | |
printExtraAndPossibleSID(&aaoace->SidStart, aceh->AceSize - offsetof(ACCESS_ALLOWED_OBJECT_ACE, SidStart)); | |
/* | |
if(!IsValidSid(&aaoace->SidStart)) { | |
_tprintf(_T("\t\t*** invalid SID; dumping SID and extra if exist\n")); | |
INT_PTR beginsid = sizeof(*aaoace) - sizeof(aaoace->SidStart); | |
printHexdump((LPCBYTE)aceh + beginsid, aceh->AceSize - beginsid); | |
} else { | |
INT_PTR endsid = (sizeof(*aaoace) - sizeof(aaoace->SidStart)) + GetLengthSid(&aaoace->SidStart); | |
INT_PTR extra = aceh->AceSize - endsid; | |
if(endsid < 0 || extra < 0) { | |
_tprintf(_T("*** Something wrong!! (endsid = %d, extra = %d)\n"), endsid, extra); | |
} else if(extra > 0) { | |
printHexdump((LPCBYTE)aceh + endsid, extra); | |
} | |
} | |
*/ | |
} | |
struct tAce { | |
BYTE aceType; | |
void (*func)(PACE_HEADER aceh); | |
} AceHandlers[] = { | |
{ACCESS_ALLOWED_ACE_TYPE, printSDAceMaskSID}, | |
{ACCESS_ALLOWED_CALLBACK_ACE_TYPE, printSDAceMaskSID}, | |
{ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, | |
//{ACCESS_ALLOWED_COMPOUND_ACE_TYPE, printSDAceMaskSID}, // Reserved. | |
{ACCESS_ALLOWED_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, | |
{ACCESS_DENIED_ACE_TYPE, printSDAceMaskSID}, | |
{ACCESS_DENIED_CALLBACK_ACE_TYPE, printSDAceMaskSID}, | |
{ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, | |
{ACCESS_DENIED_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, | |
{ACCESS_MAX_MS_ACE_TYPE, printSDAceMaskObjSID}, // Same as SYSTEM_ALARM_OBJECT_ACE_TYPE. | |
{ACCESS_MAX_MS_V2_ACE_TYPE, printSDAceMaskSID}, // Same as SYSTEM_ALARM_ACE_TYPE. | |
//{ACCESS_MAX_MS_V3_ACE_TYPE, printSDAceMaskSID}, // Reserved. | |
{ACCESS_MAX_MS_V4_ACE_TYPE, printSDAceMaskObjSID}, // Same as SYSTEM_ALARM_OBJECT_ACE_TYPE. | |
{ACCESS_MAX_MS_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, // Same as SYSTEM_ALARM_OBJECT_ACE_TYPE. | |
{ACCESS_MIN_MS_ACE_TYPE, printSDAceMaskSID}, // Same as ACCESS_ALLOWED_ACE_TYPE. | |
{ACCESS_MIN_MS_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, // Same as ACCESS_ALLOWED_OBJECT_ACE_TYPE. | |
// SYSTEM_ALERM_* are reserved... | |
{SYSTEM_ALARM_ACE_TYPE, printSDAceMaskSID}, | |
{SYSTEM_ALARM_CALLBACK_ACE_TYPE, printSDAceMaskSID}, | |
{SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, | |
{SYSTEM_ALARM_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, | |
// ^^^ | |
{SYSTEM_AUDIT_ACE_TYPE, printSDAceMaskSID}, | |
{SYSTEM_AUDIT_CALLBACK_ACE_TYPE, printSDAceMaskSID}, | |
{SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, | |
{SYSTEM_AUDIT_OBJECT_ACE_TYPE, printSDAceMaskObjSID}, | |
{SYSTEM_MANDATORY_LABEL_ACE_TYPE, printSDAceMaskSID}, | |
{0, NULL}, | |
}; | |
void printSDAce(PACE_HEADER aceh) { | |
struct tAce *acetab; | |
for(acetab = AceHandlers; acetab->func; acetab++) { | |
if(acetab->aceType == aceh->AceType) { | |
acetab->func(aceh); | |
return; | |
} | |
} | |
} | |
void __printSDAcl(BOOL (__stdcall *getter)(PSECURITY_DESCRIPTOR, LPBOOL, PACL*, LPBOOL), LPCTSTR gettername, LPCTSTR desc, PSECURITY_DESCRIPTOR secdesc) { | |
BOOL present; | |
PACL acl; | |
BOOL defaulted; | |
_tprintf(_T("%s:\n"), desc); | |
if(!getter(secdesc, &present, &acl, &defaulted)) { | |
_tprintf(_T("%s failed; hr=%08x\n"), gettername, GetLastError()); | |
return; | |
} | |
if(!present) { | |
_tprintf(_T("\t<not present>\n")); | |
return; | |
} | |
if(!acl) { | |
_tprintf(_T("\t<null>\n")); | |
return; | |
} | |
_tprintf(_T("\tRevision=%d\n"), acl->AclRevision); | |
_tprintf(_T("\tSize=%d\n"), acl->AclSize); | |
_tprintf(_T("\tACE count=%d\n"), acl->AceCount); | |
for(DWORD i = 0; i < acl->AceCount; i++) { | |
LPVOID ace; | |
_tprintf(_T("\tAce[%d]\n"), i); | |
GetAce(acl, i, &ace); | |
PACE_HEADER aceh = (PACE_HEADER)ace; | |
tstring acetypestr; | |
parseEnum(acetypestr, AceType, aceh->AceType); | |
_tprintf(_T("\t\tType=0x%x (%s)\n"), aceh->AceType, acetypestr.c_str()); | |
_tprintf(_T("\t\tSize=0x%x\n"), aceh->AceSize); | |
_tprintf(_T("\t\tAceFlags=0x%x\n"), aceh->AceFlags); | |
printSDAce(aceh); | |
} | |
} | |
#define _printSDAcl(f, d, s) __printSDAcl(f, _T(#f), d, s) | |
#define printSDAcl(t, d, s) _printSDAcl(GetSecurityDescriptor##t, d, s) | |
int parseStrSD(LPCTSTR sidstr) { | |
PSECURITY_DESCRIPTOR secdesc; | |
ULONG secdesclen; | |
if(!ConvertStringSecurityDescriptorToSecurityDescriptor(sidstr, SDDL_REVISION_1, &secdesc, &secdesclen)) { | |
_tprintf(_T("ConvertStringSecurityDescriptorToSecurityDescriptor failed; hr=%08x\n"), GetLastError()); | |
return 1; | |
} | |
printSDControl(secdesc); | |
printSDSID(Owner, secdesc); | |
printSDSID(Group, secdesc); | |
printSDAcl(Dacl, _T("DACL"), secdesc); | |
printSDAcl(Sacl, _T("SACL"), secdesc); | |
// RMControl | |
return 0; | |
} | |
int _tmain(int argc, LPTSTR *argv) { | |
//print(_T("Hello, %s!\n"), _T("World")); | |
static const LPCTSTR sids1 = _T("O:AOG:DAD:(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-0-0)"); | |
static const LPCTSTR sids2 = _T("O:DAG:DAD:(A;;RPWPCCDCLCRCWOWDSDSW;;;SY)(A;;RPWPCCDCLCRCWOWDSDSW;;;DA)(OA;;CCDC;bf967aba-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;bf967a9c-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;6da8a4ff-0e52-11d0-a286-00aa003049e2;;AO)(OA;;CCDC;bf967aa8-0de6-11d0-a285-00aa003049e2;;PO)(A;;RPLCRC;;;AU)S:(AU;SAFA;WDWOSDWPCCDCSW;;;WD)"); | |
static const LPCTSTR sids2a = _T("O:BAG:BAD:(A;;RPWPCCDCLCRCWOWDSDSW;;;SY)(A;;RPWPCCDCLCRCWOWDSDSW;;;BA)(OA;;CCDC;bf967aba-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;bf967a9c-0de6-11d0-a285-00aa003049e2;;AO)(OA;;CCDC;6da8a4ff-0e52-11d0-a286-00aa003049e2;;AO)(OA;;CCDC;bf967aa8-0de6-11d0-a285-00aa003049e2;;PO)(A;;RPLCRC;;;AU)S:(AU;SAFA;WDWOSDWPCCDCSW;;;WD)"); | |
static const LPCTSTR sids3 = _T("D:(OA;;CCDC;000a279c-0002-0005-0001-2c000120409a;;SY)"); | |
static const LPCTSTR sids4 = _T("D:(XA;;FX;;;WD;(Title==\"Heart\"))"); | |
static const LPCTSTR sids5 = _T("D:(XA;;FX;;;WD;(Title==\"oclhashcat\"))"); | |
if(argc < 2) { | |
//_tprintf(_T("usage: %s SIDString\n"), argv[0]); | |
_tprintf(_T("%s\n"), sids1); | |
parseStrSD(sids1); | |
_tprintf(_T("%s\n"), sids2); | |
parseStrSD(sids2); | |
_tprintf(_T("%s\n"), sids2a); | |
parseStrSD(sids2a); | |
_tprintf(_T("%s\n"), sids3); | |
parseStrSD(sids3); | |
_tprintf(_T("%s\n"), sids4); | |
parseStrSD(sids4); | |
_tprintf(_T("%s\n"), sids5); | |
parseStrSD(sids5); | |
} else { | |
parseStrSD(argv[1]); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment