From 475a00cc12956c0687f3d8714ab08e83bb76e097 Mon Sep 17 00:00:00 2001 From: serr Date: Thu, 27 Feb 2025 18:11:42 +0300 Subject: [PATCH] new --- cod3k.h | 127 +++++++++++++++++++++++++++++++++ get_access_rights.c | 170 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 cod3k.h create mode 100644 get_access_rights.c diff --git a/cod3k.h b/cod3k.h new file mode 100644 index 0000000..69978da --- /dev/null +++ b/cod3k.h @@ -0,0 +1,127 @@ +// Small module for correct Russian localization of programs written in C/C++ under Windows +#pragma once +#include +#include +#include +#include +#include + +#define WT _T // WT = widechar text - Macro for declaring constant widechar strings +#define W_SET wmemset // Memset for wchar + +// Internal functions of the module, not intended for use in user code +int set_unicode_mode(void); // Enable unicode mode +int set_default_mode(void); // Enable default mode +// + +void wwrite(TCHAR* dst, size_t dst_size); // Input wide char characters from console into array +void wprint(wchar_t* format, ...); // Formatted output of wide char array to console +void bwprint(wchar_t* arr, size_t size); // Output wide char array in binary form to console +void bcprint(char* arr, size_t size); // Output char array in binary form to console +TCHAR* ctow(char* arr1, TCHAR* arr2); // Converts char array to wide char array +char* wtoc(TCHAR* arr1, char* arr2); // Converts wide char array to char array + +enum COD3K_ERRORS { + SETMODE_ERROR_STDIN = -228, + SETMODE_ERROR_STDOUT, + SETMODE_ERROR_STDERR +}; + +// Enable Unicode mode +int set_unicode_mode(void) { + int err_inp, err_out, err_err; + if ((err_inp = _setmode(_fileno(stdin), _O_WTEXT)) == -1) { // Unicode mode for input stream + return SETMODE_ERROR_STDIN; + } + if ((err_inp = _setmode(_fileno(stdout), _O_WTEXT)) == -1) { // Unicode mode for output stream + return SETMODE_ERROR_STDOUT; + } + if ((err_err = _setmode(_fileno(stderr), _O_WTEXT)) == -1) { // Unicode mode for error stream + return SETMODE_ERROR_STDERR; + } +} + +// Disable Unicode mode +int set_default_mode(void) { + int err_inp, err_out, err_err; + if ((err_inp = _setmode(_fileno(stdin), _O_TEXT)) == -1) { // Restore mode for input stream + return SETMODE_ERROR_STDIN; + } + if ((err_out = _setmode(_fileno(stdout), _O_TEXT)) == -1) { // Restore mode for output stream + return SETMODE_ERROR_STDOUT; + } + if ((err_err = _setmode(_fileno(stderr), _O_TEXT)) == -1) { // Restore mode for error stream + return SETMODE_ERROR_STDERR; + } + return 0; +} + +// Formatted output of wide char array to console +void wprint(const wchar_t* format, ...) { + set_unicode_mode(); + va_list args; + va_start(args, format); vfwprintf(stdout, format, args); va_end(args); + set_default_mode(); +} + +// Function to print the first 'size' characters of wchar_t array in binary form +void bwprint(wchar_t* arr, size_t size) { + for (size_t i = 0; i < size; i++) { + for (int j = sizeof(wchar_t) * 8 - 1; j >= 0; j--) { + putchar((arr[i] & (1 << j)) ? '1' : '0'); + } + putchar(' '); + } + putchar('\n'); +} + +// Function to print the first 'size' characters of char array in binary form +void bcprint(char* arr, size_t size) { + for (size_t i = 0; i < size; i++) { + for (int j = sizeof(char) * 8 - 1; j >= 0; j--) { + putchar((arr[i] & (1 << j)) ? '1' : '0'); + } + putchar(' '); + } + putchar('\n'); +} + +// dst - TCHAR a.k.a wchar_t array, into which characters from console will be written, size - size of this array +// removes newline character +void wwrite(TCHAR* dst, size_t dst_size) { + set_unicode_mode(); + fgetws(dst, dst_size, stdin); dst[wcslen(dst) - 1] = 0; + set_default_mode(); +} + +// char to wide char conversion +TCHAR* ctow(char* arr1, TCHAR* arr2) { + int i = 0; + for (char* p_byte = arr1; *p_byte != 0; ++p_byte) { + char byte = *p_byte; + if (byte & 0x80) { // bit at position 8 is set => Russian text + // clear bit at position 8 + + // set bit at position 11 (this is necessary for correct wide char if the text is not ASCII) + arr2[i] = byte & 0x7F | 0x400; + } + else { // English text + arr2[i] = byte; + } + ++i; + } + return arr2; +} + +// widechar to char +char* wtoc(TCHAR* arr1, char* arr2) { + int i = 0; + for (TCHAR* p_wbyte = arr1; *p_wbyte != 0; ++p_wbyte) { + TCHAR wbyte = *p_wbyte; + arr2[i] = (char)(wbyte & 0xFF); // lower 8 bits + if (wbyte & 0x400) { // if the 11th bit is set, the text is Russian + arr2[i] |= 0x80; // marker for Russian text in char - set the 8th bit + } + ++i; + } + return arr2; +} \ No newline at end of file diff --git a/get_access_rights.c b/get_access_rights.c new file mode 100644 index 0000000..b221457 --- /dev/null +++ b/get_access_rights.c @@ -0,0 +1,170 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include "cod3k.h" + +wchar_t* GetAccessRights(PSECURITY_DESCRIPTOR pSD) { + PACL pDacl = NULL; + BOOL bDaclPresent = FALSE; + BOOL bDaclDefaulted = FALSE; + + // Результирующая строка + size_t RES_SIZE = 4096; // начальный размер + size_t count = 0; // количество символов в строке + wchar_t* res = (wchar_t*)malloc(RES_SIZE * sizeof(wchar_t)); + W_SET(res, 0, RES_SIZE); + if (!res) { + wprintf(L"Memory allocation failed\n"); + return NULL; + } + + // Получаем DACL (Discretionary Access Control List) из дескриптора безопасности + if (!GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pDacl, &bDaclDefaulted)) { + swprintf(res, RES_SIZE, L"GetSecurityDescriptorDacl failed (%d)\n", GetLastError()); + return res; + } + + if (!bDaclPresent || pDacl == NULL) { + swprintf(res, RES_SIZE, L"No DACL present (no access restrictions)\n"); + return res; + } + + // Перебираем все ACE (Access Control Entries) в DACL + for (DWORD i = 0; i < pDacl->AceCount; i++) { + PACE_HEADER pAceHeader; + if (!GetAce(pDacl, i, (LPVOID*)&pAceHeader)) { + swprintf(res + count, RES_SIZE - count, L"GetAce failed (%d)\n", GetLastError()); + count += wcslen(res + count); + continue; + } + + // Обрабатываем только ACCESS_ALLOWED_ACE_TYPE + if (pAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) { + PACCESS_ALLOWED_ACE pAce = (PACCESS_ALLOWED_ACE)pAceHeader; + + // Получаем SID субъекта + PSID pSid = (PSID)&pAce->SidStart; + + // Преобразуем SID в текстовый формат + LPWSTR pszSid = NULL; + if (!ConvertSidToStringSidW(pSid, &pszSid)) { + swprintf(res + count, RES_SIZE - count, L"ConvertSidToStringSid failed (%d)\n", GetLastError()); + count += wcslen(res + count); + continue; + } + + // Получаем имя субъекта по SID + WCHAR szName[256]; + WCHAR szDomain[256]; + DWORD dwNameSize = sizeof(szName) / sizeof(szName[0]); + DWORD dwDomainSize = sizeof(szDomain) / sizeof(szDomain[0]); + SID_NAME_USE eUse; + if (!LookupAccountSidW(NULL, pSid, szName, &dwNameSize, szDomain, &dwDomainSize, &eUse)) { + swprintf(res + count, RES_SIZE - count, L"LookupAccountSid failed (%d)\n", GetLastError()); + count += wcslen(res + count); + LocalFree(pszSid); + continue; + } + + // Формируем строку с информацией о субъекте + count += swprintf(res + count, RES_SIZE - count, L"SID: %s\n", pszSid); + count += swprintf(res + count, RES_SIZE - count, L"Name: %s\\%s\n", szDomain, szName); + + // Формируем строку с маской доступа и её описанием + DWORD dwMask = pAce->Mask; + count += swprintf(res + count, RES_SIZE - count, L"Access Mask: 0x%08X\n", dwMask); + count += swprintf(res + count, RES_SIZE - count, L"Access Rights:\n"); + + if (dwMask & FILE_READ_DATA) count += swprintf(res + count, RES_SIZE - count, L" FILE_READ_DATA\n"); + if (dwMask & FILE_WRITE_DATA) count += swprintf(res + count, RES_SIZE - count, L" FILE_WRITE_DATA\n"); + if (dwMask & FILE_APPEND_DATA) count += swprintf(res + count, RES_SIZE - count, L" FILE_APPEND_DATA\n"); + if (dwMask & FILE_READ_EA) count += swprintf(res + count, RES_SIZE - count, L" FILE_READ_EA\n"); + if (dwMask & FILE_WRITE_EA) count += swprintf(res + count, RES_SIZE - count, L" FILE_WRITE_EA\n"); + if (dwMask & FILE_EXECUTE) count += swprintf(res + count, RES_SIZE - count, L" FILE_EXECUTE\n"); + if (dwMask & FILE_DELETE_CHILD) count += swprintf(res + count, RES_SIZE - count, L" FILE_DELETE_CHILD\n"); + if (dwMask & FILE_READ_ATTRIBUTES) count += swprintf(res + count, RES_SIZE - count, L" FILE_READ_ATTRIBUTES\n"); + if (dwMask & FILE_WRITE_ATTRIBUTES) count += swprintf(res + count, RES_SIZE - count, L" FILE_WRITE_ATTRIBUTES\n"); + if (dwMask & DELETE) count += swprintf(res + count, RES_SIZE - count, L" DELETE\n"); + if (dwMask & READ_CONTROL) count += swprintf(res + count, RES_SIZE - count, L" READ_CONTROL\n"); + if (dwMask & WRITE_DAC) count += swprintf(res + count, RES_SIZE - count, L" WRITE_DAC\n"); + if (dwMask & WRITE_OWNER) count += swprintf(res + count, RES_SIZE - count, L" WRITE_OWNER\n"); + if (dwMask & SYNCHRONIZE) count += swprintf(res + count, RES_SIZE - count, L" SYNCHRONIZE\n"); + + LocalFree(pszSid); + } + } + + return res; +} + +PSECURITY_DESCRIPTOR get_reg_PSD(wchar_t* path) { + HKEY hKey; + LONG lRes = RegOpenKeyExW(HKEY_CURRENT_USER, path, 0, KEY_ALL_ACCESS, &hKey); + if (lRes != ERROR_SUCCESS) { + wprintf(L"RegOpenKeyEx failed (%d)\n", lRes); + return NULL; + } + + DWORD dwSize = 0; + DWORD dwRes = RegGetKeySecurity(hKey, DACL_SECURITY_INFORMATION, NULL, &dwSize); + if (dwRes != ERROR_INSUFFICIENT_BUFFER) { + wprintf(L"RegGetKeySecurity failed (%d)\n", dwRes); + return NULL; + } + + PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)malloc(dwSize); + if (!pSD) { + wprintf(L"Memory allocation failed\n"); + return NULL; + } + + dwRes = RegGetKeySecurity(hKey, DACL_SECURITY_INFORMATION, pSD, &dwSize); + if (dwRes != ERROR_SUCCESS) { + wprintf(L"RegGetKeySecurity failed (%d)\n", dwRes); + free(pSD); + return NULL; + } + + RegCloseKey(hKey); + + return pSD; +} + +PSECURITY_DESCRIPTOR get_PSD(wchar_t* path) { + PSECURITY_DESCRIPTOR pSD = NULL; + DWORD dwRes = GetNamedSecurityInfoW(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &pSD); + if (dwRes != ERROR_SUCCESS) { + wprint(L"GetNamedSecurityInfo failed (%d)\n", dwRes); + return 1; + } + return pSD; +} + +int main() { + const wchar_t* path = L"C:\\Users\\user\\Desktop\\УЧЕБА\\5 СЕМ\\СЕТИ"; + // Получаем дескриптор безопасности для указанного файла + PSECURITY_DESCRIPTOR pSD = get_PSD(path); + // Выводим информацию о правах доступа + wchar_t* info = GetAccessRights(pSD); + wprint(info); + free(info); + // Освобождаем память + LocalFree(pSD); + + printf("\n\n\n"); + + const wchar_t* keyPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"; + // Получаем дескриптор безопасности для ключа реестра + pSD = get_reg_PSD((wchar_t*)keyPath); + // Выводим информацию о правах доступа + info = GetAccessRights(pSD); + wprint(L"%s", info); + free(info); + // Освобождаем память + free(pSD); + + return 0; +} \ No newline at end of file