Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Защита памяти  (Прочитано 15601 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Disasm
Гость
« : 14-06-2006 03:25 » 

Как защитить память своего приложения от всяких гадостей типа ArtMoney? Или чтобы другие процессы получали ошибку при попытке ReadProcessMomory/WriteProcessMomory. Код защиты должен быть мой и распологаться или в самом защащаемом приложении или в приложении, которое запускает защищаемое.

ProcessGuard не предлагать :)

Спасибо.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 14-06-2006 08:05 » 

Disasm, очень просто Улыбаюсь

блок защищаемых данных выделяешь через new и периодически выделяешь новое место, копируешь туда и удаляешь старые.

Полезно несколько копий данных - и постоянно их синхронизировать
Записан

Disasm
Гость
« Ответ #2 : 14-06-2006 09:04 » 

Дело в том, что приложение (пусть это приложение A) не мое, изменять его структуру я не могу, я мой код является потоком в этом приложении. Как поставить на код и данные приложения такие права, чтобы никакое другое приложение на могло изменять память приложения A. Исходников приложения A у меня нет.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #3 : 19-06-2006 07:19 » 

И при этом "другое приложение" выполнялось под именем администратора? Гм... Много миллиардов наносекунд назад я использовал VirtualProtectEx, и ArtMoney показывал что память моего приложения = 0 МБ. Это не совсем просто - но то что нужно...
Записан

while (8==8)
Disasm
Гость
« Ответ #4 : 19-06-2006 10:05 » 

И при этом "другое приложение" выполнялось под именем администратора? Гм... Много миллиардов наносекунд назад я использовал VirtualProtectEx, и ArtMoney показывал что память моего приложения = 0 МБ. Это не совсем просто - но то что нужно...
Можете рассказать как вы это делали: на какие регионы ставить защиту? Какие флаги защиты?
Записан
sss
Специалист

ru
Offline Offline

« Ответ #5 : 20-06-2006 01:05 » 

Сильно давно было, извини. Сейчас даже старых кодов нет (хана HDD)... Я тут подумал, а почему бы не создавать процесс с дескриптором безопасности, запрещающим PROCESS_VM_OPERATION для всех?
Записан

while (8==8)
Disasm
Гость
« Ответ #6 : 20-06-2006 04:57 » 

Можете рассказать как запускать процесс с этим дескриптором безопасности (а конкретно с флагом запрета PROCESS_VM_OPERATION)?
Записан
sss
Специалист

ru
Offline Offline

« Ответ #7 : 20-06-2006 05:43 » 

Тут тема, я скажу...

Когда нибудь работал cо стандартным SecurityDescriptor? Если просто, он состоит из двух списков - SACL и DACL. Каждая строка такого списка называется ACE. Начнем с ACE.

Это может быть разрешающая или запрещающая доступ строка, или строка аудита.
Создадим union, т.к. это удобно.

Код:
//---------------------------------------------------------------------------
typedef union STANDARD_ACE
{
  ACE_HEADER          aceHeader;
  ACCESS_ALLOWED_ACE  aceAllowed;
  ACCESS_DENIED_ACE   aceDenied;
  SYSTEM_AUDIT_ACE    aceAudit;
} *PSTANDARD_ACE;

#define ACESIDOFFSET  (DWORD)(&((ACCESS_ALLOWED_ACE*) 0)->SidStart)
#define ACESTRUCTSIZE (DWORD)(sizeof(ACCESS_ALLOWED_ACE) - sizeof(((ACCESS_ALLOWED_ACE*) 0)->SidStart))

Дальше создадим класс:
Код:
//***************************************************************************
//* CAce
//***************************************************************************
class CAce
{
private:
  PSTANDARD_ACE FPAce;
public:
  CAce();
  CAce& New(DWORD dwType, DWORD dwFlags, DWORD dwMask, PSID psid);

  CAce& NewAllowed(DWORD dwFlags, DWORD dwMask, PSID psid)
              {return New(ACCESS_ALLOWED_ACE_TYPE, dwFlags, dwMask, psid);};

  CAce& NewDenied(DWORD dwFlags, DWORD dwMask, PSID psid)
              {return New(ACCESS_DENIED_ACE_TYPE, dwFlags, dwMask, psid);};

  CAce& NewAudit(DWORD dwFlags, DWORD dwMask, PSID psid)
              {return New(SYSTEM_AUDIT_ACE_TYPE, dwFlags, dwMask, psid);};

  ~CAce();
  operator PSTANDARD_ACE () {return FPAce;};
};

//***************************************************************************
//* CAce
//***************************************************************************
CAce::CAce()
{
  FPAce = NULL;
}
//---------------------------------------------------------------------------
CAce::~CAce()
{
  if (FPAce) LocalFree(FPAce);
}
//---------------------------------------------------------------------------
CAce& CAce::New(DWORD dwType, DWORD dwFlags, DWORD dwMask, PSID psid)
{
  if (FPAce) LocalFree(FPAce);
  FPAce = NewAce(dwType, dwFlags, dwMask, psid);
  return *this;
}
//---------------------------------------------------------------------------
PSTANDARD_ACE NewAce(DWORD dwType, DWORD dwFlags, DWORD dwMask, PSID psid)
{
  PSTANDARD_ACE pace = NULL;
  PBYTE         buf = NULL;
  try
  {
    DWORD dwSidSize = GetLengthSid(psid);
    buf = (PBYTE) LocalAlloc(LPTR, ACESTRUCTSIZE + dwSidSize);
    if (buf)
    {
      if (CopySid(dwSidSize, (PSID) (buf + ACESIDOFFSET), psid))
      {
        pace = (PSTANDARD_ACE) buf;
        pace->aceHeader.AceSize = (USHORT) (ACESTRUCTSIZE + dwSidSize);
        pace->aceHeader.AceFlags = (BYTE) dwFlags;
        pace->aceHeader.AceType = (BYTE) dwType;
        pace->aceAllowed.Mask = dwMask;
      }
    }
  }
  catch(...) { }
  if (buf != (PBYTE) pace) LocalFree(buf);
  return pace;
}

Теперь ACL


Код:
#define   ACLINITSIZE        0x0400
#define   ACLSIZEDELTA       0x0040
class CAcl
{
private:
  PACL    FPAcl;
  BOOL    FCanonical;
  BOOL    CreateAcl(DWORD dwSize = ACLINITSIZE);

  BOOL    TuningAclSize(PACL  pAddAcl);

  BOOL    TuningAclSize(DWORD dwAddSize);

  // Затирает старый
  BOOL    RewriteAcl(PACL pSrcAcl);

  // Добавляет
  BOOL    AddAcl(PACL pSrcAcl);

  // Возвращает индекс эквивалентного Ace
  int     EqualAceIdx(PSTANDARD_ACE pAce);

public:

  void    clear();

public:
  CAcl();
  ~CAcl() {clear();};
  CAcl& operator += (PSTANDARD_ACE);
  PSTANDARD_ACE operator [] (DWORD idx);
  operator PACL () {return FPAcl;};
  DWORD count();
};
//***************************************************************************
//* CAcl
//***************************************************************************
CAcl::CAcl()
{
  FPAcl = NULL;
  FCanonical = TRUE;
}
//---------------------------------------------------------------------------
void CAcl::clear()
{
  if (FPAcl)
  {
    LocalFree(FPAcl);
    FPAcl = NULL;
  }
}
//---------------------------------------------------------------------------
BOOL CAcl::CreateAcl(DWORD dwSize)
{
  clear();
  if (dwSize < ACLINITSIZE) dwSize = ACLINITSIZE;
  FPAcl = (PACL) LocalAlloc(LPTR, dwSize);
  if (!FPAcl)
  {
    SetLastError(ERROR_OUTOFMEMORY);
    return FALSE;
  }
  else
  if (InitializeAcl(FPAcl, dwSize, ACL_REVISION)) return TRUE;
  else
  {
    LocalFree(FPAcl);
    FPAcl = NULL;
    return FALSE;
  }
}
//---------------------------------------------------------------------------
BOOL  CAcl::TuningAclSize(DWORD dwAddSize)
{
  BOOL fRes = FALSE;
  try
  {
    if (FPAcl == NULL) return CreateAcl(dwAddSize);
    ACL_SIZE_INFORMATION dstasi;
    if (GetAclInformation(FPAcl, &dstasi, sizeof(dstasi), AclSizeInformation))
    {
      if (dstasi.AclBytesFree <= dwAddSize)
      {
        DWORD dwSize =  dstasi.AclBytesInUse + dwAddSize;
        dwSize = ((dwSize / ACLSIZEDELTA) + 1) * ACLSIZEDELTA;
        PACL FTempAcl = (PACL) LocalAlloc(LPTR, dwSize);
        if (!FTempAcl) return FALSE;
        if (!InitializeAcl(FTempAcl, dwSize, ACL_REVISION))
        {
          LocalFree(FTempAcl);
          return FALSE;
        }
        if (CopyAcl(FTempAcl, FPAcl))
        {
          LocalFree(FPAcl);
          FPAcl = FTempAcl;
          fRes = TRUE;
        }
        else LocalFree(FTempAcl);
      }
      else fRes = TRUE;
    }
  }
  catch(...) { }
  return fRes;
}
//---------------------------------------------------------------------------
BOOL CAcl::TuningAclSize(PACL pAddAcl)
{
  BOOL fRes = FALSE;
  try
  {
    ACL_SIZE_INFORMATION addasi;
    if (GetAclInformation(pAddAcl, &addasi, sizeof(addasi), AclSizeInformation))
    {
      fRes = TuningAclSize(addasi.AclBytesInUse);
    }
  }
  catch(...) { }
  return fRes;
}
//---------------------------------------------------------------------------
BOOL CAcl::RewriteAcl(PACL pSrcAcl)
{
  clear();
  if (TuningAclSize(pSrcAcl)) return (CopyAcl(FPAcl, pSrcAcl));
  else return FALSE;
}
//---------------------------------------------------------------------------
// Возвращает индекс эквивалентного Ace
int CAcl::EqualAceIdx(PSTANDARD_ACE pAce)
{
  return FindAceInAcl(FPAcl, pAce);
}
//---------------------------------------------------------------------------
DWORD CAcl::count()
{
  DWORD dwRes = 0;
  try
  {
    if (FPAcl)
    {
      ACL_SIZE_INFORMATION asi;
      if (GetAclInformation(FPAcl, &asi, sizeof(asi), AclSizeInformation))
        dwRes = asi.AceCount;
    }
  }
  catch(...) {}
  return dwRes;
}

//---------------------------------------------------------------------------
PSTANDARD_ACE CAcl::operator [] (DWORD idx)
{
  PSTANDARD_ACE pRes = NULL;
  try
  {
    PACE_HEADER pAce;
    if (GetAce(FPAcl, idx, (PVOID*) &pAce)) pRes = (PSTANDARD_ACE) pAce;
  }
  catch(...) {}
  return pRes;
}
//---------------------------------------------------------------------------
CAcl& CAcl::operator +=(PSTANDARD_ACE pAce)
{
  if (pAce && TuningAclSize(pAce->aceHeader.AceSize))
  {
    DWORD idx = EqualAceIdx(pAce); //MAXDWORD;  // В конец ACL
    switch (idx)
    {
      case MAXDWORD:
       if (FCanonical) idx = GetCanonicalIndex(FPAcl, pAce);
       AddAce(FPAcl, ACL_REVISION, idx, (PVOID) pAce, pAce->aceHeader.AceSize);
      break;
      default:
        if (FCanonical)
          (*this)[idx]->aceAllowed.Mask = pAce->aceAllowed.Mask;
    }
  }
  return *this;
}
//---------------------------------------------------------------------------
// Добавляет
BOOL CAcl::AddAcl(PACL pSrcAcl)
{
  BOOL fRes = FALSE;
  try
  {
    if (TuningAclSize(pSrcAcl))
    {
      ACL_SIZE_INFORMATION srcasi;
      if (GetAclInformation(pSrcAcl, &srcasi, sizeof(srcasi), AclSizeInformation))
      {
        PACE_HEADER pAce;
        for (DWORD idx = 0; idx < srcasi.AceCount; idx++)
        {
          if (GetAce(pSrcAcl, idx, (PVOID*) &pAce))
          {
            *this += (PSTANDARD_ACE) pAce;
          }
          else return FALSE;
        }
        fRes = TRUE;
      }
    }
  }
  catch(...){}
  return fRes;
}

//---------------------------------------------------------------------------
DWORD CalculateAclSize(PACL pOldAcl, PSID* ppSidArray, DWORD dwNumSids,
                       PSTANDARD_ACE* ppAces, DWORD dwNumAces)
{
  DWORD res = 0;
  BOOL  fOk = TRUE;
  try
  {
    if (pOldAcl)
    {
      ACL_SIZE_INFORMATION asi;
      fOk = GetAclInformation(pOldAcl, &asi, sizeof(asi), AclSizeInformation);
      if (fOk) res = asi.AclBytesInUse;
    }
    if (fOk && ppSidArray)
    {
      while (dwNumSids--)
      {
        fOk = IsValidSid(ppSidArray[dwNumSids]);
        if (fOk)
        {
          res += GetLengthSid(ppSidArray[dwNumSids]);
          res += sizeof(ACCESS_ALLOWED_ACE) - sizeof(((ACCESS_ALLOWED_ACE*) 0)->SidStart);
        }
        else break;
      }
    }
    if (fOk && ppAces)
    {
      while (dwNumAces--)
      {
        res += ppAces[dwNumAces]->aceHeader.AceSize;
      }
    }
  }
  catch(...) { fOk = FALSE;}
  if (fOk) return res;
  else return 0;
}
//---------------------------------------------------------------------------
BOOL IsEqualAce(PSTANDARD_ACE pAce1, PSTANDARD_ACE pAce2)
{
  BOOL fRes = FALSE;
  try
  {
    if (pAce1->aceHeader.AceType != pAce2->aceHeader.AceType) return FALSE;
    PBYTE pbAce1 = (PBYTE) pAce1;
    PBYTE pbAce2 = (PBYTE) pAce2;
    DWORD dwAceStructSize = ACESTRUCTSIZE;
    fRes = TRUE;
    // Жираф большой.... [1] стр.381
    while (dwAceStructSize--)
    fRes = (fRes && (pbAce1[dwAceStructSize] == pbAce2[dwAceStructSize]));
    fRes = fRes && EqualSid((PSID)(pbAce1 + ACESIDOFFSET), (PSID)(pbAce2 + ACESIDOFFSET));
  }
  catch(...)
  {
  }
  return fRes;
}
//---------------------------------------------------------------------------
int FindAceInAcl(PACL pAcl, PSTANDARD_ACE pAce)
{
  int idx = -1;
  try
  {
    ACL_SIZE_INFORMATION asi;
    if (GetAclInformation(pAcl, &asi, sizeof(asi), AclSizeInformation))
    {
      PSTANDARD_ACE pAce2;
      while (asi.AceCount--)
      {
        if (!GetAce(pAcl, asi.AceCount, (PVOID*) &pAce2)) break;
        if (IsEqualAce(pAce, pAce2))
        {
          idx = (int) asi.AceCount;
          break;
        }
      }
    }
  }
  catch(...)
  {
  }
  return (idx);
}
//---------------------------------------------------------------------------
// Возвращает положенный по каноническом стандарту индекс Ace в DACL
DWORD GetCanonicalIndex(PACL pDacl, PSTANDARD_ACE pNewAce)
{
  DWORD idx = - 1;
  try
  {
    BYTE dwOrderFilterType [] =
          {ACCESS_DENIED_ACE_TYPE, ACCESS_DENIED_OBJECT_ACE_TYPE,
          ACCESS_ALLOWED_ACE_TYPE, ACCESS_ALLOWED_OBJECT_ACE_TYPE};
    DWORD dwNewAceGroup = 0;

    for (dwNewAceGroup; dwNewAceGroup < 4; dwNewAceGroup++)
    {
      if (pNewAce->aceHeader.AceType == dwOrderFilterType[dwNewAceGroup])
        break;
    }
    // Если недопустимый тип нового Ace
    if (dwNewAceGroup == 4) return idx;
    // Если унаследованный то идет последним
    if ((pNewAce->aceHeader.AceFlags & INHERITED_ACE) != 0)
       dwNewAceGroup += 4;
    ACL_SIZE_INFORMATION asi;
    if (GetAclInformation(pDacl, &asi, sizeof(asi), AclSizeInformation))
    {
      PACE_HEADER  pAce;
      idx = 0;
      for (idx; idx < asi.AceCount; idx++)
      {
        if (GetAce(pDacl, idx, (PVOID*) &pAce))
        {
          DWORD dwAceGroup = 0;
          for (dwAceGroup; dwAceGroup < 4; dwAceGroup++)
          {
            if (pAce->AceType == dwOrderFilterType[dwAceGroup])
            break;
          }
          if (dwAceGroup == 4)
          {
            idx = - 1;
            return idx; // недопустимый ACE в DACL
          }
          // Если унаследованный то внесем поправку
          if ((pAce->AceFlags & INHERITED_ACE) != 0)
            dwAceGroup += 4;
          if (dwAceGroup >= dwNewAceGroup) break;
        }
      } // for idx
    }
  }
  catch(...) { }
  return idx;
}
//---------------------------------------------------------------------------
// Копирует ACL
BOOL CopyAcl(PACL pDestAcl, PACL pSrcAcl)
{
  BOOL fRes = FALSE;
  try
  {
    ACL_SIZE_INFORMATION asi;
    if (GetAclInformation(pSrcAcl, &asi, sizeof(asi), AclSizeInformation))
    {
      PACE_HEADER  pAce;
      for (DWORD idx = 0; idx < asi.AceCount; idx++)
      {
        if (!GetAce(pSrcAcl, idx, (PVOID*) &pAce)) return FALSE;
        if (!AddAce(pDestAcl, ACL_REVISION, MAXDWORD, (PVOID*) pAce, pAce->AceSize))
        return FALSE;
      }
    }
    fRes = TRUE;
  }
  catch(...) { }
  return (fRes);
}

Ну и в итоге используем:
 FObjHandle - Хэндл защищаемого процесса, открытого OpenProcess( PROCESS_ALL_ACCESS)
 pDacl         - PACL ( см. CAcl.operator PACL)

 SetSecurityInfo( FObjHandle, FObjType,
                       DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
                        NULL, NULL, pDacl, NULL);

Удачи. Попробуй разобраться...

Записан

while (8==8)
Disasm
Гость
« Ответ #8 : 22-06-2006 10:57 » 

Разобрался. Но это система управления дескрипторами, и к тому же я не знаю чем их заполнять. Как создать подходящий SID (если требуется защита всей или некоторой области памяти своего процесса от воздействия других процессов)?
Насколько я понял, что мой список ACL должен состоять из одной ACE (ACCESS_DENIED_ACE). Кроме того я не знаю какое должно быть значение параметра AccessMask для API функции
BOOL AddAccessDeniedAce(
    PACL pAcl,   // pointer to access-control list
    DWORD dwAceRevision,   // ACL revision level
    DWORD AccessMask,   // access mask
    PSID pSid    // pointer to security identifier
   );

Помогите, пожалуйста!
Записан
sss
Специалист

ru
Offline Offline

« Ответ #9 : 23-06-2006 01:46 » new

1)

Защита на основе списков доступа не позволит защищать области. Только объект процесса, и соответственно все его ресурсы, относительно учетных записей.
Вот пример создания
Код:
//---------------------------------------------------------------------------
PSID SECHLPAPI BuildAdministratorsSid()
{
  SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY; //SECURITY_WORLD_SID_AUTHORITY
  PSID pRes = NULL;
  BOOL fRes =  AllocateAndInitializeSid(&auth, 2, 32, 544, 0, 0, 0, 0, 0, 0, &pRes);
  return (fRes ? pRes : NULL);
}
//---------------------------------------------------------------------------
PSID SECHLPAPI BuildUsersSid()
{
  SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY; //SECURITY_WORLD_SID_AUTHORITY
  PSID pRes = NULL;
  BOOL fRes =  AllocateAndInitializeSid(&auth, 2, 32, 545, 0, 0, 0, 0, 0, 0, &pRes);
  return (fRes ? pRes : NULL);
}
//---------------------------------------------------------------------------
PSID SECHLPAPI NameToPSid(TCHAR* Name, PStr pDomain, LPDWORD pSidSize, PSID_NAME_USE peUse)
{
  if (Name && pDomain)
  {
    BOOL          fOk = FALSE;
    SID_NAME_USE  pUse;
    DWORD dwDomainLen = 30;
    DWORD dwSidLen = 0;
    PSID psid = NULL;
    pDomain->SetLength(dwDomainLen, FALSE);
    fOk = LookupAccountName(NULL, Name, psid,&dwSidLen,
                          (TCHAR*) pDomain->Buffer(), &dwDomainLen, &pUse);
    if (!fOk && (dwSidLen > 0 || dwDomainLen > 30))
    {
      psid = LocalAlloc(LPTR, dwSidLen);
      pDomain->SetLength(dwDomainLen, FALSE);
      fOk = LookupAccountName(NULL, Name, psid, &dwSidLen,
                          (TCHAR*) pDomain->Buffer(), &dwDomainLen, &pUse);
      if (!fOk && psid)
      {
        LocalFree(psid);
        psid = NULL;
      }
    }
    if (fOk)
    {
      if (peUse) *peUse = pUse;
      if (pSidSize) *pSidSize = dwSidLen;
    }
    return psid;
  }
  else
  {
    SetLastError(ERROR_INVALID_PARAMETER);
    return NULL;
  }
}

2) Думаю, что одной запрещающей ACE ты не обойдешся. Лучше прочитать список дескриптора процесса и добавить запрещающий ACE вверх. И интересно, какую информацию об памяти будет показывать TaskManager.

3) Для запрещения операций XxxProcessMemory.
Sid = Everyony (А лучше, того кто запустил...)
AccessMask = PROCESS_VM_OPERATION

4) Предполагаю, есть еще подводный камень. Владелец объектом. Если владельцем объекта будет пользователь, запустивший процесс (что скорее всего), доступ к объекту осуществляется в обход проверок списка доступа. Т.е. необходимо будет поменять владельца. Для смены владельца необходима привилегия SeTakeOwnership, которая неотемлимо (!) присутствует для учетной записи Администратор. Хоть тресни. Отсюда следует, что сопротивление программе, запущенной под этой учетной записью, и умеющей работать с дескриптором безопасности невозможно. Но, неотемлимость привилегии не распространяется (блин не помню точно ли! посмотрю допишу) на учетные записи, входящую в группу Администраторы. Дальше делай выводы.

Вот код, как сменить владельца в дескрипторе объекта. Вначале добавляем себе право менять владельца, меняем, возвращаем как было.

Код:
SECURITY_INFORMATION si = OWNER_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION
                            | PROTECTED_SACL_SECURITY_INFORMATION;
  BOOL   fRes = FALSE;
  DWORD  dwOldState_Restore = MAXDWORD;
  DWORD  dwOldState_TakeOwner = MAXDWORD;

  try
  {
    SetProcessPrivilege(NULL, SE_RESTORE_NAME, TRUE, &dwOldState_Restore);
    SetProcessPrivilege(NULL, SE_TAKE_OWNERSHIP_NAME, TRUE, &dwOldState_TakeOwner);

    switch (FNameUse)
    {
      case FALSE:
        FError = SetSecurityInfo(FObjHandle, FObjType, si,
                                      pOwnerSid, pOwnerSid, NULL, NULL);
      break;
      case TRUE:
        FError = SetNamedSecurityInfo(FObjName, FObjType, si,
                                      pOwnerSid, pOwnerSid, NULL, NULL);
      break;
    }

   if (dwOldState_Restore == 0) SetProcessPrivilege(NULL, SE_RESTORE_NAME, FALSE);
   if (dwOldState_TakeOwner == 0) SetProcessPrivilege(NULL, SE_TAKE_OWNERSHIP_NAME, FALSE);

   if (FError != ERROR_SUCCESS) SetLastError(FError);
   else
   {
     fRes = TRUE;
     GetDescriptor();
   }
  }
  catch(...) { }
  return fRes;
Код:
//---------------------------------------------------------------------------
// Разрешает/запрещает привилегию процесса
BOOL SetProcessPrivilege(HANDLE hProcess, TCHAR* PrivilegeName, BOOL fEnable, LPDWORD pPrevAttributes)
{
  BOOL             fRes = FALSE;
  HANDLE           hProc = NULL;
  HANDLE           hToken = NULL;
  TOKEN_PRIVILEGES priv;
  LUID             luid;
  if (hProcess) hProc = hProcess;
  else  hProc = OpenProcess(PROCESS_TOKEN_RIGHTS, FALSE, GetCurrentProcessId());
  if (hProc && OpenProcessToken(hProc, TOKEN_ALL_ACCESS, &hToken))
  {
    priv.PrivilegeCount = 1;
    if (LookupPrivilegeValue(NULL, PrivilegeName, &luid))
    {
      DWORD dwLength = sizeof(priv);
      priv.Privileges[0].Luid = luid;
      priv.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
      fRes= AdjustTokenPrivileges(hToken, FALSE, &priv, dwLength, &priv, &dwLength);
      if (pPrevAttributes) *pPrevAttributes = priv.Privileges[0].Attributes;
    }
    CloseHandle(hToken);
  }
  if (hProcess == NULL) if (hProc) CloseHandle(hProc);
  return fRes;
}

P.S.: Если мне кто-нибудь задаст вопрос об разрешениях для объектов Active Directory я застрелюсь.
Записан

while (8==8)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines