SCSI Miniport와 같은 프레임 워크를 이용하여 개발을 할 때 내부 프레임 워크에서 자동으로 DEVICE_OBJECT를 생성하게 됩니다.
이 때 생성되는 DEVICE_OBJECT에 보안 디스크립터 설정이 기본적으로 높게 잡혀져 있습니다.
따라서 어플리케이션에서 생성 된 DEVICE_OBJECT와 통신할 때 비스타 이상에서는 관리자 권한으로 실행하여,
해당 DEVICE_OBJECT와 통신을 해야 하는데, 이미 만들어진 DEVICE_OBJECT에 대한 보안 디스크립터 권한을
최소로 할당하여, 관리자 권한없이 접근할 수 있게 만들어주는 함수입니다.
BOOLEAN SetUnprotectedSecurityDescriptor(PDEVICE_OBJECT pDeviceObject)
{
HANDLE FileHandle;
SECURITY_DESCRIPTOR SecurityDescriptor;
NTSTATUS ntStatus;
//
// 보호되지 않은 보안 디스크립터를 만드는 방법은 IoCreateUnprotectedSymbolicLink Windows 2000 소스코드를 참고하였습니다.
//
memset(&SecurityDescriptor, 0, sizeof(SECURITY_DESCRIPTOR));
ntStatus = RtlCreateSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION1);
if (NT_SUCCESS(ntStatus) == FALSE)
{
return FALSE;
}
ntStatus = RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
TRUE,
NULL,
TRUE); //does not over-ride inheritable protection
if (NT_SUCCESS(ntStatus) == FALSE)
{
return FALSE;
}
FileHandle = NULL;
ntStatus = ObOpenObjectByPointer(pDeviceObject,
OBJ_KERNEL_HANDLE,
NULL,
WRITE_DAC,
0,
KernelMode,
&FileHandle);
if (NT_SUCCESS(ntStatus) == FALSE)
{
return FALSE;
}
if (FileHandle == NULL)
{
return FALSE;
}
ntStatus = ZwSetSecurityObject(FileHandle, DACL_SECURITY_INFORMATION, &SecurityDescriptor);
ZwClose(FileHandle);
return NT_SUCCESS(ntStatus);
}