Created
March 27, 2024 00:25
-
-
Save dragokas/5827432cd08d07cee28c9113c5ed9c89 to your computer and use it in GitHub Desktop.
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 <iostream> | |
#include <stdio.h> | |
#include <windows.h> | |
#include <vector> | |
#include <Iads.h> | |
#include <map> | |
enum ACCESS_OBJECT_TYPE | |
{ | |
ACCESS_OBJECT_FILE, | |
ACCESS_OBJECT_FOLDER, | |
ACCESS_OBJECT_REGISTRY_KEY | |
}; | |
void DecodeAccessMaskRights(int mask, ACCESS_OBJECT_TYPE objectType) | |
{ | |
const int FILE_GENERIC_ALL = FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | | |
DELETE | WRITE_DAC | WRITE_OWNER | FILE_DELETE_CHILD; | |
std::vector<std::pair<std::wstring, int>> listGen; | |
std::vector<std::pair<std::wstring, int>> listOther; | |
// icacls doing this way: | |
/* | |
listGen.push_back(std::pair<std::wstring, int>(L"F", FILE_GENERIC_ALL)); | |
listGen.push_back(std::pair<std::wstring, int>(L"RX", FILE_GENERIC_READ | FILE_GENERIC_EXECUTE)); | |
listGen.push_back(std::pair<std::wstring, int>(L"M", FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE | DELETE)); | |
listGen.push_back(std::pair<std::wstring, int>(L"R", FILE_GENERIC_READ)); | |
listGen.push_back(std::pair<std::wstring, int>(L"W", FILE_GENERIC_WRITE & ~READ_CONTROL)); | |
listGen.push_back(std::pair<std::wstring, int>(L"D", DELETE | SYNCHRONIZE)); | |
*/ | |
// Generic access rights | |
listGen.push_back(std::pair<std::wstring, int>(L"GA", GENERIC_ALL)); | |
listGen.push_back(std::pair<std::wstring, int>(L"GR", GENERIC_READ)); | |
listGen.push_back(std::pair<std::wstring, int>(L"GW", GENERIC_WRITE)); | |
listGen.push_back(std::pair<std::wstring, int>(L"GX", GENERIC_EXECUTE)); | |
// Other | |
listOther.push_back(std::pair<std::wstring, int>(L"MA", MAXIMUM_ALLOWED)); | |
listOther.push_back(std::pair<std::wstring, int>(L"AS", ACCESS_SYSTEM_SECURITY)); | |
if (objectType == ACCESS_OBJECT_FILE || objectType == ACCESS_OBJECT_FOLDER) | |
{ | |
// File access rights (standart + some specific) | |
listGen.push_back(std::pair<std::wstring, int>(L"FA", FILE_GENERIC_ALL)); | |
listGen.push_back(std::pair<std::wstring, int>(L"FR", FILE_GENERIC_READ)); | |
listGen.push_back(std::pair<std::wstring, int>(L"FW", FILE_GENERIC_WRITE)); | |
listGen.push_back(std::pair<std::wstring, int>(L"FX", FILE_GENERIC_EXECUTE)); | |
} | |
if (objectType == ACCESS_OBJECT_REGISTRY_KEY) | |
{ | |
// Registry key access rights (standart + some specific) | |
listGen.push_back(std::pair<std::wstring, int>(L"KA", KEY_ALL_ACCESS)); | |
listGen.push_back(std::pair<std::wstring, int>(L"KR", KEY_READ)); | |
listGen.push_back(std::pair<std::wstring, int>(L"KW", KEY_WRITE)); | |
listGen.push_back(std::pair<std::wstring, int>(L"KX", KEY_EXECUTE)); | |
} | |
// Standard access rights | |
listOther.push_back(std::pair<std::wstring, int>(L"SD", DELETE)); | |
listOther.push_back(std::pair<std::wstring, int>(L"RC", READ_CONTROL)); | |
listOther.push_back(std::pair<std::wstring, int>(L"WDAC", WRITE_DAC)); | |
listOther.push_back(std::pair<std::wstring, int>(L"WO", WRITE_OWNER)); | |
listOther.push_back(std::pair<std::wstring, int>(L"S", SYNCHRONIZE)); | |
// Object specific access rights | |
if (objectType == ACCESS_OBJECT_FILE || objectType == ACCESS_OBJECT_FOLDER) | |
{ | |
listOther.push_back(std::pair<std::wstring, int>(L"REA", FILE_READ_EA)); | |
listOther.push_back(std::pair<std::wstring, int>(L"WEA", FILE_WRITE_EA)); | |
listOther.push_back(std::pair<std::wstring, int>(L"RA", FILE_READ_ATTRIBUTES)); | |
listOther.push_back(std::pair<std::wstring, int>(L"WA", FILE_WRITE_ATTRIBUTES)); | |
// For a shorter code, let's limiting to folder object only | |
/* | |
if (objectType == ACCESS_OBJECT_FILE) | |
{ | |
listOther.push_back(std::pair<std::wstring, int>(L"RD", FILE_READ_DATA)); | |
listOther.push_back(std::pair<std::wstring, int>(L"WD", FILE_WRITE_DATA)); | |
listOther.push_back(std::pair<std::wstring, int>(L"AD", FILE_APPEND_DATA)); | |
listOther.push_back(std::pair<std::wstring, int>(L"X", FILE_EXECUTE)); | |
} | |
*/ | |
//if (objectType == ACCESS_OBJECT_FOLDER) | |
{ | |
listOther.push_back(std::pair<std::wstring, int>(L"RD", FILE_LIST_DIRECTORY)); | |
listOther.push_back(std::pair<std::wstring, int>(L"WD", FILE_ADD_FILE)); | |
listOther.push_back(std::pair<std::wstring, int>(L"AD", FILE_ADD_SUBDIRECTORY)); | |
listOther.push_back(std::pair<std::wstring, int>(L"X", FILE_TRAVERSE)); | |
listOther.push_back(std::pair<std::wstring, int>(L"DC", FILE_DELETE_CHILD)); | |
} | |
} | |
std::wstring szRights; | |
int maskLeft = mask; | |
int maskGen = 0; | |
for (auto it : listGen) | |
{ | |
if ((maskLeft & it.second) == it.second) | |
{ | |
szRights += it.first + L","; | |
maskGen |= it.second; | |
} | |
} | |
maskLeft &= ~maskGen; | |
for (auto it : listOther) | |
{ | |
if ((maskLeft & it.second) == it.second) | |
{ | |
maskLeft &= ~it.second; | |
szRights += it.first + L","; | |
} | |
} | |
szRights.pop_back(); | |
if (maskLeft == 0) | |
{ | |
wprintf_s(L"mask 0x%X = %s\n", mask, szRights.c_str()); | |
} | |
else { | |
wprintf_s(L"mask 0x%X = %s,0x%X\n", mask, szRights.c_str(), maskLeft); | |
} | |
} | |
int main() | |
{ | |
DecodeAccessMaskRights(0x1201ff, ACCESS_OBJECT_TYPE::ACCESS_OBJECT_FOLDER); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment