首页
社区
课程
招聘
[求助]win7的非管理员用户如何打开驱动设备?
发表于: 2013-10-8 15:21 15074

[求助]win7的非管理员用户如何打开驱动设备?

2013-10-8 15:21
15074
普通应用程序使用如下语句,
createfiel(驱动设备名,参数...),然后
deviceiocontrol(驱动设备,参数...)
象这样,r3层和r0层交互是很通常的做法。
可是win7下面,creatfile(驱动设备,...)一定要administrator才能成功,
那么普通用户就不能运行大量的含有和驱动层通信的应用程序了吗?
qq在r3层和qqprotect.sys的r0层如何通信的?
我想不可能把,难道非要administrator才能打开驱动层设备,那么多普通用户,
如何使用驱动层设备啊,我的驱动程序都已经编好了,r3层不能调用,
win7的uac是怎么搞的,这么简单的r3和驱动层deviceiocontrol都不能用吗?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (10)
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
createfile是否成功,主要开device的acl如何设置,以及irp_mj_create如何处理请求。

如果acl设置的是允许everyone或允许user的,而且create dispatch也没拦截(比如QQ的驱动可能在这里检查是不是自己的驱动通讯),一般就可以打开
2013-10-8 16:35
0
雪    币: 8
活跃值: (233)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
3
是啊,对于"createfile是否成功",我业不知道如何设置才能使createfile一定成功,我测试的情况是,如果是administrator,那么createfile打开我自己的驱动设备名,createfile(mhdevice,...)
是成功了,如果不是administrator,那么createfile(mhdevice,...)就不成功。如果不是administrator,但是以administrator方式运行,就会弹出窗口,要求确认是否以administrator管理员身份运行,并要求输入密码,然后createfile(mhdevice,...)就会成功。我就想,能够不弹出UAC窗口,也能createfile(mhdevice,...)成功,那样就好了。不知道这种想法能否实现。看样子要createfile(mhdevice,...)成功,必须要指定administrator管理员身份啊,普通用户为什么不行?而且我就要问win7系统了,为什么剥夺了普通用户打开“驱动设备”并且进行“deviciocontrol”的权利。我想需要进行“deviciocontrol”的软件应该很多很多吧,这样以来让这么多的软件,在win7普通用户权限下都不能运行了吗?非要administrator权限运行吗?而xp就没有这个限制。所以win7的UAC很讨厌。
2013-10-8 16:55
0
雪    币: 8
活跃值: (233)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
4
creatfile的调用就和是否系统管理员权限这个有关。creatfile(mydevice,其他参数...)
执行这个creatfile,如果是administrator,就返回成功,如果不是管理员,就返回失败。
createfile("普通文件",...),如果是创建普通磁盘上的文件,那么不管是系统管理员,还是普通用户,都返回成功,如果创建的是我自己的驱动设备,就只有administrator才能创建成功啊。
这样就剥夺了普通用户使用任何“驱动设备”的能力,普通用户只能打开普通的磁盘文件,不能打开驱动设备啊。
另外,有一个疑问,就是如果要弹出UAC窗口,提示是否以系统管理员运行,是必需在程序开始的时候弹出的,通过设置编译开关也好,或者通过右键菜单“以管理员身份运行”也好,这都是在程序还没开始前就提问UAC,并输入管理员密码,再运行程序。
我就想,能否是这样,我的程序以普通方式运行,运行到一半的时候,我在程序里面调用某个函数,弹出UAC窗口,提示输入管理员密码,获得管理员权限,然后在运行createfile(mydeive,....)。就是不知道有这个函数没有?是运行一半的时候,把本身这个进程改为管理员权限,而不是运行一半的时候,新开一个进程,使新开的进程具有管理员权限。
2013-10-8 17:27
0
雪    币: 8
活跃值: (233)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
5
createfile是否成功,主要开device的acl如何设置,如果acl设置的是允许everyone或允许user的,
device的acl是哪个标志?是哪个字节?
2013-10-8 17:37
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
如果你的device没做任何特殊设置,直接用IoCreateDevice创建的(不是用IoCreateDeviceSecure),那么默认是所有用户都可以打开的
2013-10-8 19:52
0
雪    币: 8
活跃值: (233)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
7
问题是我就是这样直接用IoCreateDevice创建的device,可是administrator能打开,其他用户都不能打开啊。请注意,你说的是不是xp的情况都可以打开?我说的是win7,有UAC,除了administator,其他用户都不能打开,这个UAC很讨厌。
2013-10-8 20:09
0
雪    币: 8
活跃值: (233)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
8
难道要按这篇文章所说,生成全用户可读写的驱动设备。
// 全用户可读写权限

UNICODE_STRING sddl =

RLT_CONSTANT_STRING(L"D:P(A;;GA;;;WD)");

3)设备的生成安全性限制

NTSTATUS

IoCreateDevice(

IN PDRIVER_OBJECT DriverObject,

IN ULONG DeviceExtensionSize,

IN PUNICODE_STRING DeviceName OPTIONAL,

IN DEVICE_TYPE DeviceType,

IN ULONG DeviceCharacteristics,

IN BOOLEAN Exclusive,

OUT PDEVICE_OBJECT *DeviceObject

);

第一个参数是生成这个设备的驱动对象。

第二个参数DeviceExtensionSize非常重要;由于分发函数中得到的总是设备的指针,当用户需要在每个设备上记录一些额外的信息(比如用于判断这个设备是哪个设备的信息、以及不同的实际设备所需要记录的实际信息,比如网卡上数据包的流量、过滤器所绑定真实设备指针等等),需要指定的设备扩展区内存的大小。如果DeviceExtensionSize设置为非0,IoCreateDevice会分配这个大小的内存在 DeviceObject->DeviceExtension中。以后用户就可以从根据DeviceObject-> DeviceExtension来获得这些预先保存的信息。

DeviceName如前例,是设备的名字。目前生成设备,请总是生成在\Device\目录下。所以前面写的名字是“\Device\MyCDO”。

最后生成的设备对象指针返回到DeviceObject中。

这种设备生成之后,必须有系统权限的用户才能打开(比如管理员)。为了保证交互的成功与安全性,应该用服务程序与之交互,但是有时候必须用普通用户打开设备。必须用IoCreateDeviceSecure。

NTSTATUS

IoCreateDeviceSecure(

IN PDRIVER_OBJECT DriverObject,

IN ULONG DeviceExtensionSize,

IN PUNICODE_STRING DeviceName OPTIONAL,

IN DEVICE_TYPE DeviceType,

IN ULONG DeviceCharacteristics,

IN BOOLEAN Exclusive,

IN PCUNICODE_STRING DefaultSDDLString,

IN LPCGUID DeviceClassGuid,

OUT PDEVICE_OBJECT *DeviceObject)

这个函数增加了两个参数(其他的没变)。一个是DefaultSDDLString,这是一个用于描述权限的字符串。字符串“D:P(A;;GA;;;WD)”将满足“人人皆可以打开”的需求。

http://msdn.microsoft.com/en-us/library/ff563667%28VS.85%29.aspx

http://msdn.microsoft.com/en-us/library/ff548407%28VS.85%29.aspx

另一个参数是一个设备的GUID,随机手写一个GUID。不要和其他设备的GUID冲突。

// 随机手写一个GUID

const GUID DECLSPEC_SELECTANY MYGUID_CLASS_MYCDO =

{0x26e0d1e0L, 0x8189, 0x12e0, {0x99,0x14, 0x08, 0x00, 0x22, 0x30, 0x19, 0x03}};

// 全用户可读写权限

UNICODE_STRING sddl =

RLT_CONSTANT_STRING(L"D:P(A;;GA;;;WD)");

// 生成设备

status = IoCreateDeviceSecure( DriverObject,

0,

&device_name,

FILE_DEVICE_UNKNOWN,

FILE_DEVICE_SECURE_OPEN,

FALSE,

&sddl,

(LPCGUID)&SFGUID_CLASS_MYCDO,

&device);

使用这个函数的时候,必须连接库wdmsec.lib。
2013-10-8 20:18
0
雪    币: 158
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
这样可以吗? lz搞定了没有?
2013-10-12 08:40
0
雪    币: 8
活跃值: (233)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
10
这样测试了一下,IoCreateDeviceSecure需要kernel32.dll,也就是启动初期,无法用IoCreateDeviceSecure生成设备,kernel32.dll是什么时候调入内存的啊?我的驱动生成的时候,
内存应该只有ntoskrnl.exe和hal.dll吧,所以只能用IoCreateDevice生成设备。我用IoCreateDeviceSecure生成设备结果启动的时候蓝屏了,肯定啊,因为当时kernel32.dll还没调入内存呢。
所以我的实践操作是失败了。
但是我想到另一个变通的办法,就是我在初期是用IoCreateDevice生成设备A,这个我早已经调试成功了,
然后再后期再用IoCreateDeviceSecure生成另一个设备B,B的功能就是在r0层向A发送ioctrl,而B应该可以
用普通用户使用createfile打开吧。后面这种思路只是一个想法,没有去实践。
2013-10-12 19:18
0
雪    币: 8
活跃值: (233)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
11
已经经过实践测试了,成功!
开始的错误,因为编译的时候链接库显示wdmsec.lib有个getcurrentprocess未链接,不知道
怎么莫名其妙出现了getcurrentprocess 未连接,我一查,getcurrentprocess属于kernel32.dll,就把kernle32.lib库文件添加进去,居然连接成功了,生成的mrdriver.sys。
而我这个mydriver.sys无论如何都不能加载,我放进IDA一看,我的mydriver.sys需要导入函数
用到kernel32.dll和ntosknrl.exe,而kernel32.dll是r3的,ntoskrnl.exe 是r0的,不可能同时工作,所以这个mydriver.sys是无效的,但奇怪的是编译器怎么会生成成功了mydriver.sys。

后来一查,要使用IoCreateDeviceSecure,需要连接wdmsec.lib库,而要连接wdmsec.lib库,
还需另外连接BufferOverflowK.lib库,我把这两个库都连接了,可是显示为找到函数
_DriverEntry@8,这个就是我的驱动入口函数,为何未找到呢?后来觉得可能编译器翻译的函数名字不对,_DriverEntry@8可能被翻译成了??DriverEntry@@sdf@@.....一大堆,可能是C++编译函数名称的问题。后来编译生成.asm文件,查看.asm文件里面果然是??DriverEntry@@sdf@@.....这个名称,然后把??DriverEntry@@sdf@@.....这个名称改为_DriverEntry@8,然后用宏汇编编译ml编译obj,再手工link连接,最后终于生成了正确的mydriver.sys。
把生成的mydriver.sys替换以前需要kernel32.dll的错误的sys,这个正确的mydriver.sys可以加载成功了,并生成了驱动设备对象,应用层普通用户createfile(驱动设备,...)成功!
证明此方法可行。
2013-10-12 22:47
0
游客
登录 | 注册 方可回帖
返回
//