在尝试运行《竹林蹊径 深入浅出Windows驱动开发》的第一个例子-HelloDRIVER时,在XP下没有问题,但在Win7下却发生蓝屏,蓝屏发生点在于卸载函数DriverUnload。

先看看卸载驱动的代码

VOID DriverUnload (__in PDRIVER_OBJECT DriverObject)
{PDEVICE_OBJECT deviceObject;UNICODE_STRING linkName;KdPrint(("Enter HelloDRIVER DriverUnload!\n"));deviceObject = DriverObject->DeviceObject;while(NULL != deviceObject){PDEVICE_EXTENSION deviceExtesion = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;// 删除符号链接与设备linkName = deviceExtesion->SymbolicLink;IoDeleteSymbolicLink(&linkName);deviceObject = deviceObject->NextDevice;IoDeleteDevice(deviceExtesion->DeviceObject);}KdPrint(("End of HelloDRIVER DriverUnload!\n"));
}
很通用的卸载驱动例程,按道理是不会出现问题的,从dump文件进行进一步分析,定位到deviceObject = deviceObject->NextDevice;这一句蓝屏,复制操作会导致蓝屏?什么鬼,再看下调用堆栈
原来还没到赋值语句,在处于IoDeleteSymbolicLink阶段就发生蓝屏了,于是就断点调试看下IoDeleteSymbolicLink的参数linkName是否正常,一调试发现memory can't access,
为什么会出现内存不可访问,于是追溯到DriverEntry,下面看下这个函数里面做了什么操作
NTSTATUS DriverEntry (__in PDRIVER_OBJECT DriverObject,__in PUNICODE_STRING RegistryPath)
{NTSTATUS status;PDEVICE_OBJECT deviceObject;PDEVICE_EXTENSION deviceExtension;UNICODE_STRING symbolicLink;UNICODE_STRING deviceName;ULONG i;KdPrint(("Enter HelloDRIVER DriverEntry!\n"));UNREFERENCED_PARAMETER(RegistryPath); RtlInitUnicodeString(&deviceName, L"\\Device\\HelloDRIVER");// 处理派遣例程 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++){DriverObject->MajorFunction[i] = DefaultDispatch; }DriverObject->DriverUnload = DriverUnload;DriverObject->MajorFunction[IRP_MJ_CREATE] = DefaultDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DefaultDispatch; DriverObject->MajorFunction[IRP_MJ_READ] = DefaultDispatch; DriverObject->MajorFunction[IRP_MJ_WRITE] = DefaultDispatch; // 创建设备 status = IoCreateDevice( DriverObject,sizeof(DEVICE_EXTENSION),&deviceName,FILE_DEVICE_UNKNOWN,0,TRUE,&deviceObject);if(!NT_SUCCESS(status)){return status;}deviceObject->Flags = DO_BUFFERED_IO;deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;deviceExtension->DeviceObject = deviceObject;deviceExtension->DeviceName = deviceName;RtlInitUnicodeString(&symbolicLink, L"\\??\\HelloDRIVER");deviceExtension->SymbolicLink = symbolicLink;// 创建符号链接 status = IoCreateSymbolicLink(&symbolicLink, &deviceName);if(!NT_SUCCESS(status)){IoDeleteDevice(deviceObject);return status;}KdPrint(("End of HelloDRIVER DriverEntry!\n")); return status;
}

重点在于这两句

RtlInitUnicodeString(&symbolicLink, L"\\??\\HelloDRIVER");
    deviceExtension->SymbolicLink = symbolicLink;

在网上查找资料RtlInitUnicodeString并没有动态分配内存,而是指向应用,而由于

#pragma alloc_text(INIT, DriverEntry)

DriverEntry函数是运行完后就退出内存,所以 RtlInitUnicodeString(&deviceName, L"\\Device\\HelloDRIVER");这个赋值方式不可靠。

解决方案:

在头文件或者函数外声明一个全局变量来存储符号链接,如

WCHAR  linkNameBuffer[] =  L"\\??\\HelloDRIVER";

然后再在函数内

RtlInitUnicodeString(&symbolicLink, linkNameBuffer);

即可解决读取符号链接不可访问的问题。

总结:

1.Win7会出现蓝屏,而XP不会,可能涉及到IoDeleteSymbolicLink里面的实现,会判断字符串的合法性问题

2.INIT和PAGE的区别,在驱动加载入口函数要注意字符串变量的生命周期

3.学会利用windbg进行调试分析

关于《竹林蹊径 深入浅出Windows驱动开发》第一个例子在Win7下蓝屏相关推荐

  1. 竹林蹊径:深入浅出Windows驱动开发(china-pub预订中)

    竹林蹊径:深入浅出Windows驱动开发(china-pub预订中) 基本信息 作者: 张佩   马勇   董鉴源 出版社:电子工业出版社 ISBN:9787121125553 内容简介 本书是作者根 ...

  2. Windows驱动开发学习笔记(一)—— 环境配置第一个驱动程序

    Windows驱动开发学习笔记(一)-- 环境配置&第一个驱动程序 环境配置 第一个驱动程序 环境配置 安装VS2010:https://pan.baidu.com/s/1uZWWxCtB60 ...

  3. Windows驱动开发书籍简介

    分享到 一键分享 QQ空间 新浪微博 百度搜藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 首页 我的主页 相册 广 ...

  4. C++开发方向之windows驱动开发

    1.为什么要写这篇文章? 最近浏览招聘网站看到关于windows驱动开发的岗位,前几天一个C++客户端工作岗位,猎头也问我是否有了解windows内核. 所以,调研了一下C++的开发方向:window ...

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

    5.在驱动中获取系统时间 1)获取启动毫秒数 在ring3 我们可以通过一个GetTickCount 函数来获得自系统启动开始的毫秒数,在ring0也有一个与之对应的KeQueryTickCount ...

  6. Windows驱动开发学习笔记(七)—— 多核同步内核重载

    Windows驱动开发学习笔记(七)-- 多核同步 基础知识 并发与同步 分析 InterlockedIncrement 原子操作相关API 内核文件 多核同步 临界区 示例一:错误的临界区 示例二: ...

  7. Windows驱动开发学习笔记(五)—— SSDT HOOK

    Windows驱动开发学习笔记(五)-- SSDT HOOK 系统服务表 系统服务描述符表 实验一:通过代码获取SSDT表地址 通过页表基址修改页属性 方法1:修改页属性 方法2:修改CR0寄存器 实 ...

  8. Windows驱动开发学习笔记(四)—— 3环与0环通信(常规方式)

    Windows驱动开发学习笔记(四)-- 3环与0环通信(常规方式) 设备对象 创建设备对象 设置数据交互方式 创建符号链接 IRP与派遣函数 IRP的类型 其它类型的IRP 派遣函数 派遣函数注册位 ...

  9. Windows驱动开发学习笔记(三)—— 内核空间内核模块

    Windows驱动开发学习笔记(三)-- 内核空间&内核模块 内核空间 实验 第一步:编译如下代码 第二步:将 .sys 文件拷贝到虚拟机中 第三步:部署 .sys 文件并运行 第四步:创建一 ...

最新文章

  1. Python基础-re模块
  2. 如何理解拜占庭将军问题?
  3. Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises)
  4. Ajax(二)-XMLHttpRequest(核心)对象的属性和方法
  5. [算法 笔记]2014年 去哪儿网 开发笔试题
  6. python︱matplotlib使用(读入、显示、写出、opencv混用、格式转换...)
  7. “我爱淘”冲刺阶段Scrum站立会议3
  8. java 反编译 exe_Java反编译
  9. ESP8266 WIFI 模块和手机通信
  10. linux基础操作之三
  11. 【外文翻译】外国友人写得很不错的Java Lambda表达式入门教程,我终于翻译好给大家啦!!!...
  12. 30行Python代码,抓取全网实时热点,获取最新资讯
  13. Comparator自定义顺序
  14. 论文中 c.f. i.e. s.t. e.g. w.r.t. et al. etc英文缩写是什么意思
  15. 微软“咸鱼翻身”:股价沉沦17年后创历史新高
  16. 如何在Windows上安装Ghost
  17. 智能超表面,6G时代的颠覆式技术揭秘
  18. 昂达vi40精英版刷Linux,昂达VI40双核版刷机教程
  19. IBM Rational产品与协作软件生命周期管理
  20. C++的异常处理机制

热门文章

  1. 人们的烦躁症,来自于社会结构的不稳定
  2. DVD机读碟故障维修技巧
  3. 【BZOJ】【P3685】【普通van Emde Boas树】【题解】【vEB树】
  4. 信息安全 —— 病毒前缀
  5. 大数据 就业 缺口_大数据专业就业前景 人才需求缺口大 今年增了24倍
  6. Graph Neural Networks (GNN)(三):Spectral-GNN 之 GCN
  7. 洞悉特性、属性和样式
  8. 【天眼】Java大规模分布式跟踪监控系统源码+视频教程小编送你!
  9. wce实现hash注入
  10. Java——阶段练习(2)