首页
社区
课程
招聘
[原创]Visual studio 2008+DDK搭建驱动开发环境(一)
发表于: 2013-3-10 13:41 11668

[原创]Visual studio 2008+DDK搭建驱动开发环境(一)

2013-3-10 13:41
11668
Visual studio 2008+DDK搭建驱动开发环境(一)
驱动开发对这里的很多新人都具有很强的吸引力,相信很多人都还没来得及在Windows平台下写出一个内核态的Hello Word,也许是正处于理论学习阶段还没有着手实践,也许是想实践但是却一直徘徊在起点。说到驱动开发的起点,当然包括很多方面:编程能力,内核架构的了解,少量硬件知识等等。但是这篇文章不会介绍这些东西,今天只讲真正的起点—开发环境的搭建,希望能让所有在这个真正的起点上遇到问题的人都能顺路走上驱动开发的实践之路。

目前网上关于Windows驱动开发环境的介绍最多的就两个:Driver Studio和DDK Wizard,还有一种估计只有大牛才用:make……make……原生态DDK Build Environment。10年末的时候看完了扬帆的《Windows 驱动开发技术详解》,然后就急切的想写个驱动出来找找感觉,后来按照网上的一篇文章搭建了DDK Wizard的环境,也算写出了自己的第一个驱动,可是总觉得对驱动编译环境的配置,项目工程属性的配置,编译链接过程等一无所知。所以还是想去了解一下DDK的原生的build环境,然后想办法把这些环境通过自己动手的方式在Visual Studio中实现一下。

Visual Studio本身就是一个开放的扩展性很强的IED,所以我们完全可以不借助任何额外的框架来搭建自己的开发环境。因为编写驱动需要考虑目标机器的架构(CPU架构),所以对于不同的目标机器架构我们应该搭建不同的开发环境,具体的不同之处是我们在编译过程中所使用的编译工具(可执行程序)不同。
比如我的机器是32位CPU的32位Windows 7系统,如果我要编译一个将来运行在32位CPU的Windows 7系统下的驱动,那我在编译过程中就使用专门的为x86架构生成目标程序的cl.exe和link.exe。
而入如果我想要编译一个将来运行在32位CPU的其他系统,或者运行与64位CPU的系统中的驱动程序,那我就要使用专门的为amd64架构生成目标程序的cl.exe和link.exe,这就属于交叉编译了。

本文主要介绍在32位CPU下的32位操作系统下搭建开发运行于32位Windows XP系统下驱动程序的环境,其他的各种交叉编译环境可以按照文中的方法进行配置。 
下面详细介绍环境搭建的步骤:

本人的机器环境:32位Intel CPU,32位 Windows7系统,系统的位数决定了编译过程中使用的一些可执行文件版本。
准备软件:Visual Studio 2008 安装包和Window Driver Devlopment Kits(DDK)—仅此两项。注意这里只选择了VS2008,低版本和高版本没有搭建过,所以不确定本文方法试用,DDK的版本我用的是7600.16385.1。

第一步:安装Visula Studio 2008,路径随意,最好不要放在系统分区下,常识。
还有两点需要提醒下,首先Visual studio集成了很多开发功能,可是如果你的专业方向够单一,就把多余的去掉吧,像我的只选择了VC++这个组件,什么VB,C#,Web,SQL都没有安装,节省空间,加快VS启动速度。其次建议安装完整的本地MSDN(作为一个Windows开发者,如果连一个Windows API的返回值都搞不清,是该说他不敬业呢,还是不专业呢?工作中经常看到这种情况,最滥用的一个就是INVALID_HANDLE_VALUE。既然这个事说了,那我就补充点小插曲,工作中看到有很多代码比如获取一个进程或线程的句柄,然后拿返回值和INVLAID_HANDLE_VALUE进行比较来判断成功与否。进程和线程句柄有两个特殊值,-1:当前进程,-2:当前线程,如果你用GetCurrentProcess的值和INVALID_HANDLE_VALUE来进行比较,那就悲剧了。小知识:IVALID_HANDLE_VALUE是16位Windows系统时候的遗留物,在如今的32位或者64位Windows下除了常用的CreateFile和少数其他句柄相关API会返回该值外,其他句柄操作都用NULL来进行判断。)

第二步:安装Windows DDK,路径随意,同上不要放在系统分区下。
同样需要提醒下,安装过程去掉不需要的组件。这里想介绍一下DDK的目录结构和用途。
DDK安装完成之后目录下一般是一个版本号,在版本号目录下才是很多子目录,重要的有这几个:bin,inc,lib。
bin:该目录中放置的是一些编译链接工具。其下又有子目录x86,ia64,amd64等,IA64在本文中不会进行任何介绍,因为一般开发者基本不会接触到这个纯的64位架构。
  bin\x86:该目录下存放的都是32位程序,其中包含的都是编译器和链接器,在这个目录下又存在x86,ia64,amd64文件夹,这些目录就是用于交叉编译的。
      bin\x86\x86:存放有cl和link等,用于编译链接运行于32位系统下的目标程序
      bin\x86\amd64:存放有cl和link等,用于编译链接运行于64位系统下的目标程序
  bin\amd64:该目录下存放的都是64位程序,只能运行于64位系统中,这些程序只是一些签名和证书的工具,如果你的系统是64位并且需要进行这些操作,那就使用他们吧。
inc:该目录下存放的是编译期间使用的头文件
lib:该目录下存放的是链接期间使用的lib文件,其中有atl,mfc,crt,和wdm是同用的,而剩下的几个目录则是针对你要编译的驱动运行的系统选择一个使用的。其对应关系如下
lib\wxp:用于链接运行于Windows XP下的驱动程序
lib\wlh:用于链接运行于Windows Vista and Windows Server 2008下的驱动程序
lib\wnet:用于链接运行于Windows Server 2003下的驱动程序
lib\win7:用于链接运行于Windows 7下的驱动程序
而以上目录下又会有i386,amd64,ia64文件夹,

以上两步都成功完成,为了方便后续行文,我把以上两个安装路径给出来,在我的机器上路径如下:
VS 2008:F:\Program Files\Microsoft Visual Studio 9.0
WinDDK:F:\WinDDK

第三步:配置用于驱动开发的vssettings。
Visula Studio的一个特性就是整个IDE的所有配置都可以个性化定制,然后导出为vssettings文件保存,这样就可以把自己习惯使用的一套环境配置保存成文件,如果以后工作环境迁移,或者重装VS的时候就可以直接导入保存过的配置文件,然后就可以看到自己习惯使用的熟悉的界面布局和内部设置了。而我们就可以利用这个特性来设置一套专用与内核驱动开发的配置,然后保存为配置文件,这样如果以后我们要进行驱动开发的时候就导入个配置文件就行了,如果要进行普通的应用层程序开发,只需要导入默认的配置文件行了。具体配置方法:
1.  设置编译工具可执行文件路径,工具>选项>项目和解决方案>VC+目录,如下图所示:
 
删除原有的所有文件路径,然后添加如上图所示的两个文件夹。因为我们最开始说的是搭建开发运行于32位Windows XP系统下驱动程序的环境,所以这里的第二行我选择了x86\x86文件夹,如果你需要编译运行于64位架构下的驱动程序就应该选择x86\amd64文件夹。

2.  .设置默认包含文件搜索路径(include),工具>选项>项目和解决方案>VC+目录,如下图所示:
 
删除原有的所有目录,添加如上图所示的目录。

3.  设置默认库文件搜索路径(lib),如下图所示:
 
删除原有的所有目录,添加如上图所示的目录,同理,因为我们是要搭建开发运行于32位Windows XP系统下驱动程序的环境,所以这里的所有库文件都要选择i386目录。

第四步:导出并保存已经配置好的开发环境。
选择工具>导入导出设置…,然后选择“导出选定的环境设置”,然后把所有选项都勾选上,如下图所示:
 
然后选择配置文件的保存路径,命名,在这里我命名为x86-DrvDevEnv-shion.vssettings。以后如果要进行驱动开发,我们就选择导入导出设置,然后导入这个保存的环境配置,就会切换到我们配置好的环境了。

到这里,我们已经搭建完成了一个驱动的开发环境,用这个环境我们可以开发运行于32位操作系统下的所有驱动程序了,驱动开发的老手可能已经注意到了,在lib搜索目录下面我并没有配置一个对应于系统的lib文件路径,这样做的理由是,这个环境是作为32位操作系统下的驱动开发而搭建的,至于我们要编译的驱动程序需要运行在哪个具体的操作系统下,这个属性应该属于一个驱动程序的Procject工程属性,所以这个配置在工程属性中更为恰当一点。下面我们来创建一个工程,命名为HelloKernle。
选择新建项目,然后选择Visula C++下的常规,选择空项目,然后创建。然后添加一个名为HelloKernel的cpp源文件,源文件内容如下:
#include <ntifs.h>

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
           IN PUNICODE_STRING pRegistryPath)
{
  NTSTATUS status;
  
  DbgPrint("Hellor, Kernel!\r\n");

  status = STATUS_SUCCESS;
  return status;
}
先别着急编译,因为我们用的Windows 应用程序的编译链接配置,所以现在编译的话肯定是会出错的。
下面进行工程编译链接配置。
打开配置管理器:
 
在活动解决方案配置下面下拉列表中选择新建,命名为wxp-i386-Checked,其他选项参照下图,这里我们是要配置一个Checked编译,在驱动编程中Checked相当于应用程序的Debug版本,Free相当于应用程序的Release版本,不好意思手误,下图中所有的checked写成了cheched了: D

 
然后点击确定,关闭。
然后在解决方案资源管理器中右键工程,选择属性,弹出配置对话框,然后参照下图进行所有的配置,图中黑体字都是需要修改的选项,没有贴出来的配置页面都是不需要修改的。

编译器-常规
 
编译器-预处理器
  
编译器-代码生成
 
编译器-高级
 
链接器-常规
 
这里需要说明一下,我们编译的驱动的目标机器是xp,所以上图的附加库目录选择wxp的,如果要编译其他系统的就只需要改成其他系统的库目录。

链接器-输入
 
链接器-清单文件
 
链接器-系统
 
链接器-高级
 

设置完成之后,进行熟悉的编译操作吧,然后就可以看到生成的HelloKerne.sys了,然后用Driver Monitor加载,用DbgView观察,第一个驱动已经正常运行工作了。我在这里是直接在Windows 7系统上运行的,虽然说使用的是xp的lib,但是程序中仅仅只有一个DbugPrint函数,并没有牵涉到Windows 7系统新增加的函数或者数据结构,所以运行起来是没有任何问题的。

 

好了,到这里已经使用我们自己搭建的环境编译了第一个驱动程序,可是如果以后每次编写一个驱动工程都要这么繁琐的一步一步的去设置工程属性吗?为什么我们创建其他工程的时候都可以免去这些步骤呢?其实这些步骤是可以省去的,做法就是用Visual Studio的自定义向导功能,创建一个自定义的向导,以后我们创建驱动项目的时候就可以像其他工程一样选择一个对象的工程类型,当创建完毕的时候VS已经把我们配置好的工程属性,和代码框架加进去了。

额,本文就到这里吧,写起来有点累。。因为要贴图,下篇文章介绍创建用于配合DDK编译驱动的自定义向导。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 6
支持
分享
最新回复 (3)
雪    币: 84
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
顶一个。。表示懒人....一般用easysys或者visual ddk....
2013-3-10 15:02
0
雪    币: 2120
活跃值: (73)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
还是visualddk+vs2010好用啊
2013-3-10 15:06
0
雪    币: 215
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
很久没写驱动了~
2013-3-13 15:11
0
游客
登录 | 注册 方可回帖
返回
//