├── .gitignore ├── README.md ├── SecurityDescriptorHelper.sln ├── common ├── ResourceOwned.hpp ├── ResourceTraitsWin32.hpp ├── common.vcxitems ├── common.vcxitems.user └── xstring.hpp └── sddl-display ├── ConvertGuidToStringGuid.cpp ├── ConvertSidToAccountName.cpp ├── DisplayAccessControlEntryBody.cpp ├── DisplayAccessControlEntryHeader.cpp ├── DisplaySecurityDescriptorDacl.cpp ├── DisplaySecurityDescriptorHeader.cpp ├── DisplaySecurityDescriptorSacl.cpp ├── _tmain.cpp ├── sddl-display.vcxproj ├── sddl-display.vcxproj.filters └── sddl-display.vcxproj.user /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | bin/ 3 | obj/ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SecurityDescriptor Helper 2 | 3 | ## 1. sddl-display 4 | 5 | ### 1.1 Compile 6 | 7 | ```console 8 | $ git clone https://github.com/DoubleLabyrinth/SecurityDescriptorHelper.git 9 | $ cd SecurityDescriptorHelper 10 | $ msbuild SecurityDescriptorHelper.sln /target:sddl-display /p:Configuration=Release /p:Platform=x64 # or `x86` if you like 11 | ``` 12 | 13 | Then you will see `sddl-display.exe` in `bin\x64-Release\` folder. 14 | 15 | ### 1.2 Usage 16 | 17 | ``` console 18 | $ sddl-display.exe 19 | ``` 20 | 21 | ### 1.3 Example 22 | 23 | ```console 24 | $ sddl-display D:P(A;;GA;;;SY) 25 | ->Revision: 0x1 26 | ->Sbz1 : 0x0 27 | ->Control : 0x9004 28 | : (0x0004) SE_DACL_PRESENT 29 | : (0x1000) SE_DACL_PROTECTED 30 | : (0x8000) SE_SELF_RELATIVE 31 | ->Owner : 32 | ->Group : 33 | ->Dacl : ->AclRevision: 0x2 34 | ->Dacl : ->Sbz1 : 0x0 35 | ->Dacl : ->AclSize : 0x1c 36 | ->Dacl : ->AceCount : 0x1 37 | ->Dacl : ->Sbz2 : 0x0 38 | ->Dacl : ->Ace[0]: ->AceType : 0x00 (ACCESS_ALLOWED_ACE_TYPE) 39 | ->Dacl : ->Ace[0]: ->AceFlags: 0x00 40 | ->Dacl : ->Ace[0]: ->AceSize : 0x14 41 | ->Dacl : ->Ace[0]: ->Mask : 0x10000000 42 | ->Dacl : ->Ace[0]: ->SID : S-1-5-18 (NT AUTHORITY\SYSTEM) 43 | 44 | ->Sacl : is NULL 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /SecurityDescriptorHelper.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29230.47 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "common\common.vcxitems", "{883CCF15-FE1F-42BA-8DF7-6B6B592E6A57}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sddl-display", "sddl-display\sddl-display.vcxproj", "{9582BE27-9843-462B-BFBB-79427D553966}" 9 | EndProject 10 | Global 11 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 12 | common\common.vcxitems*{883ccf15-fe1f-42ba-8df7-6b6b592e6a57}*SharedItemsImports = 9 13 | common\common.vcxitems*{9582be27-9843-462b-bfbb-79427d553966}*SharedItemsImports = 4 14 | EndGlobalSection 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|x64 = Debug|x64 17 | Debug|x86 = Debug|x86 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {9582BE27-9843-462B-BFBB-79427D553966}.Debug|x64.ActiveCfg = Debug|x64 23 | {9582BE27-9843-462B-BFBB-79427D553966}.Debug|x64.Build.0 = Debug|x64 24 | {9582BE27-9843-462B-BFBB-79427D553966}.Debug|x86.ActiveCfg = Debug|Win32 25 | {9582BE27-9843-462B-BFBB-79427D553966}.Debug|x86.Build.0 = Debug|Win32 26 | {9582BE27-9843-462B-BFBB-79427D553966}.Release|x64.ActiveCfg = Release|x64 27 | {9582BE27-9843-462B-BFBB-79427D553966}.Release|x64.Build.0 = Release|x64 28 | {9582BE27-9843-462B-BFBB-79427D553966}.Release|x86.ActiveCfg = Release|Win32 29 | {9582BE27-9843-462B-BFBB-79427D553966}.Release|x86.Build.0 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {F6219374-D1A0-433F-8E5E-DC19D959E5B6} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /common/ResourceOwned.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | template 6 | class ResourceOwned { 7 | public: 8 | 9 | using TraitsType = __Traits; 10 | using HandleType = typename __Traits::HandleType; 11 | using DeleterType = __Deleter; 12 | 13 | static_assert(std::is_pod_v); 14 | 15 | private: 16 | 17 | HandleType _Handle; 18 | DeleterType _Deleter; 19 | 20 | public: 21 | 22 | // 23 | // Construct from custom deleter. 24 | // Internal handle value will be initialized by `__Traits::InvalidValue`. 25 | // 26 | template 27 | ResourceOwned(__DeleterArg&& Deleter) noexcept : 28 | _Handle(TraitsType::InvalidValue), 29 | _Deleter(std::forward<__DeleterArg>(Deleter)) {} 30 | 31 | // 32 | // Construct from handle given and custom deleter. 33 | // 34 | template 35 | ResourceOwned(const HandleType& Handle, __DeleterArg&& Deleter) noexcept : 36 | _Handle(Handle), 37 | _Deleter(std::forward<__DeleterArg>(Deleter)) {} 38 | 39 | // 40 | // Construct from custom deleter with hint of traits. 41 | // Internal handle value will be initialized by `__Traits::InvalidValue`. 42 | // 43 | template 44 | ResourceOwned(TraitsType, __DeleterArg&& Deleter) noexcept : 45 | _Handle(TraitsType::InvalidValue), 46 | _Deleter(std::forward<__DeleterArg>(Deleter)) {} 47 | 48 | // 49 | // Construct from handle given and custom deleter with hint of traits. 50 | // 51 | template 52 | ResourceOwned(TraitsType, const HandleType& Handle, __DeleterArg&& Deleter) noexcept : 53 | _Handle(Handle), 54 | _Deleter(std::forward<__DeleterArg>(Deleter)) {} 55 | 56 | // 57 | // ResourceOwned doesn't allow copy. 58 | // Because it holds handle exclusively. 59 | // 60 | ResourceOwned(const ResourceOwned<__Traits, __Deleter>& Other) = delete; 61 | 62 | // 63 | // ResourceOwned allows to move. 64 | // 65 | ResourceOwned(ResourceOwned<__Traits, __Deleter>&& Other) noexcept : 66 | _Handle(std::move(Other._Handle)), 67 | _Deleter(std::move(Other._Deleter)) { Other._Handle = TraitsType::InvalidValue; } 68 | 69 | // 70 | // ResourceOwned doesn't allow copy. 71 | // Because it holds handle exclusively. 72 | // 73 | ResourceOwned<__Traits, __Deleter>& operator=(const ResourceOwned<__Traits, __Deleter>& Other) = delete; 74 | 75 | // 76 | // ResourceOwned allows to move. 77 | // 78 | ResourceOwned<__Traits, __Deleter>& operator=(ResourceOwned<__Traits, __Deleter>&& Other) noexcept { 79 | _Handle = std::move(Other._Handle); 80 | _Deleter = std::move(Other._Deleter); 81 | Other._Handle = TraitsType::InvalidValue; 82 | return *this; 83 | } 84 | 85 | // 86 | // Act like handle itself. 87 | // 88 | [[nodiscard]] 89 | operator HandleType() const noexcept { // NOLINT: Allow implicit conversion. 90 | return _Handle; 91 | } 92 | 93 | // 94 | // If handle is a pointer, allow to be casted to another pointer type. 95 | // 96 | template>> 97 | [[nodiscard]] 98 | __AsPtrType As() const noexcept { 99 | static_assert(std::is_pointer_v<__AsPtrType>); 100 | return reinterpret_cast<__AsPtrType>(_Handle); 101 | } 102 | 103 | // 104 | // If handle is a pointer, enable operator->. 105 | // 106 | template>> 107 | [[nodiscard]] 108 | HandleType operator->() const noexcept { 109 | return _Handle; 110 | } 111 | 112 | // 113 | // Check if handle is valid. 114 | // 115 | [[nodiscard]] 116 | bool IsValid() const noexcept { 117 | return TraitsType::IsValid(_Handle); 118 | } 119 | 120 | // 121 | // Get handle explicitly. 122 | // 123 | [[nodiscard]] 124 | const HandleType& Get() const noexcept { 125 | return _Handle; 126 | } 127 | 128 | // 129 | // Get address of handle. this function is designed for functions that receive arguments whose type is `HandleType*`. 130 | // Use it if and only if `IsValid() == false`. 131 | // 132 | template 133 | [[nodiscard]] 134 | __ReturnType GetAddressOf() noexcept { 135 | return reinterpret_cast<__ReturnType>(&_Handle); 136 | } 137 | 138 | void TakeOver(const HandleType& Handle) { 139 | if (IsValid()) { 140 | _Deleter(_Handle); 141 | } 142 | _Handle = Handle; 143 | } 144 | 145 | void Discard() noexcept { 146 | _Handle = TraitsType::InvalidValue; 147 | } 148 | 149 | [[nodiscard]] 150 | HandleType Transfer() noexcept { 151 | HandleType t = std::move(_Handle); 152 | _Handle = TraitsType::InvalidValue; 153 | return t; 154 | } 155 | 156 | void Release() { 157 | if (IsValid()) { 158 | _Deleter(_Handle); 159 | _Handle = TraitsType::InvalidValue; 160 | } 161 | } 162 | 163 | // 164 | // Release then get address of handle. 165 | // This function is designed for functions that receive arguments whose type is `HandleType*`. 166 | // 167 | template 168 | [[nodiscard]] 169 | __ReturnType ReleaseAndGetAddressOf() { 170 | Release(); 171 | return reinterpret_cast<__ReturnType>(&_Handle); 172 | } 173 | 174 | ~ResourceOwned() { 175 | Release(); 176 | } 177 | }; 178 | 179 | template 180 | class ResourceOwned<__Traits, void> { 181 | public: 182 | 183 | using TraitsType = __Traits; 184 | using HandleType = typename __Traits::HandleType; 185 | using DeleterType = decltype(__Traits::Release); 186 | 187 | static_assert(std::is_pod_v); 188 | 189 | private: 190 | 191 | HandleType _Handle; 192 | 193 | public: 194 | 195 | // 196 | // Internal handle value will be initialized by `__Traits::InvalidValue`. 197 | // 198 | ResourceOwned() noexcept : 199 | _Handle(TraitsType::InvalidValue) {} 200 | 201 | // 202 | // Construct from handle given. 203 | // 204 | ResourceOwned(const HandleType& Handle) noexcept : 205 | _Handle(Handle) {} 206 | 207 | // 208 | // Construct with hint of traits. 209 | // Internal handle value will be initialized by `__Traits::InvalidValue`. 210 | // 211 | explicit ResourceOwned(TraitsType) noexcept : 212 | _Handle(TraitsType::InvalidValue) {} 213 | 214 | // 215 | // Construct from handle given with hint of traits. 216 | // 217 | ResourceOwned(TraitsType, const HandleType& Handle) noexcept : 218 | _Handle(Handle) {} 219 | 220 | // 221 | // ResourceOwned doesn't allow copy. 222 | // Because it holds handle exclusively. 223 | // 224 | ResourceOwned(const ResourceOwned<__Traits, void>& Other) = delete; 225 | 226 | // 227 | // ResourceOwned allows to move. 228 | // 229 | ResourceOwned(ResourceOwned<__Traits, void>&& Other) noexcept : 230 | _Handle(std::move(Other._Handle)) { Other._Handle = TraitsType::InvalidValue; } 231 | 232 | // 233 | // ResourceOwned doesn't allow copy. 234 | // Because it holds handle exclusively. 235 | // 236 | ResourceOwned<__Traits, void>& operator=(const ResourceOwned<__Traits, void>& Other) = delete; 237 | 238 | // 239 | // ResourceOwned allows to move. 240 | // 241 | ResourceOwned<__Traits, void>& operator=(ResourceOwned<__Traits, void>&& Other) noexcept { 242 | _Handle = std::move(Other._Handle); 243 | Other._Handle = TraitsType::InvalidValue; 244 | return *this; 245 | } 246 | 247 | // 248 | // Act like handle itself. 249 | // 250 | [[nodiscard]] 251 | operator HandleType() const noexcept { // NOLINT: Allow implicit conversion. 252 | return _Handle; 253 | } 254 | 255 | // 256 | // If handle is a pointer, allow to be casted to another pointer type. 257 | // 258 | template>> 259 | [[nodiscard]] 260 | __AsPtrType As() const noexcept { 261 | static_assert(std::is_pointer_v<__AsPtrType>); 262 | return reinterpret_cast<__AsPtrType>(_Handle); 263 | } 264 | 265 | // 266 | // If handle is a pointer, enable operator->. 267 | // 268 | template>> 269 | [[nodiscard]] 270 | HandleType operator->() const noexcept { 271 | return _Handle; 272 | } 273 | 274 | // 275 | // Check if handle is valid. 276 | // 277 | [[nodiscard]] 278 | bool IsValid() const noexcept { 279 | return TraitsType::IsValid(_Handle); 280 | } 281 | 282 | // 283 | // Get handle explicitly. 284 | // 285 | [[nodiscard]] 286 | const HandleType& Get() const noexcept { 287 | return _Handle; 288 | } 289 | 290 | // 291 | // Get address of handle. this function is designed for functions that receive arguments whose type is `HandleType*`. 292 | // Use it if and only if `IsValid() == false`. 293 | // 294 | template 295 | [[nodiscard]] 296 | __ReturnType GetAddressOf() noexcept { 297 | return reinterpret_cast<__ReturnType>(&_Handle); 298 | } 299 | 300 | void TakeOver(const HandleType& Handle) { 301 | if (IsValid()) { 302 | TraitsType::Release(_Handle); 303 | } 304 | _Handle = Handle; 305 | } 306 | 307 | void Discard() noexcept { 308 | _Handle = TraitsType::InvalidValue; 309 | } 310 | 311 | [[nodiscard]] 312 | HandleType Transfer() noexcept { 313 | HandleType t = _Handle; 314 | _Handle = TraitsType::InvalidValue; 315 | return t; 316 | } 317 | 318 | void Release() { 319 | if (IsValid()) { 320 | TraitsType::Release(_Handle); 321 | _Handle = TraitsType::InvalidValue; 322 | } 323 | } 324 | 325 | // 326 | // Release then get address of handle. 327 | // This function is designed for functions that receive arguments whose type is `HandleType*`. 328 | // 329 | template 330 | [[nodiscard]] 331 | __ReturnType ReleaseAndGetAddressOf() { 332 | Release(); 333 | return reinterpret_cast<__ReturnType>(&_Handle); 334 | } 335 | 336 | ~ResourceOwned() { 337 | Release(); 338 | } 339 | }; 340 | 341 | // 342 | // ResourceOwned deduce guide 343 | // 344 | 345 | template 346 | ResourceOwned(__Traits) -> 347 | ResourceOwned<__Traits, void>; 348 | 349 | template 350 | ResourceOwned(__Traits, __ArgType&&) -> 351 | ResourceOwned< 352 | __Traits, 353 | std::conditional_t< 354 | std::is_same_v>, typename __Traits::HandleType>, 355 | void, 356 | std::remove_cv_t> 357 | > 358 | >; 359 | 360 | template 361 | ResourceOwned(__Traits, const typename __Traits::HandleType&, __DeleterArg&&) -> 362 | ResourceOwned< 363 | __Traits, 364 | std::remove_cv_t> 365 | >; 366 | 367 | template 368 | struct CppObjectTraits { 369 | using HandleType = __ClassType*; 370 | 371 | static inline const HandleType InvalidValue = nullptr; 372 | 373 | [[nodiscard]] 374 | static bool IsValid(const HandleType& Handle) noexcept { 375 | return Handle != InvalidValue; 376 | } 377 | 378 | static void Release(HandleType& Handle) { 379 | delete Handle; 380 | } 381 | }; 382 | 383 | template 384 | struct CppDynamicArrayTraits { 385 | using HandleType = __Type*; 386 | 387 | static inline const HandleType InvalidValue = nullptr; 388 | 389 | [[nodiscard]] 390 | static bool IsValid(const HandleType& Handle) noexcept { 391 | return Handle != InvalidValue; 392 | } 393 | 394 | static void Release(HandleType& Handle) { 395 | delete[] Handle; 396 | } 397 | }; 398 | 399 | -------------------------------------------------------------------------------- /common/ResourceTraitsWin32.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | struct GenericHandleTraits { 7 | using HandleType = HANDLE; 8 | 9 | static inline const HandleType InvalidValue = NULL; 10 | 11 | [[nodiscard]] 12 | static bool IsValid(const HandleType& Handle) noexcept { 13 | return Handle != InvalidValue; 14 | } 15 | 16 | static void Release(_In_ HandleType& Handle) { 17 | if (CloseHandle(Handle) == FALSE) { 18 | auto err = GetLastError(); 19 | throw std::system_error(err, std::system_category()); 20 | } 21 | } 22 | }; 23 | 24 | template 25 | struct HeapAllocTraits { 26 | static_assert(std::is_pointer_v<__PtrType>); 27 | 28 | using HandleType = __PtrType; 29 | 30 | static inline const HandleType InvalidValue = nullptr; 31 | 32 | [[nodiscard]] 33 | static bool IsValid(const HandleType& Handle) noexcept { 34 | return Handle != InvalidValue; 35 | } 36 | 37 | static void Release(_In_ HandleType& Handle) { 38 | if (HeapFree(GetProcessHeap(), 0, Handle) == FALSE) { 39 | auto err = GetLastError(); 40 | throw std::system_error(err, std::system_category()); 41 | } 42 | } 43 | }; 44 | 45 | template 46 | struct LocalAllocTraits { 47 | static_assert(std::is_pointer_v<__PtrType>); 48 | 49 | using HandleType = __PtrType; 50 | 51 | static inline const HandleType InvalidValue = nullptr; 52 | 53 | [[nodiscard]] 54 | static bool IsValid(const HandleType& Handle) noexcept { 55 | return Handle != InvalidValue; 56 | } 57 | 58 | static void Release(_In_ HandleType& Handle) { 59 | if (LocalFree(Handle) != NULL) { 60 | auto err = GetLastError(); 61 | throw std::system_error(err, std::system_category()); 62 | } 63 | } 64 | }; 65 | 66 | template 67 | struct CoTaskMemAllocTraits { 68 | static_assert(std::is_pointer_v<__PtrType>); 69 | 70 | using HandleType = __PtrType; 71 | 72 | static inline const HandleType InvalidValue = nullptr; 73 | 74 | [[nodiscard]] 75 | static bool IsValid(const HandleType& Handle) noexcept { 76 | return Handle != InvalidValue; 77 | } 78 | 79 | static void Release(_In_ HandleType& Handle) noexcept { 80 | CoTaskMemFree(Handle); 81 | } 82 | }; 83 | 84 | -------------------------------------------------------------------------------- /common/common.vcxitems: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 5 | true 6 | {883ccf15-fe1f-42ba-8df7-6b6b592e6a57} 7 | 8 | 9 | 10 | %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /common/common.vcxitems.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /common/xstring.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace std { 11 | 12 | struct xstring_extension {}; 13 | 14 | #if defined(_UNICODE) || defined(UNICODE) 15 | class xstring final : public wstring { 16 | public: 17 | 18 | using wstring::wstring; 19 | using wstring::operator=; 20 | 21 | xstring(const wstring& wstr) : wstring(wstr) {} 22 | 23 | xstring(wstring&& wstr) : wstring(std::move(wstr)) {} 24 | 25 | xstring(xstring_extension, const string& str, DWORD CodePage = CP_ACP) { 26 | auto len = MultiByteToWideChar(CodePage, 0, str.c_str(), -1, NULL, 0); 27 | if (len == 0) { 28 | auto err = GetLastError(); 29 | throw std::system_error(err, std::system_category()); 30 | } 31 | 32 | resize(static_cast(len) - 1); 33 | 34 | len = MultiByteToWideChar(CodePage, 0, str.c_str(), -1, data(), len); 35 | if (len == 0) { 36 | auto err = GetLastError(); 37 | throw std::system_error(err, std::system_category()); 38 | } 39 | } 40 | 41 | xstring(xstring_extension, const char* lpstr, DWORD CodePage = CP_ACP) { 42 | auto len = MultiByteToWideChar(CodePage, 0, lpstr, -1, NULL, 0); 43 | if (len == 0) { 44 | auto err = GetLastError(); 45 | throw std::system_error(err, std::system_category()); 46 | } 47 | 48 | resize(static_cast(len) - 1); 49 | 50 | len = MultiByteToWideChar(CodePage, 0, lpstr, -1, data(), len); 51 | if (len == 0) { 52 | auto err = GetLastError(); 53 | throw std::system_error(err, std::system_category()); 54 | } 55 | } 56 | #else 57 | class xstring final : public string { 58 | public: 59 | 60 | using string::string; 61 | using string::operator=; 62 | 63 | xstring(const string& str) : string(str) {} 64 | 65 | xstring(string&& str) : string(std::move(str)) {} 66 | 67 | xstring(xstring_extension, const string& str, DWORD CodePage = CP_ACP) { 68 | if (CodePage == CP_ACP || CodePage == GetACP()) { 69 | assign(str); 70 | } else { 71 | std::wstring wstr; 72 | 73 | auto len = MultiByteToWideChar(CodePage, 0, str.c_str(), -1, NULL, 0); 74 | if (len == 0) { 75 | auto err = GetLastError(); 76 | throw std::system_error(err, std::system_category()); 77 | } 78 | 79 | wstr.resize(len - 1); 80 | 81 | len = MultiByteToWideChar(CodePage, 0, str.c_str(), -1, wstr.data(), len); 82 | if (len == 0) { 83 | auto err = GetLastError(); 84 | throw std::system_error(err, std::system_category()); 85 | } 86 | 87 | len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL); 88 | if (len == 0) { 89 | auto err = GetLastError(); 90 | throw std::system_error(err, std::system_category()); 91 | } 92 | 93 | resize(len - 1); 94 | 95 | len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, data(), len, NULL, NULL); 96 | if (len == 0) { 97 | auto err = GetLastError(); 98 | throw std::system_error(err, std::system_category()); 99 | } 100 | } 101 | } 102 | 103 | xstring(xstring_extension, const char* lpstr, DWORD CodePage = CP_ACP) { 104 | if (CodePage == CP_ACP || CodePage == GetACP()) { 105 | assign(str); 106 | } else { 107 | std::wstring wstr; 108 | 109 | auto len = MultiByteToWideChar(CodePage, 0, lpstr, -1, NULL, 0); 110 | if (len == 0) { 111 | auto err = GetLastError(); 112 | throw std::system_error(err, std::system_category()); 113 | } 114 | 115 | wstr.resize(len - 1); 116 | 117 | len = MultiByteToWideChar(CodePage, 0, lpstr, -1, wstr.data(), len); 118 | if (len == 0) { 119 | auto err = GetLastError(); 120 | throw std::system_error(err, std::system_category()); 121 | } 122 | 123 | len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL); 124 | if (len == 0) { 125 | auto err = GetLastError(); 126 | throw std::system_error(err, std::system_category()); 127 | } 128 | 129 | resize(len - 1); 130 | 131 | len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, data(), len, NULL, NULL); 132 | if (len == 0) { 133 | auto err = GetLastError(); 134 | throw std::system_error(err, std::system_category()); 135 | } 136 | } 137 | } 138 | 139 | xstring(xstring_extension, const wstring& wstr) { 140 | auto len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL); 141 | if (len == 0) { 142 | auto err = GetLastError(); 143 | throw std::system_error(err, std::system_category()); 144 | } 145 | 146 | resize(len - 1); 147 | 148 | len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, data(), len, NULL, NULL); 149 | if (len == 0) { 150 | auto err = GetLastError(); 151 | throw std::system_error(err, std::system_category()); 152 | } 153 | } 154 | 155 | xstring(xstring_extension, const wchar_t* lpwstr) { 156 | auto len = WideCharToMultiByte(CP_ACP, 0, lpwstr, -1, NULL, 0, NULL, NULL); 157 | if (len == 0) { 158 | auto err = GetLastError(); 159 | throw std::system_error(err, std::system_category()); 160 | } 161 | 162 | resize(len - 1); 163 | 164 | len = WideCharToMultiByte(CP_ACP, 0, lpwstr, -1, data(), len, NULL, NULL); 165 | if (len == 0) { 166 | auto err = GetLastError(); 167 | throw std::system_error(err, std::system_category()); 168 | } 169 | } 170 | #endif 171 | 172 | std::string explicit_string(DWORD CodePage = CP_ACP) const { 173 | #if defined(_UNICODE) || defined(UNICODE) 174 | std::string str; 175 | 176 | auto len = WideCharToMultiByte(CodePage, 0, c_str(), -1, NULL, 0, NULL, NULL); 177 | if (len == 0) { 178 | auto err = GetLastError(); 179 | throw std::system_error(err, std::system_category()); 180 | } 181 | 182 | str.resize(static_cast(len) - 1); 183 | 184 | len = WideCharToMultiByte(CodePage, 0, c_str(), -1, str.data(), len, NULL, NULL); 185 | if (len == 0) { 186 | auto err = GetLastError(); 187 | throw std::system_error(err, std::system_category()); 188 | } 189 | 190 | return str; 191 | #else 192 | if (CodePage == CP_ACP || CodePage == GetACP()) { 193 | return *this; 194 | } else { 195 | std::string str; 196 | std::wstring wstr; 197 | 198 | auto len = MultiByteToWideChar(CP_ACP, 0, c_str(), -1, NULL, 0); 199 | if (len == 0) { 200 | auto err = GetLastError(); 201 | throw std::system_error(err, std::system_category()); 202 | } 203 | 204 | wstr.resize(len - 1); 205 | 206 | len = MultiByteToWideChar(CP_ACP, 0, c_str(), -1, wstr.data(), len); 207 | if (len == 0) { 208 | auto err = GetLastError(); 209 | throw std::system_error(err, std::system_category()); 210 | } 211 | 212 | len = WideCharToMultiByte(CodePage, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL); 213 | if (len == 0) { 214 | auto err = GetLastError(); 215 | throw std::system_error(err, std::system_category()); 216 | } 217 | 218 | str.resize(len - 1); 219 | 220 | len = WideCharToMultiByte(CodePage, 0, wstr.c_str(), -1, str.data(), len, NULL, NULL); 221 | if (len == 0) { 222 | auto err = GetLastError(); 223 | throw std::system_error(err, std::system_category()); 224 | } 225 | 226 | return str; 227 | } 228 | #endif 229 | } 230 | 231 | std::wstring explicit_wstring() const { 232 | #if defined(_UNICODE) || defined(UNICODE) 233 | return *this; 234 | #else 235 | std::wstring wstr; 236 | 237 | auto len = MultiByteToWideChar(CP_ACP, 0, c_str(), -1, NULL, 0); 238 | if (len == 0) { 239 | auto err = GetLastError(); 240 | throw std::system_error(err, std::system_category()); 241 | } 242 | 243 | wstr.resize(len - 1); 244 | 245 | len = MultiByteToWideChar(CP_ACP, 0, c_str(), -1, wstr.data(), len); 246 | if (len == 0) { 247 | auto err = GetLastError(); 248 | throw std::system_error(err, std::system_category()); 249 | } 250 | 251 | return wstr; 252 | #endif 253 | } 254 | 255 | template 256 | static xstring format(const xstring& Format, __Ts&&... Args) { 257 | xstring s; 258 | 259 | auto len = _sctprintf(Format.c_str(), std::forward<__Ts>(Args)...); 260 | if (len == -1) { 261 | throw std::invalid_argument("_sctprintf failed."); 262 | } 263 | 264 | s.resize(len); 265 | 266 | _sntprintf_s(s.data(), s.length() + 1, _TRUNCATE, Format.c_str(), std::forward<__Ts>(Args)...); 267 | 268 | return s; 269 | } 270 | 271 | template 272 | static xstring format(PCTSTR lpszFormat, __Ts&& ... Args) { 273 | xstring s; 274 | 275 | auto len = _sctprintf(lpszFormat, std::forward<__Ts>(Args)...); 276 | if (len == -1) { 277 | throw std::invalid_argument("_sctprintf failed."); 278 | } 279 | 280 | s.resize(len); 281 | 282 | _sntprintf_s(s.data(), s.length() + 1, _TRUNCATE, lpszFormat, std::forward<__Ts>(Args)...); 283 | 284 | return s; 285 | } 286 | }; 287 | 288 | } 289 | -------------------------------------------------------------------------------- /sddl-display/ConvertGuidToStringGuid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace sddldisplay { 5 | 6 | std::xstring ConvertGuidToStringGuid(const GUID& Guid) { 7 | return std::xstring::format( 8 | TEXT("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"), 9 | Guid.Data1, 10 | Guid.Data2, 11 | Guid.Data3, 12 | Guid.Data4[0], 13 | Guid.Data4[1], 14 | Guid.Data4[2], 15 | Guid.Data4[3], 16 | Guid.Data4[4], 17 | Guid.Data4[5], 18 | Guid.Data4[6], 19 | Guid.Data4[7] 20 | ); 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /sddl-display/ConvertSidToAccountName.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #pragma comment(lib, "advapi32") 5 | 6 | namespace sddldisplay { 7 | 8 | std::xstring ConvertSidToAccountName(PSID lpSid) { 9 | DWORD cchName = 0; 10 | std::xstring Name; 11 | 12 | DWORD ccbDomain = 0; 13 | std::xstring Domain; 14 | 15 | SID_NAME_USE SidNameUse; 16 | 17 | LookupAccountSid(NULL, lpSid, NULL, &cchName, NULL, &ccbDomain, &SidNameUse); 18 | if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { 19 | auto err = GetLastError(); 20 | throw std::system_error(err, std::system_category()); 21 | } 22 | 23 | Name.resize(cchName - 1); 24 | Domain.resize(ccbDomain - 1); 25 | 26 | if (LookupAccountSid(NULL, lpSid, Name.data(), &cchName, Domain.data(), &ccbDomain, &SidNameUse) == FALSE) { 27 | auto err = GetLastError(); 28 | throw std::system_error(err, std::system_category()); 29 | } 30 | 31 | return Domain + TEXT('\\') + Name; 32 | } 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /sddl-display/DisplayAccessControlEntryBody.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #pragma comment(lib, "advapi32") 13 | 14 | namespace sddldisplay { 15 | 16 | std::xstring ConvertSidToAccountName(PSID lpSid); 17 | 18 | std::xstring ConvertGuidToStringGuid(const GUID& Guid); 19 | 20 | template 21 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx); 22 | 23 | template<> 24 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 25 | auto lpAce = reinterpret_cast(p); 26 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 27 | 28 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 29 | auto err = GetLastError(); 30 | throw std::system_error(err, std::system_category()); 31 | } 32 | 33 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 34 | 35 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 36 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 37 | } 38 | 39 | template<> 40 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 41 | auto lpAce = reinterpret_cast(p); 42 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 43 | 44 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 45 | auto err = GetLastError(); 46 | throw std::system_error(err, std::system_category()); 47 | } 48 | 49 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 50 | 51 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 52 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 53 | } 54 | 55 | template<> 56 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 57 | auto lpAce = reinterpret_cast(p); 58 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 59 | 60 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 61 | auto err = GetLastError(); 62 | throw std::system_error(err, std::system_category()); 63 | } 64 | 65 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 66 | 67 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 68 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 69 | } 70 | 71 | template<> 72 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 73 | auto lpAce = reinterpret_cast(p); 74 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 75 | 76 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 77 | auto err = GetLastError(); 78 | throw std::system_error(err, std::system_category()); 79 | } 80 | 81 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 82 | 83 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 84 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 85 | } 86 | 87 | template<> 88 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 89 | // Reserved 90 | } 91 | 92 | template<> 93 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 94 | auto lpAce = reinterpret_cast(p); 95 | 96 | auto lpszObjectTypeGuid = ConvertGuidToStringGuid(lpAce->ObjectType); 97 | auto lpszInheritedObjectTypeGuid = ConvertGuidToStringGuid(lpAce->InheritedObjectType); 98 | 99 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 100 | 101 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 102 | auto err = GetLastError(); 103 | throw std::system_error(err, std::system_category()); 104 | } 105 | 106 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 107 | 108 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 109 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Flags); 110 | 111 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 112 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_OBJECT_TYPE_PRESENT, TEXT("ACE_OBJECT_TYPE_PRESENT")); 113 | } 114 | 115 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 116 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_INHERITED_OBJECT_TYPE_PRESENT, TEXT("ACE_INHERITED_OBJECT_TYPE_PRESENT")); 117 | } 118 | 119 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 120 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->ObjectType: %s\n"), lpszPrefix, Idx, lpszObjectTypeGuid.c_str()); 121 | } 122 | 123 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 124 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->InheritedObjectType: %s\n"), lpszPrefix, Idx, lpszInheritedObjectTypeGuid.c_str()); 125 | } 126 | 127 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 128 | } 129 | 130 | template<> 131 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 132 | auto lpAce = reinterpret_cast(p); 133 | 134 | auto lpszObjectTypeGuid = ConvertGuidToStringGuid(lpAce->ObjectType); 135 | auto lpszInheritedObjectTypeGuid = ConvertGuidToStringGuid(lpAce->InheritedObjectType); 136 | 137 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 138 | 139 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 140 | auto err = GetLastError(); 141 | throw std::system_error(err, std::system_category()); 142 | } 143 | 144 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 145 | 146 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 147 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Flags); 148 | 149 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 150 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_OBJECT_TYPE_PRESENT, TEXT("ACE_OBJECT_TYPE_PRESENT")); 151 | } 152 | 153 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 154 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_INHERITED_OBJECT_TYPE_PRESENT, TEXT("ACE_INHERITED_OBJECT_TYPE_PRESENT")); 155 | } 156 | 157 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 158 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->ObjectType: %s\n"), lpszPrefix, Idx, lpszObjectTypeGuid.c_str()); 159 | } 160 | 161 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 162 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->InheritedObjectType: %s\n"), lpszPrefix, Idx, lpszInheritedObjectTypeGuid.c_str()); 163 | } 164 | 165 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 166 | } 167 | 168 | template<> 169 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 170 | auto lpAce = reinterpret_cast(p); 171 | 172 | auto lpszObjectTypeGuid = ConvertGuidToStringGuid(lpAce->ObjectType); 173 | auto lpszInheritedObjectTypeGuid = ConvertGuidToStringGuid(lpAce->InheritedObjectType); 174 | 175 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 176 | 177 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 178 | auto err = GetLastError(); 179 | throw std::system_error(err, std::system_category()); 180 | } 181 | 182 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 183 | 184 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 185 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Flags); 186 | 187 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 188 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_OBJECT_TYPE_PRESENT, TEXT("ACE_OBJECT_TYPE_PRESENT")); 189 | } 190 | 191 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 192 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_INHERITED_OBJECT_TYPE_PRESENT, TEXT("ACE_INHERITED_OBJECT_TYPE_PRESENT")); 193 | } 194 | 195 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 196 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->ObjectType: %s\n"), lpszPrefix, Idx, lpszObjectTypeGuid.c_str()); 197 | } 198 | 199 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 200 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->InheritedObjectType: %s\n"), lpszPrefix, Idx, lpszInheritedObjectTypeGuid.c_str()); 201 | } 202 | 203 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 204 | } 205 | 206 | template<> 207 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 208 | auto lpAce = reinterpret_cast(p); 209 | 210 | auto lpszObjectTypeGuid = ConvertGuidToStringGuid(lpAce->ObjectType); 211 | auto lpszInheritedObjectTypeGuid = ConvertGuidToStringGuid(lpAce->InheritedObjectType); 212 | 213 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 214 | 215 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 216 | auto err = GetLastError(); 217 | throw std::system_error(err, std::system_category()); 218 | } 219 | 220 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 221 | 222 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 223 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Flags); 224 | 225 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 226 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_OBJECT_TYPE_PRESENT, TEXT("ACE_OBJECT_TYPE_PRESENT")); 227 | } 228 | 229 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 230 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_INHERITED_OBJECT_TYPE_PRESENT, TEXT("ACE_INHERITED_OBJECT_TYPE_PRESENT")); 231 | } 232 | 233 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 234 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->ObjectType: %s\n"), lpszPrefix, Idx, lpszObjectTypeGuid.c_str()); 235 | } 236 | 237 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 238 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->InheritedObjectType: %s\n"), lpszPrefix, Idx, lpszInheritedObjectTypeGuid.c_str()); 239 | } 240 | 241 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 242 | } 243 | 244 | template<> 245 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 246 | auto lpAce = reinterpret_cast(p); 247 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 248 | 249 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 250 | auto err = GetLastError(); 251 | throw std::system_error(err, std::system_category()); 252 | } 253 | 254 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 255 | 256 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 257 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 258 | } 259 | 260 | template<> 261 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 262 | auto lpAce = reinterpret_cast(p); 263 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 264 | 265 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 266 | auto err = GetLastError(); 267 | throw std::system_error(err, std::system_category()); 268 | } 269 | 270 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 271 | 272 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 273 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 274 | } 275 | 276 | template<> 277 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 278 | auto lpAce = reinterpret_cast(p); 279 | 280 | auto lpszObjectTypeGuid = ConvertGuidToStringGuid(lpAce->ObjectType); 281 | auto lpszInheritedObjectTypeGuid = ConvertGuidToStringGuid(lpAce->InheritedObjectType); 282 | 283 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 284 | 285 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 286 | auto err = GetLastError(); 287 | throw std::system_error(err, std::system_category()); 288 | } 289 | 290 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 291 | 292 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 293 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Flags); 294 | 295 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 296 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_OBJECT_TYPE_PRESENT, TEXT("ACE_OBJECT_TYPE_PRESENT")); 297 | } 298 | 299 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 300 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_INHERITED_OBJECT_TYPE_PRESENT, TEXT("ACE_INHERITED_OBJECT_TYPE_PRESENT")); 301 | } 302 | 303 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 304 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->ObjectType: %s\n"), lpszPrefix, Idx, lpszObjectTypeGuid.c_str()); 305 | } 306 | 307 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 308 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->InheritedObjectType: %s\n"), lpszPrefix, Idx, lpszInheritedObjectTypeGuid.c_str()); 309 | } 310 | 311 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 312 | } 313 | 314 | template<> 315 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 316 | auto lpAce = reinterpret_cast(p); 317 | 318 | auto lpszObjectTypeGuid = ConvertGuidToStringGuid(lpAce->ObjectType); 319 | auto lpszInheritedObjectTypeGuid = ConvertGuidToStringGuid(lpAce->InheritedObjectType); 320 | 321 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 322 | 323 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 324 | auto err = GetLastError(); 325 | throw std::system_error(err, std::system_category()); 326 | } 327 | 328 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 329 | 330 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 331 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Flags); 332 | 333 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 334 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_OBJECT_TYPE_PRESENT, TEXT("ACE_OBJECT_TYPE_PRESENT")); 335 | } 336 | 337 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 338 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_INHERITED_OBJECT_TYPE_PRESENT, TEXT("ACE_INHERITED_OBJECT_TYPE_PRESENT")); 339 | } 340 | 341 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 342 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->ObjectType: %s\n"), lpszPrefix, Idx, lpszObjectTypeGuid.c_str()); 343 | } 344 | 345 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 346 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->InheritedObjectType: %s\n"), lpszPrefix, Idx, lpszInheritedObjectTypeGuid.c_str()); 347 | } 348 | 349 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 350 | } 351 | 352 | template<> 353 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 354 | auto lpAce = reinterpret_cast(p); 355 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 356 | 357 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 358 | auto err = GetLastError(); 359 | throw std::system_error(err, std::system_category()); 360 | } 361 | 362 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 363 | 364 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 365 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 366 | } 367 | 368 | template<> 369 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 370 | auto lpAce = reinterpret_cast(p); 371 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 372 | 373 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 374 | auto err = GetLastError(); 375 | throw std::system_error(err, std::system_category()); 376 | } 377 | 378 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 379 | 380 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 381 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 382 | } 383 | 384 | template<> 385 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 386 | auto lpAce = reinterpret_cast(p); 387 | 388 | auto lpszObjectTypeGuid = ConvertGuidToStringGuid(lpAce->ObjectType); 389 | auto lpszInheritedObjectTypeGuid = ConvertGuidToStringGuid(lpAce->InheritedObjectType); 390 | 391 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 392 | 393 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 394 | auto err = GetLastError(); 395 | throw std::system_error(err, std::system_category()); 396 | } 397 | 398 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 399 | 400 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 401 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Flags); 402 | 403 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 404 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_OBJECT_TYPE_PRESENT, TEXT("ACE_OBJECT_TYPE_PRESENT")); 405 | } 406 | 407 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 408 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_INHERITED_OBJECT_TYPE_PRESENT, TEXT("ACE_INHERITED_OBJECT_TYPE_PRESENT")); 409 | } 410 | 411 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 412 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->ObjectType: %s\n"), lpszPrefix, Idx, lpszObjectTypeGuid.c_str()); 413 | } 414 | 415 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 416 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->InheritedObjectType: %s\n"), lpszPrefix, Idx, lpszInheritedObjectTypeGuid.c_str()); 417 | } 418 | 419 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 420 | } 421 | 422 | template<> 423 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 424 | auto lpAce = reinterpret_cast(p); 425 | 426 | auto lpszObjectTypeGuid = ConvertGuidToStringGuid(lpAce->ObjectType); 427 | auto lpszInheritedObjectTypeGuid = ConvertGuidToStringGuid(lpAce->InheritedObjectType); 428 | 429 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 430 | 431 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 432 | auto err = GetLastError(); 433 | throw std::system_error(err, std::system_category()); 434 | } 435 | 436 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 437 | 438 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 439 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Flags); 440 | 441 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 442 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_OBJECT_TYPE_PRESENT, TEXT("ACE_OBJECT_TYPE_PRESENT")); 443 | } 444 | 445 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 446 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Flags : (0x%.8x) %s\n"), lpszPrefix, Idx, ACE_INHERITED_OBJECT_TYPE_PRESENT, TEXT("ACE_INHERITED_OBJECT_TYPE_PRESENT")); 447 | } 448 | 449 | if (lpAce->Flags & ACE_OBJECT_TYPE_PRESENT) { 450 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->ObjectType: %s\n"), lpszPrefix, Idx, lpszObjectTypeGuid.c_str()); 451 | } 452 | 453 | if (lpAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT) { 454 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->InheritedObjectType: %s\n"), lpszPrefix, Idx, lpszInheritedObjectTypeGuid.c_str()); 455 | } 456 | 457 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 458 | } 459 | 460 | template<> 461 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 462 | auto lpAce = reinterpret_cast(p); 463 | auto lpszSid = ResourceOwned(LocalAllocTraits{}); 464 | 465 | if (ConvertSidToStringSid(reinterpret_cast(&lpAce->SidStart), lpszSid.GetAddressOf()) == FALSE) { 466 | auto err = GetLastError(); 467 | throw std::system_error(err, std::system_category()); 468 | } 469 | 470 | auto szName = ConvertSidToAccountName(reinterpret_cast(&lpAce->SidStart)); 471 | 472 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->Mask : 0x%.8x\n"), lpszPrefix, Idx, lpAce->Mask); 473 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->SID : %s (%s)\n"), lpszPrefix, Idx, lpszSid.Get(), szName.c_str()); 474 | } 475 | 476 | template<> 477 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 478 | // todo 479 | } 480 | 481 | template<> 482 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 483 | // todo 484 | } 485 | 486 | template<> 487 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 488 | // todo 489 | } 490 | 491 | template<> 492 | static void DisplayAccessControlEntryBody(PVOID p, PCTSTR lpszPrefix, DWORD Idx) { 493 | // todo 494 | } 495 | 496 | void DisplayAccessControlEntryBody(PVOID lpAce, PCTSTR lpszPrefix, DWORD Idx) { 497 | auto lpAceHeader = reinterpret_cast(lpAce); 498 | switch (lpAceHeader->AceType) { 499 | case ACCESS_ALLOWED_ACE_TYPE: 500 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 501 | break; 502 | case ACCESS_DENIED_ACE_TYPE: 503 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 504 | break; 505 | case SYSTEM_AUDIT_ACE_TYPE: 506 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 507 | break; 508 | case SYSTEM_ALARM_ACE_TYPE: 509 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 510 | break; 511 | case ACCESS_ALLOWED_COMPOUND_ACE_TYPE: 512 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 513 | break; 514 | case ACCESS_ALLOWED_OBJECT_ACE_TYPE: 515 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 516 | break; 517 | case ACCESS_DENIED_OBJECT_ACE_TYPE: 518 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 519 | break; 520 | case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 521 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 522 | break; 523 | case SYSTEM_ALARM_OBJECT_ACE_TYPE: 524 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 525 | break; 526 | case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: 527 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 528 | break; 529 | case ACCESS_DENIED_CALLBACK_ACE_TYPE: 530 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 531 | break; 532 | case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: 533 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 534 | break; 535 | case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: 536 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 537 | break; 538 | case SYSTEM_AUDIT_CALLBACK_ACE_TYPE: 539 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 540 | break; 541 | case SYSTEM_ALARM_CALLBACK_ACE_TYPE: 542 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 543 | break; 544 | case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 545 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 546 | break; 547 | case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE: 548 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 549 | break; 550 | case SYSTEM_MANDATORY_LABEL_ACE_TYPE: 551 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 552 | break; 553 | case SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE: 554 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 555 | break; 556 | case SYSTEM_SCOPED_POLICY_ID_ACE_TYPE: 557 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 558 | break; 559 | case SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE: 560 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 561 | break; 562 | case SYSTEM_ACCESS_FILTER_ACE_TYPE: 563 | DisplayAccessControlEntryBody(lpAce, lpszPrefix, Idx); 564 | break; 565 | default: 566 | break; 567 | } 568 | } 569 | 570 | } 571 | 572 | -------------------------------------------------------------------------------- /sddl-display/DisplayAccessControlEntryHeader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace sddldisplay { 6 | 7 | void DisplayAccessControlEntryHeader(PVOID lpAce, PCTSTR lpszPrefix, DWORD Idx) { 8 | auto lpAceHeader = reinterpret_cast(lpAce); 9 | switch (lpAceHeader->AceType) { 10 | #define ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(pref, i, t) case t: _tprintf_s(TEXT("%s : ->Ace[%u]: ->AceType : 0x%.2x (%s)\n"), pref, Idx, t, TEXT(#t)); break 11 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_ALLOWED_ACE_TYPE); 12 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_DENIED_ACE_TYPE); 13 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_AUDIT_ACE_TYPE); 14 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_ALARM_ACE_TYPE); 15 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_ALLOWED_COMPOUND_ACE_TYPE); 16 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_ALLOWED_OBJECT_ACE_TYPE); 17 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_DENIED_OBJECT_ACE_TYPE); 18 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_AUDIT_OBJECT_ACE_TYPE); 19 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_ALARM_OBJECT_ACE_TYPE); 20 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_ALLOWED_CALLBACK_ACE_TYPE); 21 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_DENIED_CALLBACK_ACE_TYPE); 22 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE); 23 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE); 24 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_AUDIT_CALLBACK_ACE_TYPE); 25 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_ALARM_CALLBACK_ACE_TYPE); 26 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE); 27 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE); 28 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_MANDATORY_LABEL_ACE_TYPE); 29 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE); 30 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_SCOPED_POLICY_ID_ACE_TYPE); 31 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE); 32 | ACCESS_CONTROL_ENTRY_DISPLAY_TYPE(lpszPrefix, Idx, SYSTEM_ACCESS_FILTER_ACE_TYPE); 33 | default: throw std::invalid_argument("Unknown AceType."); 34 | #undef ACCESS_CONTROL_ENTRY_DISPLAY_TYPE 35 | } 36 | 37 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->AceFlags: 0x%.2x\n"), lpszPrefix, Idx, lpAceHeader->AceFlags); 38 | 39 | #define ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(p, v, f) if (((v) & (f)) != 0) _tprintf_s(TEXT("%*c: (0x%.2x) %s\n"), p, TEXT(' '), f, TEXT(#f)) 40 | int padding = _sctprintf(TEXT("%s : ->Ace[%u]: ->AceFlags"), lpszPrefix, Idx); 41 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, OBJECT_INHERIT_ACE); 42 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, CONTAINER_INHERIT_ACE); 43 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, NO_PROPAGATE_INHERIT_ACE); 44 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, INHERIT_ONLY_ACE); 45 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, INHERITED_ACE); 46 | 47 | if (lpAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) { 48 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, CRITICAL_ACE_FLAG); 49 | } 50 | 51 | switch (lpAceHeader->AceType) { 52 | case SYSTEM_AUDIT_ACE_TYPE: 53 | case SYSTEM_AUDIT_OBJECT_ACE_TYPE: 54 | case SYSTEM_AUDIT_CALLBACK_ACE_TYPE: 55 | case SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE: 56 | case SYSTEM_ALARM_ACE_TYPE: 57 | case SYSTEM_ALARM_OBJECT_ACE_TYPE: 58 | case SYSTEM_ALARM_CALLBACK_ACE_TYPE: 59 | case SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE: 60 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, SUCCESSFUL_ACCESS_ACE_FLAG); 61 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, FAILED_ACCESS_ACE_FLAG); 62 | default: 63 | break; 64 | } 65 | 66 | if (lpAceHeader->AceType == SYSTEM_ACCESS_FILTER_ACE_TYPE) { 67 | ACCESS_CONTROL_ENTRY_DISPLAY_FLAG(padding, lpAceHeader->AceFlags, TRUST_PROTECTED_FILTER_ACE_FLAG); 68 | } 69 | #undef ACCESS_CONTROL_ENTRY_DISPLAY_FLAG 70 | 71 | _tprintf_s(TEXT("%s : ->Ace[%u]: ->AceSize : 0x%x\n"), lpszPrefix, Idx, lpAceHeader->AceSize); 72 | } 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /sddl-display/DisplaySecurityDescriptorDacl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #pragma comment(lib, "advapi32") 11 | 12 | namespace sddldisplay { 13 | 14 | void DisplayAccessControlEntryHeader(PVOID lpAce, PCTSTR lpszPrefix, DWORD Idx); 15 | 16 | void DisplayAccessControlEntryBody(PVOID lpAce, PCTSTR lpszPrefix, DWORD Idx); 17 | 18 | void DisplaySecurityDescriptorDacl(PSECURITY_DESCRIPTOR lpSecurityDescriptor) { 19 | BOOL bDaclPresent; 20 | PACL lpDacl = NULL; 21 | BOOL bIsDefaulted; 22 | 23 | if (GetSecurityDescriptorDacl(lpSecurityDescriptor, &bDaclPresent, &lpDacl, &bIsDefaulted) == FALSE) { 24 | auto err = GetLastError(); 25 | throw std::system_error(err, std::system_category()); 26 | } 27 | 28 | if (bDaclPresent) { 29 | _tprintf_s(TEXT("->Dacl : ->AclRevision: 0x%x\n"), lpDacl->AclRevision); 30 | _tprintf_s(TEXT("->Dacl : ->Sbz1 : 0x%x\n"), lpDacl->Sbz1); 31 | _tprintf_s(TEXT("->Dacl : ->AclSize : 0x%x\n"), lpDacl->AclSize); 32 | _tprintf_s(TEXT("->Dacl : ->AceCount : 0x%x\n"), lpDacl->AceCount); 33 | _tprintf_s(TEXT("->Dacl : ->Sbz2 : 0x%x\n"), lpDacl->Sbz2); 34 | 35 | for (DWORD i = 0; i < lpDacl->AceCount; ++i) { 36 | PACE_HEADER lpAceHdr = NULL; 37 | if (GetAce(lpDacl, i, reinterpret_cast(&lpAceHdr))) { 38 | DisplayAccessControlEntryHeader(lpAceHdr, TEXT("->Dacl"), i); 39 | DisplayAccessControlEntryBody(lpAceHdr, TEXT("->Dacl"), i); 40 | _putts(TEXT("")); 41 | } else { 42 | auto err = GetLastError(); 43 | throw std::system_error(err, std::system_category()); 44 | } 45 | } 46 | 47 | if (lpDacl->AceCount == 0) { 48 | _tprintf_s(TEXT("\n")); 49 | } 50 | } else { 51 | _tprintf_s(TEXT("->Dacl : is NULL\n")); 52 | _tprintf_s(TEXT("\n")); 53 | } 54 | } 55 | 56 | } 57 | 58 | -------------------------------------------------------------------------------- /sddl-display/DisplaySecurityDescriptorHeader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #pragma comment(lib, "advapi32") 11 | 12 | namespace sddldisplay { 13 | 14 | std::xstring ConvertSidToAccountName(PSID lpSid); 15 | 16 | void DisplaySecurityDescriptorHeader(PSECURITY_DESCRIPTOR lpSecurityDescriptor) { 17 | DWORD Revision; 18 | UCHAR Sbz1; 19 | SECURITY_DESCRIPTOR_CONTROL Control; 20 | 21 | PSID lpSidOwner; 22 | ResourceOwned lpszSidOwner(LocalAllocTraits{}); 23 | std::xstring szOwnerName; 24 | 25 | PSID lpSidGroup; 26 | ResourceOwned lpszSidGroup(LocalAllocTraits{}); 27 | std::xstring szGroupName; 28 | 29 | if (GetSecurityDescriptorControl(lpSecurityDescriptor, &Control, &Revision) == FALSE) { 30 | auto err = GetLastError(); 31 | throw std::system_error(err, std::system_category()); 32 | } 33 | 34 | if (GetSecurityDescriptorRMControl(lpSecurityDescriptor, &Sbz1) == FALSE) { 35 | auto err = GetLastError(); 36 | throw std::system_error(err, std::system_category()); 37 | } 38 | 39 | if (BOOL _; GetSecurityDescriptorOwner(lpSecurityDescriptor, &lpSidOwner, &_) == FALSE) { 40 | auto err = GetLastError(); 41 | throw std::system_error(err, std::system_category()); 42 | } 43 | 44 | if (lpSidOwner) { 45 | if (ConvertSidToStringSid(lpSidOwner, lpszSidOwner.GetAddressOf()) == FALSE) { 46 | auto err = GetLastError(); 47 | throw std::system_error(err, std::system_category()); 48 | } 49 | 50 | szOwnerName = ConvertSidToAccountName(lpSidOwner); 51 | } 52 | 53 | if (BOOL _; GetSecurityDescriptorGroup(lpSecurityDescriptor, &lpSidGroup, &_) == FALSE) { 54 | auto err = GetLastError(); 55 | throw std::system_error(err, std::system_category()); 56 | } 57 | 58 | if (lpSidGroup) { 59 | if (ConvertSidToStringSid(lpSidGroup, lpszSidGroup.GetAddressOf()) == FALSE) { 60 | auto err = GetLastError(); 61 | throw std::system_error(err, std::system_category()); 62 | } 63 | 64 | szGroupName = ConvertSidToAccountName(lpSidGroup); 65 | } 66 | 67 | _tprintf_s(TEXT("->Revision: 0x%x\n"), Revision); 68 | _tprintf_s(TEXT("->Sbz1 : 0x%x\n"), Sbz1); 69 | _tprintf_s(TEXT("->Control : 0x%x\n"), Control); 70 | 71 | #define SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(v, f) if (((v) & (f)) != 0) _tprintf_s(TEXT(" : (0x%.4x) %s\n"), f, TEXT(#f)) 72 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_OWNER_DEFAULTED); 73 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_GROUP_DEFAULTED); 74 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_DACL_PRESENT); 75 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_DACL_DEFAULTED); 76 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_SACL_PRESENT); 77 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_SACL_DEFAULTED); 78 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_DACL_AUTO_INHERIT_REQ); 79 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_SACL_AUTO_INHERIT_REQ); 80 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_DACL_AUTO_INHERITED); 81 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_SACL_AUTO_INHERITED); 82 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_DACL_PROTECTED); 83 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_SACL_PROTECTED); 84 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_RM_CONTROL_VALID); 85 | SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG(Control, SE_SELF_RELATIVE); 86 | #undef SECURITY_DESCRIPTOR_CONTROL_DISPLAY_FLAG 87 | 88 | if (lpSidOwner) { 89 | _tprintf_s(TEXT("->Owner : %s (%s)\n"), lpszSidOwner.Get(), szOwnerName.c_str()); 90 | } else { 91 | _tprintf_s(TEXT("->Owner :\n")); 92 | } 93 | 94 | if (lpSidGroup) { 95 | _tprintf_s(TEXT("->Group : %s (%s)\n"), lpszSidGroup.Get(), szGroupName.c_str()); 96 | } else { 97 | _tprintf_s(TEXT("->Group :\n")); 98 | } 99 | } 100 | 101 | } 102 | 103 | -------------------------------------------------------------------------------- /sddl-display/DisplaySecurityDescriptorSacl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | #pragma comment(lib, "advapi32") 7 | 8 | namespace sddldisplay { 9 | 10 | void DisplayAccessControlEntryHeader(PVOID lpAce, PCTSTR lpszPrefix, DWORD Idx); 11 | 12 | void DisplayAccessControlEntryBody(PVOID lpAce, PCTSTR lpszPrefix, DWORD Idx); 13 | 14 | void DisplaySecurityDescriptorSacl(PSECURITY_DESCRIPTOR lpSecurityDescriptor) { 15 | BOOL bSaclPresent; 16 | PACL lpSacl = NULL; 17 | BOOL bIsDefaulted; 18 | 19 | if (GetSecurityDescriptorSacl(lpSecurityDescriptor, &bSaclPresent, &lpSacl, &bIsDefaulted) == FALSE) { 20 | auto err = GetLastError(); 21 | throw std::system_error(err, std::system_category()); 22 | } 23 | 24 | if (bSaclPresent) { 25 | _tprintf_s(TEXT("->Sacl : ->AclRevision: 0x%x\n"), lpSacl->AclRevision); 26 | _tprintf_s(TEXT("->Sacl : ->Sbz1 : 0x%x\n"), lpSacl->Sbz1); 27 | _tprintf_s(TEXT("->Sacl : ->AclSize : 0x%x\n"), lpSacl->AclSize); 28 | _tprintf_s(TEXT("->Sacl : ->AceCount : 0x%x\n"), lpSacl->AceCount); 29 | _tprintf_s(TEXT("->Sacl : ->Sbz2 : 0x%x\n"), lpSacl->Sbz2); 30 | 31 | for (DWORD i = 0; i < lpSacl->AceCount; ++i) { 32 | PACE_HEADER lpAceHdr = NULL; 33 | if (GetAce(lpSacl, i, reinterpret_cast(&lpAceHdr))) { 34 | DisplayAccessControlEntryHeader(lpAceHdr, TEXT("->Sacl"), i); 35 | DisplayAccessControlEntryBody(lpAceHdr, TEXT("->Sacl"), i); 36 | _putts(TEXT("")); 37 | } else { 38 | auto err = GetLastError(); 39 | throw std::system_error(err, std::system_category()); 40 | } 41 | } 42 | 43 | if (lpSacl->AceCount == 0) { 44 | _tprintf_s(TEXT("\n")); 45 | } 46 | } else { 47 | _tprintf_s(TEXT("->Sacl : is NULL\n")); 48 | _tprintf_s(TEXT("\n")); 49 | } 50 | } 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /sddl-display/_tmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace sddldisplay { 11 | 12 | void DisplaySecurityDescriptorHeader(PSECURITY_DESCRIPTOR lpSecurityDescriptor); 13 | 14 | void DisplaySecurityDescriptorDacl(PSECURITY_DESCRIPTOR lpSecurityDescriptor); 15 | 16 | void DisplaySecurityDescriptorSacl(PSECURITY_DESCRIPTOR lpSecurityDescriptor); 17 | 18 | } 19 | 20 | void Help() { 21 | _putts(TEXT("Usage:")); 22 | _putts(TEXT(" sddl-display.exe ")); 23 | _putts(TEXT("")); 24 | } 25 | 26 | int _tmain(int argc, PTSTR argv[]) { 27 | try { 28 | if (argc == 2) { 29 | ResourceOwned lpSecurityDescriptor(LocalAllocTraits{}); 30 | 31 | if (ConvertStringSecurityDescriptorToSecurityDescriptor(argv[1], SDDL_REVISION, lpSecurityDescriptor.GetAddressOf(), NULL) == FALSE) { 32 | auto err = GetLastError(); 33 | throw std::system_error(err, std::system_category()); 34 | } 35 | 36 | sddldisplay::DisplaySecurityDescriptorHeader(lpSecurityDescriptor); 37 | sddldisplay::DisplaySecurityDescriptorDacl(lpSecurityDescriptor); 38 | sddldisplay::DisplaySecurityDescriptorSacl(lpSecurityDescriptor); 39 | 40 | return 0; 41 | } else { 42 | Help(); 43 | return -1; 44 | } 45 | } catch (std::system_error& e) { 46 | _tprintf_s(TEXT("[-] system_error -> %hs (%d)\n"), e.what(), e.code().value()); 47 | return e.code().value(); 48 | } catch (std::exception& e) { 49 | _tprintf_s(TEXT("[-] exception -> %hs\n"), e.what()); 50 | return -1; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sddl-display/sddl-display.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | {9582BE27-9843-462B-BFBB-79427D553966} 24 | Win32Proj 25 | sddldisplay 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | false 35 | 36 | 37 | Application 38 | false 39 | v142 40 | true 41 | Unicode 42 | false 43 | 44 | 45 | Application 46 | true 47 | v142 48 | Unicode 49 | false 50 | 51 | 52 | Application 53 | false 54 | v142 55 | true 56 | Unicode 57 | false 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | true 80 | $(SolutionDir)bin\$(PlatformTarget)-$(Configuration)\ 81 | $(SolutionDir)obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ 82 | 83 | 84 | true 85 | $(SolutionDir)bin\$(PlatformTarget)-$(Configuration)\ 86 | $(SolutionDir)obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ 87 | 88 | 89 | false 90 | $(SolutionDir)bin\$(PlatformTarget)-$(Configuration)\ 91 | $(SolutionDir)obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ 92 | 93 | 94 | false 95 | $(SolutionDir)bin\$(PlatformTarget)-$(Configuration)\ 96 | $(SolutionDir)obj\$(PlatformTarget)-$(Configuration)\$(ProjectName)\ 97 | 98 | 99 | 100 | Level3 101 | Disabled 102 | true 103 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 104 | true 105 | stdcpp17 106 | 107 | 108 | Console 109 | true 110 | 111 | 112 | 113 | 114 | Level3 115 | Disabled 116 | true 117 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 118 | true 119 | stdcpp17 120 | 121 | 122 | Console 123 | true 124 | 125 | 126 | 127 | 128 | Level3 129 | MaxSpeed 130 | true 131 | true 132 | true 133 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 134 | true 135 | stdcpp17 136 | 137 | 138 | Console 139 | true 140 | true 141 | true 142 | 143 | 144 | 145 | 146 | Level3 147 | MaxSpeed 148 | true 149 | true 150 | true 151 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 152 | true 153 | stdcpp17 154 | 155 | 156 | Console 157 | true 158 | true 159 | true 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /sddl-display/sddl-display.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | 源文件 23 | 24 | 25 | 源文件 26 | 27 | 28 | 源文件 29 | 30 | 31 | 源文件 32 | 33 | 34 | 源文件 35 | 36 | 37 | 源文件 38 | 39 | 40 | 源文件 41 | 42 | 43 | -------------------------------------------------------------------------------- /sddl-display/sddl-display.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | --------------------------------------------------------------------------------