![b659fa4ea552527bbce9a538621259b2.png](https://i-blog.csdnimg.cn/blog_migrate/0de7d2d6198defa3b160558ad2345273.jpeg)
相对而言,市面上驱动开发的书确实不多,虽然这本书还是以Windows XP进行讲解,但它放到现在仍然是学习驱动开发的不错的选择。
我碰到的问题是,第四第五章的内容,即使是用示例代码编译驱动,在安装,启动时都是正常的,但是卸载驱动,驱动执行Unload例程时,里面的IoDeleteSymbolicLink(&pDevExt->ustrSymLinkName)
时,猛然发现:预先保存在DEVICE_EXTENSION
中的符号链接指向的内存已经无效了,SymbolicLink字符串不翼而飞!?
![f893e8a142d36b87c47525398201c483.png](https://i-blog.csdnimg.cn/blog_migrate/b313b7732af925ab1f447ce06cfab3be.jpeg)
具体情况
按照示例代码,有一个头文件里面有如下定义
#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](https://i-blog.csdnimg.cn/blog_migrate/7b43eba0d9c215ebfb8592d20d714340.png)
当然,按照示例代码,DriverEntry
,CreateDevice
函数代码自然都在INIT段里面。
解决方案
#pragma INITCODE
去掉或者改为pragma PAGEDCODE
总结
code_seg("INIT")
下的函数和其中的字符串在驱动加载时装入内存 ,会在之后移出内存。DEVICE_EXTENSION
用来放device对象的额外数据倒是安全的,但是要留意,如果其中储存了指针,一定要留意是不是指向了在INIT段上的内存,比如我碰到的这个问题里面,DEVICE_EXTENSION
存放的UNICODE_STRING
成员变量Buffer
就是这样的指针。
另外发现这个坑10年前就有人踩了。害!
![35417df12a264bceb006c9561513443a.png](https://i-blog.csdnimg.cn/blog_migrate/cff202e27c2d06e4c18df18d7aab7754.png)
参考资料:
[1] 驱动加入code_seg("INIT")出现蓝屏,问题出自《windows驱动开发技术详解》
[2] 关于#pragma code_seg