Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save murachue/6578201 to your computer and use it in GitHub Desktop.
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 の出力みたいなのを求めるプログラムあるんですか」
#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