能力值:
( LV2,RANK:10 )
|
-
-
2 楼
createfile是否成功,主要开device的acl如何设置,以及irp_mj_create如何处理请求。
如果acl设置的是允许everyone或允许user的,而且create dispatch也没拦截(比如QQ的驱动可能在这里检查是不是自己的驱动通讯),一般就可以打开
|
能力值:
(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很讨厌。
|
能力值:
(RANK:10 )
|
-
-
4 楼
creatfile的调用就和是否系统管理员权限这个有关。creatfile(mydevice,其他参数...)
执行这个creatfile,如果是administrator,就返回成功,如果不是管理员,就返回失败。
createfile("普通文件",...),如果是创建普通磁盘上的文件,那么不管是系统管理员,还是普通用户,都返回成功,如果创建的是我自己的驱动设备,就只有administrator才能创建成功啊。
这样就剥夺了普通用户使用任何“驱动设备”的能力,普通用户只能打开普通的磁盘文件,不能打开驱动设备啊。
另外,有一个疑问,就是如果要弹出UAC窗口,提示是否以系统管理员运行,是必需在程序开始的时候弹出的,通过设置编译开关也好,或者通过右键菜单“以管理员身份运行”也好,这都是在程序还没开始前就提问UAC,并输入管理员密码,再运行程序。
我就想,能否是这样,我的程序以普通方式运行,运行到一半的时候,我在程序里面调用某个函数,弹出UAC窗口,提示输入管理员密码,获得管理员权限,然后在运行createfile(mydeive,....)。就是不知道有这个函数没有?是运行一半的时候,把本身这个进程改为管理员权限,而不是运行一半的时候,新开一个进程,使新开的进程具有管理员权限。
|
能力值:
(RANK:10 )
|
-
-
5 楼
createfile是否成功,主要开device的acl如何设置,如果acl设置的是允许everyone或允许user的,
device的acl是哪个标志?是哪个字节?
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
如果你的device没做任何特殊设置,直接用IoCreateDevice创建的(不是用IoCreateDeviceSecure),那么默认是所有用户都可以打开的
|
能力值:
(RANK:10 )
|
-
-
7 楼
问题是我就是这样直接用IoCreateDevice创建的device,可是administrator能打开,其他用户都不能打开啊。请注意,你说的是不是xp的情况都可以打开?我说的是win7,有UAC,除了administator,其他用户都不能打开,这个UAC很讨厌。
|
能力值:
(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。
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
这样可以吗? lz搞定了没有?
|
能力值:
(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打开吧。后面这种思路只是一个想法,没有去实践。
|
能力值:
(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(驱动设备,...)成功!
证明此方法可行。
|