设为首页 收藏本站
查看: 1492|回复: 0

12、Windows驱动开发技术详解笔记(8) 基本语法回顾

[复制链接]

尚未签到

发表于 2015-5-23 12:55:03 | 显示全部楼层 |阅读模式
8、加裁驱动,驱动与设备
1)前面我们主要通过Driver Studio和KmdManager。现在了解一下程序加裁。
Windows NT式驱动是基于服务方式加载的,可以通过修改注册表内容完成,也可以通过服务相关API完成。设备驱动程序的动态加载主要由服务控制管理程序(Service Control Manager, SCM)系统组件完成,该组件可以启动、停止和控制服务等。
具体加裁方法,参见 [1,3]。在这种情况下加载驱动需要调用OpenSCManager->CreateService->StartService,此时驱动会在服务管理器中注册自己,但这往往显得麻烦,我们还有一个不需要通过服务而直接加载驱动的方法,即使用ZwLoadDriver(这个函数通常是ring0中加载驱动时用,由于它被ntdll.dll导出,因此在ring3也可以用)进行直接加载。
及 http://hi.baidu.com/xlsdg/blog/item/93632681bf1ed4dabc3e1e97.html
2)设备与符号链接
驱动程序和系统其他组件之间的交互是通过给设备发送或者接受发给设备的请求来交互的。换句话说,一个没有任何设备的驱动是不能按规范方式和系统交互的。当然也不会收到任何IRP,分发函数也失去了意义。
但并不意味着这样的驱动程序不存在。如果一个驱动程序只是想写写日志文件、Hook某些内核函数或者是做一些其他的小动作,也可以不生成任何设备,也不需要关心分发函数的设置。
如果驱动程序要和应用程序之间通信,则应该生成设备。此外还必须为设备生成应用程序可以访问的符号链接。下面的驱动程序生成了一个设备,并设置了分发函数:


DSC0000.gif DSC0001.gif 代码



1 #include
2
3 NTSTATUS DriverEntry(
4
5 PDRIVER_OBJECT driver,
6
7 PUNICODE_STRING reg_path)
8
9 {
10
11 NTSTATUS status;
12
13 PDEVICE_OBJECT device;
14
15  // 设备名
16  
17 UNICODE_STRING device_name =
18
19 RTL_CONSTANT_STRING("\\Device\\MyCDO");
20
21 // 符号链接名
22
23 UNICODE_STRING symb_link =
24
25 RTL_CONSTANT_STRING("\\DosDevices\\MyCDOSL");
26
27 // 生成设备对象
28
29 status = IoCreateDevice(
30
31 driver,
32
33 0,
34
35 device_name,
36
37 FILE_DEVICE_UNKNOWN,
38
39 0,
40
41 FALSE,
42
43 &device);
44
45 // 如果不成功,就返回。
46
47 if(!NT_SUCCESS(status))
48
49 return status;
50
51 // 生成符号链接
52
53 status = IoCreateSymbolicLink(
54
55 &symb_link,
56
57 &device_name);
58
59 if(!NT_SUCCESS(status))
60
61 {
62
63 IoDeleteDevice(device);
64
65 return status;
66
67 }
68
69 // 设备生成之后,打开初始化完成标记
70
71 device->Flags &= ~DO_DEVICE_INITIALIZING;
72
73 return status;
74
75 }
  

这个驱动成功加载之后,生成名为“\Device\MyCDO”的设备。给这个设备生成了一个符号链接名字“\DosDevices\MyCDOSL”。应用层可以通过打开这个符号链接来打开设备,可以调用CreateFile就像打开文件一样打开。只是路径应该是“"\\.\ MyCDOSL”。“\\.\”意味后面是一个符号链接名(用户态下),而不是普通文件。请注意,由于C语言中斜杠要双写,所以正确的写法应该是“ \\\\.\\”。
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。
4)符号链接的用户相关性
简单的符号链接(还有一种使用GUID的符号链接)总是命名在\DosDevices\之下。但是实际上这会有一些问题。
比较高级的Windows系统(哪个版本的操作系统很难讲,可能必须判定补丁号),符号链接也带有用户相关性。如果一个普通用户创建了符号链接 “\DosDevices\MyCDOSL”,那么,其实其他的用户是看不见这个符号链接的(除在DriverEntry中外,因为 DriverEntry总是在进程“System”中执行)。当前用户总是取决于当前启动当前进程的用户。
解决方案是:任何用户都可以生成全局符号链接,让所有其他用户都能看见。路径“\DosDevices\MyCDOSL”改为“\DosDevices\Global\MyCDOSL”即可。
但是在不支持符号链接用户相关性的系统上,生成“\DosDevices\Global\MyCDOSL”这样的符号链接是一种错误。为此必须先判断一下。


代码



1 UNICODE_STRING device_name;
2
3 UNICODE_STRING symbl_name;
4
5 if (IoIsWdmVersionAvailable(1, 0x10))
6
7 {
8
9 // 如果是支持符号链接用户相关性的版本的系统,用\DosDevices\Global.
10
11 RtlInitUnicodeString(&symbl_name, L"\\DosDevices\\Global\\SymbolicLinkName");
12
13 }
14
15 else
16
17 {
18
19 // 如果是不支持的,则用\DosDevices
20
21 RtlInitUnicodeString(&symbl, L"\\DosDevices\\SymbolicLinkName");
22
23 }
24
25 // 生成符号链接
26
27 IoCreateSymbolicLink(&symbl_name, &device_name);
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-69840-1-1.html 上篇帖子: 体验Windows 8 的Snap View (辅屏视图) 下篇帖子: Windows 8本地化多语言支持
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表