2009-12-15 2 views
6

프로세스 DACL을 변경하고 .NET 3.5에서 관리되는 코드 클래스를 사용하려고하는 기존 C++ 코드가 있습니다. 웹에서 누군가가 서비스의 NativeObjectSecurity 클래스를 확장하는 SetAclOnServices 클래스를 만든 코드를 발견했습니다. 나는 이것을 구현할 수 있고 ResourceType.Service를 ResourceType.KernelObject로 변경한다고 생각했지만 GetAccessControl을 호출하면 File Not Found 오류로 실패합니다.C#에서 프로세스 DACL을 수정하는 방법이 있습니까

답변

10

메리 크리스마스.

public class ProcessSecurity : NativeObjectSecurity 
{ 
    public ProcessSecurity(SafeHandle processHandle) 
     : base(false, ResourceType.KernelObject, processHandle, AccessControlSections.Access) 
    { 

    } 

    public void AddAccessRule(ProcessAccessRule rule) 
    { 
     base.AddAccessRule(rule); 
    } 

    // this is not a full impl- it only supports writing DACL changes 
    public void SaveChanges(SafeHandle processHandle) 
    { 
     Persist(processHandle, AccessControlSections.Access); 
    } 

    public override Type AccessRightType 
    { 
     get { return typeof(ProcessAccessRights); } 
    } 

    public override AccessRule AccessRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) 
    { 
     return new ProcessAccessRule(identityReference, (ProcessAccessRights)accessMask, isInherited, inheritanceFlags, propagationFlags, type); 
    } 

    public override Type AccessRuleType 
    { 
     get { return typeof(ProcessAccessRule); } 
    } 

    public override AuditRule AuditRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) 
    { 
     throw new NotImplementedException(); 
    } 

    public override Type AuditRuleType 
    { 
     get { throw new NotImplementedException(); } 
    } 
} 

public class ProcessAccessRule : AccessRule 
{ 
    public ProcessAccessRule(IdentityReference identityReference, ProcessAccessRights accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) 
     : base(identityReference, (int)accessMask, isInherited, inheritanceFlags, propagationFlags, type) 
    { 
    } 

    public ProcessAccessRights ProcessAccessRights { get { return (ProcessAccessRights)AccessMask; } } 
} 

[Flags] 
public enum ProcessAccessRights 
{ 
    STANDARD_RIGHTS_REQUIRED = (0x000F0000), 
    DELETE = (0x00010000), // Required to delete the object. 
    READ_CONTROL = (0x00020000), // Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right. 
    WRITE_DAC = (0x00040000), // Required to modify the DACL in the security descriptor for the object. 
    WRITE_OWNER = (0x00080000), // Required to change the owner in the security descriptor for the object. 

    PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF, //All possible access rights for a process object. 
    PROCESS_CREATE_PROCESS = (0x0080), // Required to create a process. 
    PROCESS_CREATE_THREAD = (0x0002), // Required to create a thread. 
    PROCESS_DUP_HANDLE = (0x0040), // Required to duplicate a handle using DuplicateHandle. 
    PROCESS_QUERY_INFORMATION = (0x0400), // Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob). 
    PROCESS_QUERY_LIMITED_INFORMATION = (0x1000), 
    PROCESS_SET_INFORMATION = (0x0200), // Required to set certain information about a process, such as its priority class (see SetPriorityClass). 
    PROCESS_SET_QUOTA = (0x0100), // Required to set memory limits using SetProcessWorkingSetSize. 
    PROCESS_SUSPEND_RESUME = (0x0800), // Required to suspend or resume a process. 
    PROCESS_TERMINATE = (0x0001), // Required to terminate a process using TerminateProcess. 
    PROCESS_VM_OPERATION = (0x0008), // Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory). 
    PROCESS_VM_READ = (0x0010), // Required to read memory in a process using ReadProcessMemory. 
    PROCESS_VM_WRITE = (0x0020), // Required to write to memory in a process using WriteProcessMemory. 
    SYNCHRONIZE = (0x00100000), // Required to wait for the process to terminate using the wait functions. 
} 
+0

감사합니다. 이것을 구현하여 SafeHandle 클래스를 추가하고 프로세스 보안 설명자를 수정할 수는 있지만 원하는 작업을 수행하지 않는 것처럼 보입니다. 프로그램 종료를 거부하려고합니다. 거부 규칙을 추가하기 전후에 보안 설명자가 표시되고 정상적으로 작동하는 것처럼 보입니다. 그러나 프로그램을 종료 할 수는 있습니다. 프로세스 보안 설명 자에 대한 액세스 제어를 설정해야합니까? –

+0

프로세스 ACL에 대한 자동 권한 확장과 관련하여 문서화되지 않은 특별한 경우가있을 수 있습니다. ACE * 거부는 항상 허용보다 우선해야합니다. 어쩌면 소유자가 변경되어 효과가 있는지 확인해보십시오. – nitzmahone

+0

죄송합니다. 보호 된 Persist 메서드에 대한 호출을 추가하여 실제로 프로세스에 ACL을 작성해야합니다. NativeObjectSecurity를 ​​자세히 살펴 보지 않았습니다. Persist에 프로세스 핸들을 전달하는 "SaveChanges"메서드를 추가하고 그 트릭을 수행했습니다. – nitzmahone

관련 문제