Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

DALC и процесс

54K
27 октября 2010 года
Stoneman
6 / / 28.02.2010
Вообщем я хочу создать процесс, который допустим нельзя грохнуть или запретить менять для него владельца.
То есть хочу отобрать некоторые права у самого себя. Ниже привожу код, пытаюсь запустить калькулятор, без прав на его завершения.
Код работает без ошибок, но процесс все равно грохается без проблем. Подскажите в чем может быть проблема?
Код:
#ifndef UNICODE
      #define UNICODE
      #endif
      #include <windows.h>
      #include <stdio.h>
      #include <lm.h>
       
      int main()
      {
       
       
        HANDLE hProcess;
        ACL *lpDacl;           // указатель на список доступа
        DWORD dwDaclLength;    // длина списка доступа
       
        wchar_t wchUserName[UNLEN];      // имя пользователя
       
        DWORD dwLengthOfDomainName = 0;  // длина имени домена
       
        DWORD dwLengthOfSid = 0;         // длина SID
        SID *lpSid = NULL;               // указатель на SID
        LPTSTR lpDomainName = NULL;      // указатель на имя домена
       
        SID_NAME_USE typeOfSid;    // тип учетной записи
       
        SECURITY_DESCRIPTOR sd;    // дескриптор безопасности
        SECURITY_ATTRIBUTES sa;    // атрибуты защиты
       
        DWORD dwRetCode;   // код возврата
       
        // вводим имя пользователя, которому разрешим\запретип  доступ
        printf("Input a user name: ");
        _getws(wchUserName);
       
        // определяем длину SID пользователя
        if (!LookupAccountName(
          NULL,              // ищем имя на локальном компьютере
          wchUserName,       // имя пользователя
          NULL,              // определяем длину SID
          &dwLengthOfSid,    // длина SID
          NULL,              // определяем имя домена
          &dwLengthOfDomainName,  // длина имени домена
          &typeOfSid))       // тип учетной записи
        {
          dwRetCode = GetLastError();
       
          if (dwRetCode == ERROR_INSUFFICIENT_BUFFER)
          {
            // распределяем память для SID и имени домена
            lpSid = (SID*) new char[dwLengthOfSid];
            lpDomainName = (LPTSTR) new wchar_t[dwLengthOfDomainName];
          }
          else
          {
            // выходим из программы
            printf("Lookup account name failed.\n");
            printf("Error code: %d\n", dwRetCode);
      getchar();
            return dwRetCode;
          }
        }
       
        // определяем SID и имя домена пользователя
        if(!LookupAccountName(
          NULL,              // ищем имя на локальном компьютере
          wchUserName,       // имя пользователя
          lpSid,             // указатель на SID
          &dwLengthOfSid,    // длина SID
          lpDomainName,      // указатель на имя домена
          &dwLengthOfDomainName,  // длина имени домена
          &typeOfSid))       // тип учетной записи
        {
          dwRetCode = GetLastError();
       
          printf("Lookup account name failed.\n");
          printf("Error code: %d\n", dwRetCode);
      getchar();
          return dwRetCode;
        }
       
        // проверяем тип SID
        if (typeOfSid != SidTypeUser)
        {
          printf("This is not a user name.\n");
          getchar();
          return 1;
        }
       
        // определем длину списка DACL
        dwDaclLength = sizeof(ACL)
          + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + dwLengthOfSid
          + sizeof(ACCESS_DENIED_ACE) - sizeof(DWORD) + dwLengthOfSid;
       
        // распределяем память под DACL
        lpDacl = (ACL*)new char[dwDaclLength];
       
        // инициализируем список DACL
        if (!InitializeAcl(
          lpDacl,          // адрес DACL
          dwDaclLength,    // длина DACL
          ACL_REVISION))   // версия DACL
        {
          dwRetCode = GetLastError();
       
          printf("Lookup account name failed.\n");
          printf("Error code: %d\n", dwRetCode);
      getchar();
          return dwRetCode;
        }
       
        // добавляем запрещающий элемент в список DACL
        if (!AddAccessDeniedAce(
          lpDacl,          // адрес DACL
          ACL_REVISION,    // версия DACL
          PROCESS_TERMINATE,     // запрещаем грохать объект
          lpSid))          // адрес SID
        {
          dwRetCode = GetLastError();
          perror("Add access denied ace failed.\n");
          printf("The last error code: %u\n", dwRetCode);
      getchar();
          return dwRetCode;
        }
       
        // добавляем разрешающий элемент в список DACL
        if (!AddAccessAllowedAce(
          lpDacl,        // адрес DACL
          ACL_REVISION,  // версия DACL
          WRITE_DAC,   // разрешаем менять dacl
          lpSid))        // адрес SID
        {
          dwRetCode = GetLastError();
          perror("Add access allowed ace failed.\n");
          printf("The last error code: %u\n", dwRetCode);
      getchar();
          return dwRetCode;
        }
       
        // инициализируем версию дескриптора безопасности
        if (!InitializeSecurityDescriptor(
          &sd,
          SECURITY_DESCRIPTOR_REVISION))
        {
          dwRetCode = GetLastError();
          printf("Initialize security descroptor failed.\n");
          printf("Error code: %d\n", dwRetCode);
      getchar();
          return dwRetCode;
        }
       
        // устанавливаем SID владельца объекта
        if (!SetSecurityDescriptorOwner(
          &sd,         // адрес дескриптора безопасности
          NULL,        // не задаем владельца
          SE_OWNER_DEFAULTED))    // определить владельца по умолчанию
        {
          dwRetCode = GetLastError();
          perror("Set security descriptor owner failed.\n");
          printf("The last error code: %u\n", dwRetCode);
      getchar();
          return dwRetCode;
        }
       
        // устанавливаем SID первичной группы владельца
        if (!SetSecurityDescriptorGroup(
          &sd,         // адрес дескриптора безопасности
          NULL,        // не задаем первичную группу
          SE_GROUP_DEFAULTED))    // определить первичную группу по умолчанию
        {
          dwRetCode = GetLastError();
          perror("Set security descriptor group failed.\n");
          printf("The last error code: %u\n", dwRetCode);
      getchar();
          return dwRetCode;
        }
        // устанавливаем DACL  в дескриптор безопасности
        if (!SetSecurityDescriptorDacl(
          &sd,       // адрес дескриптора безопасности
          TRUE,      // DACL присутствует
          lpDacl,    // указатель на DACL
          FALSE))    // DACL не задан по умолчанию
        {
          dwRetCode = GetLastError();
          perror("Set security descriptor group failed.\n");
          printf("The last error code: %u\n", dwRetCode);
      getchar();
          return dwRetCode;
        }
       
        // проверяем структуру дескриптора безопасности
        if (!IsValidSecurityDescriptor(&sd))
        {
          dwRetCode = GetLastError();
          perror("Security descriptor is invalid.\n");
          printf("The last error code: %u\n", dwRetCode);
          getchar();
          return dwRetCode;
        }
       
        // инициализируем атрибуты безопасности
        sa.nLength = sizeof(sa);       // устанавливаем длину атрибутов защиты
        sa.lpSecurityDescriptor = &sd;   // устанавливаем адрес SD
        sa.bInheritHandle = FALSE;     // дескриптор не наследуемый
       
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
       
        ZeroMemory( &si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi));
       
       
         CreateProcess(L"C:\\Windows\\System32\\calc.exe",NULL,&sa,NULL,FALSE,0,NULL,NULL,&si,&pi);
         if (pi.hProcess == NULL)
        {
          dwRetCode = GetLastError();
          perror("Create process failed.\n");
          printf("The last error code: %u\n", dwRetCode);
          getchar();
          return dwRetCode;
        }
       
        printf("The process is created.\n");
        getchar();
        // освобождаем память
        delete[] lpSid;
        delete[] lpDomainName;
        delete[] lpDacl;
       
        CloseHandle(pi.hProcess);
       
        return 0;
      }
8.2K
27 октября 2010 года
bagie2
299 / / 26.10.2008
А у меня работает и доступ к процессу запрещен причем не только для TERMINATE а полный запрет к процессу, но я и сижу не под админом. Может плясать от этого?

экспериментально определил, что если у пользователя есть права отлаживать приложения (см. аттач), то он имеет полный доступ к процессам (еще надо запросить SeDebugPrivilege) даже к csrss.exe, например (правда будет BSOD) и может завершить его.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог