Skip to content

Instantly share code, notes, and snippets.

@dragokas
Created March 27, 2024 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dragokas/5827432cd08d07cee28c9113c5ed9c89 to your computer and use it in GitHub Desktop.
Save dragokas/5827432cd08d07cee28c9113c5ed9c89 to your computer and use it in GitHub Desktop.
#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