windows 网络驱动开发_记《Windows驱动开发技术详解》的一处坑

b659fa4ea552527bbce9a538621259b2.png

相对而言,市面上驱动开发的书确实不多,虽然这本书还是以Windows XP进行讲解,但它放到现在仍然是学习驱动开发的不错的选择。

我碰到的问题是,第四第五章的内容,即使是用示例代码编译驱动,在安装,启动时都是正常的,但是卸载驱动,驱动执行Unload例程时,里面的IoDeleteSymbolicLink(&pDevExt->ustrSymLinkName) 时,猛然发现:预先保存在DEVICE_EXTENSION中的符号链接指向的内存已经无效了,SymbolicLink字符串不翼而飞!?

f893e8a142d36b87c47525398201c483.png
WinDbg查看DEVICE_EXTENSION结构体

具体情况

按照示例代码,有一个头文件里面有如下定义

#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")

typedef struct _DEVICE_EXTENSION {
	PDEVICE_OBJECT pDevice;
	UNICODE_STRING ustrDeviceName;	//设备名称
	UNICODE_STRING ustrSymLinkName;	//符号链接名
} DEVICE_EXTENSION, * PDEVICE_EXTENSION;

而示例代码里面:

#pragma INITCODE
NTSTATUS CreateDevice(IN PDRIVER_OBJECT	pDriverObject)
{ ... }

一开始我以为只是函数编译后的代码放在INIT段,我的字符串还是安全的。直到最后打开IDA看才发现:

d4cb253d28e5ec362a87f48c261ce1ba.png
SymbolicLink字符串(PUNICODE_STRING)的Buffer成员也放在了了INIT段

当然,按照示例代码,DriverEntryCreateDevice函数代码自然都在INIT段里面。

解决方案

#pragma INITCODE去掉或者改为pragma PAGEDCODE

总结

  • code_seg("INIT")下的函数和其中的字符串在驱动加载时装入内存 ,会在之后移出内存。
  • DEVICE_EXTENSION用来放device对象的额外数据倒是安全的,但是要留意,如果其中储存了指针,一定要留意是不是指向了在INIT段上的内存,比如我碰到的这个问题里面,DEVICE_EXTENSION存放的UNICODE_STRING成员变量Buffer就是这样的指针。

另外发现这个坑10年前就有人踩了。害!

35417df12a264bceb006c9561513443a.png

参考资料:

[1] 驱动加入code_seg("INIT")出现蓝屏,问题出自《windows驱动开发技术详解》

[2] 关于#pragma code_seg

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值