引用注明>> 【作者:张佩】【原文:www.yiiyee.cn/blog】

最近我发现为Win8开发的驱动程序,有些能安装在Win7上(包括更早系统),有些则不能。那些不能安装的情况很可怕:一旦安装并加载驱动,系统就会立刻蓝屏。针对这个问题,做了一番调查研究。发现了一个简单的规律:

如果开发时使用的是WDM驱动框架,则存在此问题;如果使用KMDF驱动框架,则正常。

这是为什么呢?一起来看看吧。

VS2012集成开发环境

Visual Studio 2012(简称VS2012)中包含了Windows驱动程序编译器,使得Windows驱动也可以在Visual Studio的集成开发环境中进行开发了。安装VS2012后,再安装Win8 WDK,打开VS2012会发现多了两种新的“平台工具集”,支持Windows内核和用户驱动程序的编译。如下图所示:

新建的内核驱动项目,会自动选择合适的工具集:WindowsKernelModeDriver8.0。更改工作集,会影响相关的工程项目设置,比如包含目录的查找路径等。所以,如果把驱动项目的工作集改成用户程序相关的话,编译器会报很多找不到头文件的错误,比如找不到<ntddk.h>。

和以前的控制台编译环境类似,在IDE环境中,我们也可以选择不同的目标系统:操作系统,硬件平台。通过工具栏上的列表框进行选择。如下图所示:

我们可以通过工程向导来产生一个WDM内核驱动项目,这里将项目名称设为Test。

Security Cookie导致的不兼容

编译器默认开启/GS编译选项,用来保护内核栈的完整性。编译器会在程序开始的地方,保存一个cookie值到栈上;在程序退出时再检查这个cookie值是否被破坏,如果被破坏,说明栈溢出,表明系统遭到了破坏从而需要蓝屏保护。

GS是一种被普遍运用的保护机制。开启了GS选项后,编译器会链接一个GS相关的库文件来实现GS功能,当目标系统为Win7时库文件是BufferOverflowK.lib,当目标系统为Win8+时库文件是BufferOverflowFastFailK.lib。链接器是如何实现栈保护的呢?它先在驱动加载的时候,也就是GsDriverEntry函数内初始化cookie。然后在每个驱动函数的开始和结束的地方,添加cookie检查的代码。

链接器为了对cookie进行初始化,会为驱动程序重新生成一个名为GsDriverEntry的入口函数,初始化Cookie后再调用驱动程序自己的DriverEntry入口函数。下面是一个典型的GsDriverEntry的实现:

Test!GsDriverEntry:
82ea403e 8bff            mov     edi,edi
82ea4040 55              push    ebp
82ea4041 8bec            mov     ebp,esp
82ea4043 e8bdffffff      call    Test!__security_init_cookie// 初始化cookie
82ea4048 5d              pop     ebp
82ea4049 e9b8fff7ff      jmp     Test!DriverEntry (82e24006)//调用DriverEntry
82ea404e cc              int     3

下面是Win7版本security_init_cookie函数的逻辑:

test!__security_init_cookie:
82eb3005 a10050e382      mov     eax,dword ptr [test!__security_cookie (82e35000)] ds:0023:82e35000=00300083
82eb300a b94ee640bb      mov     ecx,0BB40E64Eh
82eb300f 85c0            test    eax,eax
82eb3011 7404            je      test!__security_init_cookie+0x12 (82eb3017) // 判断是否等于0
82eb3013 3bc1            cmp     eax,ecx                                     // 判断是否等于0BB40E64Eh
82eb3015 751a            jne     test!__security_init_cookie+0x2c (82eb3031)
82eb3017 a13040e382      mov     eax,dword ptr [test!KeTickCount (82e34030)] // 获取当前系统时间
82eb301c 8b00            mov     eax,dword ptr [eax]
82eb301e 350050e382      xor     eax,offset test!__security_cookie (82e35000)
82eb3023 a30050e382      mov     dword ptr [test!__security_cookie (82e35000)],eax
82eb3028 7507            jne     test!__security_init_cookie+0x2c (82eb3031)
82eb302a 8bc1            mov     eax,ecx
82eb302c a30050e382      mov     dword ptr [test!__security_cookie (82e35000)],eax // 生成新cookie值// 返回
82eb3031 f7d0            not     eax
82eb3033 a30450e382      mov     dword ptr [test!__security_cookie_complement (82e35004)],eax
82eb3038 c3              ret

这段逻辑先检查security_cookie的当前值,如果不等于0且不等于0xBB40E64E,就立即退出;否则根据当前的系统时间,产生一个随机的cookie值。这里的值0xBB40E64E是个特征值,可能是系统默认生成的。大部分的镜像在加载的时候,其cookie都会被初始化成这个特征值。

当目标OS为Win8时,编译器默认链接BufferOverflowFastFailK.lib文件,它使用新的Cookie算法。正是这个新算法导致了不兼容性。看看Win8中security_init_cookie函数的逻辑,它硬是和0xBB40E64E较上了劲:

mov     eax, __security_cookie
test    eax, eax
jz      short loc_404029
cmp     eax, 0BB40E64Eh // 如果等于0BB40E64Eh,跳到下面产生0x29中断,产生蓝屏
jz      short loc_404029
not     eax
mov     __security_cookie_complement, eax
retnloc_404029:                             ; CODE XREF:
push    6
pop     ecx
int     29h               // 蓝屏

它判断当前的cookie值是否等于特征值0xBB40E64E,如果相等,立刻蓝屏。神奇的是,在 Win7及以前的OS上,大部分的驱动程序的cookie值都会被加载器初始化为0xBB40E64E。而在Win8+系统上则永远不会这样。这就是为什么能在Win8+正常运行的驱动,一放到Win7上就蓝屏的原因。

WDM和KMDF的区别

那为什么使用KMDF编译的驱动,又没有问题呢?原因很简单,KMDF框架链接的静态库文件还是BufferOverflowK.lib。不保证KMDF以后的版本不会链接新库文件的可能。

如何避免

虽然KMDF兼容性良好,但很多情况下,还是会用WDM框架编写驱动,而且还有很多小端口驱动也可能存在类似问题。如何避免呢。有三种简单的方法:

其一是为Win7及以前系统和Win8+系统产生不同的镜像文件。这也是比较推荐的方法。

其二是在Win8+系统上安装为Win7系统编译的驱动程序。经过测试,大多数为Win7编译的驱动程序,都能正常运行在Win8和Win blue系统上。但不保证更新的Windows系统出来后,这种向前兼容性仍然有效。

其三是干脆关闭GS编译选项。但这样就缺少了栈保护,不推荐。

最后介绍一种MSDN中介绍的比较高级的修改编译选项的办法,可以让编译器在为Win8+目标系统编译驱动程序时,仍选择旧版本的栈保护库文件BufferOverflowK.lib:

  1. 手动编译,手动设定KernelBufferOverflowLib的路径:
msbuild /p:KernelBufferOverflowLib="C:\Program Files (x86)\Windows Kits\8.1\Lib\win8\km\x64\BufferOverflowK.lib" /p:platform=x64 /p:Configuration="Win8 Release" myDriver.sln
  1. 用记事本软件打开驱动项目的工程文件,并在合适的地方添加下面的属性:
<KernelBufferOverflowLib>$(DDK_LIB_PATH)\BufferOverflowK.lib<KernelBufferOverflowLib>

Win8驱动的兼容性问题相关推荐

  1. 宽带我世界和win8、win8.1的兼容性问题的到解决了

    宽带我世界和win8.win8.1的兼容性问题的到解决了 1.百度搜索宽带我世界并下载 2.在安装软件之前,一定是安装之前哟,选中下载软件,右键--属性--兼容性,选择win7并用管理员打开 3.正常 ...

  2. 宽带我世界和win8、win8.1的兼容性…

    宽带我世界和win8.win8.1的兼容性问题的到解决了 1.百度搜索宽带我世界并下载 2.在安装软件之前,一定是安装之前哟,选中下载软件,右键--属性--兼容性,选择win7并用管理员打开 3.正常 ...

  3. 设备驱动的兼容性,例如cpu_to_le16函数

    中断管理 在2.1的开发中,有些Linux内部被修改了.新核心提供了对内部锁的很好的管理:通过使用几个细粒度的锁,而不是全局的锁,竞争条件被避免了,这样也获得了更好的性能----特别是SMP配置下.更 ...

  4. 通过修改程序解决Vista/Win7/Win8下应用程序兼容性问题

    在Vista/Win7/Win8下,有一个系统兼容性助手功能,使得程序在安装完成后或运行时,总是弹出应用程序兼容性助手相关的提示,很是烦人,事实上我们的程序兼容性是没有问题的,只不过是在程序中没有指定 ...

  5. windows10/win8.1下AMD显卡驱动无法安装的解决方法

    win10已经出来很久了,个人很喜欢win10,相比于win8改进了很多,使用起来更方便,但是在安装显卡驱动上,着实费了我很长时间.我的笔记本是Thinkpad E40,显卡是ATI Mobility ...

  6. 计算机更新有什么坏处,电脑上的驱动要不要经常更新,更新的好处和坏处有哪些,驱动和硬件之间的关系...

    知识导读:最近电脑用起来比较卡,在游戏里将这个烦恼高速了和我以前一直玩的朋友,他让我将驱动更新一下,我对此没啥概念,因为大学才接触的电脑,用起来也就一两年而已,一直属于电脑萌新,对于驱动这些概念知之甚 ...

  7. 原装win8系统电脑崩溃问题解决

    原装win8系统电脑崩溃问题解决 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:之所以撰写本篇关于win8原装系统电脑崩溃的博文,一是要吐槽一下原装w ...

  8. windows 7 下安装 Android 设备驱动

    为什么80%的码农都做不了架构师?>>>    window xp 我不知道,很久不用xp了. 1.将设备通过USB线连接PC机,这个时候系统会自动安装驱动,但是最后提示不成功: 2 ...

  9. 计算机设备驱动程序的安装与更新,电脑系统驱动如何安装更新?

    电脑平时出现问题比较多的一个是系统问题,一个是硬件问题!这两个问题都会跟电脑驱动打交道!如果说驱动出现问题就会引起电脑蓝屏.卡屏.拖尾等现象,就需要重装驱动程序,电脑驱动的安装也不是简单的安装一下就行 ...

  10. VMware ESXi 8.0 Unlocker OEM BIOS 集成网卡驱动和 NVMe 驱动 (集成驱动版)

    发布 ESXi 8.0 集成驱动版,在个人电脑上运行企业级工作负载 请访问原文链接:VMware ESXi 8.0 Unlocker & OEM BIOS 集成网卡驱动和 NVMe 驱动 (集 ...

最新文章

  1. 全球IT支出保持稳定增长 中国IT支出将超2.3万亿元
  2. Elasticsearch介绍Kibana分词器增删改操作
  3. java logfaction_Java调试的变迁:从System.out.println到log4j
  4. boost::strong_components用法的测试程序
  5. P3195 [HNOI2008]玩具装箱TOY(斜率优化)
  6. P1352-没有上司的舞会【树形dp】
  7. 云原生时代微服务的高可用架构设计
  8. SCOI2019凉凉记
  9. 内连接 左连接 右连接 交叉连接的区别
  10. mesh threejs 属性_ThreeJS拖动案例解析
  11. c++11支持类数据成员的初始化
  12. Remove Duplicates from Sorted List解题报告
  13. 帧率常量15可以随便改,问为什么是15,是想暴露自己不懂编程?
  14. div+css需要注意的问题
  15. 如何修改服务器ntp配置,[修改]Linux下NTP服务器的配置
  16. 2019/10/8今日头条笔试
  17. 学习笔记:弱监督学习-valse青年会议
  18. 【一键激活win8.1系统】
  19. excel自动填充脚本(awk)
  20. 五个学习管理系统的优点

热门文章

  1. WinRAR的命令行模式用法介绍
  2. 使用电子签章确立电子劳动合同的法律效力
  3. 小甲鱼C语言单链表通讯录作业
  4. 最大团问题回溯法求解
  5. python爬取景点信息_Python用Pyspider爬取TripAdvisor的景点信息
  6. snmptrap 中文内容java解析_snmp trap内容中的中文如何解析
  7. 微信小程序css方式animation动画弹幕实现
  8. 游戏框架设计【各大管理系统篇】
  9. ad软件画pcb方法总结_AD软件中导入BRD的PCB文件总结分享,,,,
  10. 第十三届蓝桥杯省赛Java-B组