CreateFile打开驱动设备权限不足
2021-07-01
284
0
记得以前写了一个文件过滤驱动,使用的是minifilter的框架。
在创建设备时,很常规的使用IoCreateDevice来创建一个命名的设备对象,然后对这个设备名使用IoCreateSymbolicLink创建其应用层的链接符号名,这样我们在应用层就可以通过CreateFile函数就可以打开这个设备,然后通过WriteFile,ReadFile和DeviceIoControl来进行应用层与设备对象的数据通讯了。
我是在虚拟机下开发的,所以虚拟机使用的是管理员模式,所以一切都很OK.
不过在正式环境中,做上层的同事告诉我说,设备打不开,GetLastError()=5即权限不够。
当然,如果使用右键管理员的方式运行应用程序,是可以的~~
原因,从GetLastError()的返回值已经知道结果了,该怎么解决问题了?
我以前做普通设备驱动的时候,也没有遇到这个问题啊~
最后,经过调试,发现在创建设备设置相关的权限,这样就可以了。大致流程如下:
- 使用ObOpenObjectByPointer函数获取设备的句柄,当然这个模式得是内核模式。
- 使用ExAllocatePool函数分配一个安全描述符结构体SECURITY_DESCRIPTOR的内存。
- 使用RtlCreateSecurityDescriptor函数初始化安全描述符结构体内存。
- 使用NtSetSecurityObject函数对我们1中获取的结构体对象设置2和3创建的安全描述符对象。
相关代码如下:
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
HANDLE hDevice = NULL;
do
{
status = ObOpenObjectByPointer(DeviceObject,
0,
NULL,
FILE_ALL_ACCESS,
NULL, KernelMode,
&hDevice);
if (!NT_SUCCESS(status))
{
KdPrint(("ObOpenObjectByPointer err 0x%08x\n", status));
break;
}
//ObDereferenceObject(DeviceObject); 打开这句蓝屏
SecurityDescriptor = (PSECURITY_DESCRIPTOR)ExAllocatePool(NonPagedPool, sizeof(SECURITY_DESCRIPTOR));
status = RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(status))
{
DPrint1(("RtlCreateSecurityDescriptor err 0x%08x\n", status));
break;
}
status = NtSetSecurityObject(CtlDevHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor);
if (!NT_SUCCESS(status))
{
DPrint1(("RtlCreateSecurityDescriptor err 0x%08x\n", status));
break;
}
} while (0);
if (hDevice != NULL)
{
ZwClose(hDevice);
hDevice = NULL;
}
if (SecurityDescriptor != NULL)
{
ExFreePool(SecurityDescriptor);
SecurityDescriptor = NULL;
}
设备安全描述符
每个设备对象都有一个安全描述符,安全描述符包括一个DACL,每个DACL中包含各个用户对象对本设备的权限信息,大体见下图:
一个DACL(Discretionary Access Control List),其指出了允许和拒绝某用户或用户组的存取控制列表。 当一个进程需要访问安全对象,系统就会检查DACL来决定进程的访问权。如果一个对象没有DACL,那么就是说这个对象是任何人都可以拥有完全的访问权限。