| 
							Disasm
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 «  : 14-06-2006 03:25 »   | 
								
								 | 
							  
							 
							Как защитить память своего приложения от всяких гадостей типа ArtMoney? Или чтобы другие процессы получали ошибку при попытке ReadProcessMomory/WriteProcessMomory. Код защиты должен быть мой и распологаться или в самом защащаемом приложении или в приложении, которое запускает защищаемое.
  ProcessGuard не предлагать :)
  Спасибо. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алексей++
							
								глобальный и пушистый 
								Глобальный модератор
								
								 
								  Offline
								
								Сообщений: 13
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #1 : 14-06-2006 08:05 »   | 
								
								 | 
							  
							 
							Disasm, очень просто   блок защищаемых данных выделяешь через new и периодически выделяешь новое место, копируешь туда и удаляешь старые. Полезно несколько копий данных - и постоянно их синхронизировать  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Disasm
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #2 : 14-06-2006 09:04 »   | 
								
								 | 
							  
							 
							Дело в том, что приложение (пусть это приложение A) не мое, изменять его структуру я не могу, я мой код является потоком в этом приложении. Как поставить на код и данные приложения такие права, чтобы никакое другое приложение на могло изменять память приложения A. Исходников приложения A у меня нет. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							sss
							
								Специалист 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #3 : 19-06-2006 07:19 »   | 
								
								 | 
							  
							 
							И при этом "другое приложение" выполнялось под именем администратора? Гм... Много миллиардов наносекунд назад я использовал VirtualProtectEx, и ArtMoney показывал что память моего приложения = 0 МБ. Это не совсем просто - но то что нужно... 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							 while (8==8)  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Disasm
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #4 : 19-06-2006 10:05 »   | 
								
								 | 
							  
							 
							И при этом "другое приложение" выполнялось под именем администратора? Гм... Много миллиардов наносекунд назад я использовал VirtualProtectEx, и ArtMoney показывал что память моего приложения = 0 МБ. Это не совсем просто - но то что нужно...
  Можете рассказать как вы это делали: на какие регионы ставить защиту? Какие флаги защиты?  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							sss
							
								Специалист 
								
								 
								  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
							
								Специалист 
								
								 
								  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
							
								Специалист 
								
								 
								  Offline
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #9 : 23-06-2006 01:46 »   | 
								
								 | 
							  
							 
							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)  
						 | 
					 
				 
			 |  
		 
	 | 
	 |