Windows内核安全与驱动开发(txt+pdf+epub+mobi电子书下载)


发布时间:2020-09-04 19:51:16

点击下载

作者:谭文,陈铭霖 等

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Windows内核安全与驱动开发

Windows内核安全与驱动开发试读:

前言

本书的前身是《天书夜读——从汇编语言到Windows内核编程》和《寒江独钓——Windows内核安全编程》。实际上,本书相当于这两本书(重写和充实了不少章节)的合体。因为这两本书讲述的内容本来就是同一类技术,只不过各有侧重,合并成一本书之后体系更加完整了。

与Windows客户端安全软件开发相关的驱动程序开发是本书的主题。因为这些驱动程序都运行在Windows内核中,所以本书称为《Windows内核安全与驱动开发》。这些驱动程序主要分成三大类:第一类是串口、键盘等输入/输出设备驱动程序;第二类是硬盘、文件系统驱动程序;第三类是网络驱动程序。覆盖了客户端安全的Windows编程中所涉及的各种驱动程序。书中的程序使用环境从32位到64位,从Windows XP到Windows 8都有涉及,大部分程序不经过修改即可在Windows 10上运行。同时本书也深入浅出地介绍了进行内核安全编程所需要的操作系统、汇编等基础知识。

与前身相比,本书重新排布了章节,主体上分为三个部分。第一个部分为“

基础篇

”,囊括了驱动开发的基础知识,降低了入门的难度;第二个部分为“开发篇”,包含了在实际工作中可能遇到的各种开发需求的技术实现;第三个部分是“高级篇”,汇编语言、操作系统原理、处理器体系架构相关的内容都放在了本篇中介绍。本篇内容对读者来说可能会感觉比较困难,但由于有前两篇的基础,相信读者不会太难以跨越。

本书是由长期从事这个行业的工程师自己写的,所以处处以实用为准。对细节的考究主要体现在对实际问题的解决,而不是知识的详尽程度上。有些读者可能会觉得这不太像一本“教科书”,在某些细节点上很有“囫囵吞枣”的嫌疑。当然,本书本来就不是教科书,但它是可以用来学习的。只是学习的方法,以实际应用为唯一的动力。

以前常有读者和我交流。我发现最常问的问题是:“我对内核编程有兴趣,请问应该如何学习呢?”

学习的方法应该根据每个人不同的需要有所不同。每个人性格不同,学习的路线也会不一样。比如有的人就擅长计划,他们会先制定周全的步骤,然后按部就班地执行。先从有经验的人那里讨教“如何学习”也是步骤之一。我曾很努力地想这样去做,但总是没有足够的毅力而失败。所以我成了一个随波逐流、随遇而安的家伙。我的学习都是迫不得已,没有计划和方法可言。所以被问到这个问题时,我只能说,我都是在解决实际问题的过程中学习的。这个风格也被带到了本书中。

在读大学的时候,我对驱动开发并无任何概念,我也不为此担心。什么时候我会需要为一个硬件去编写驱动程序呢?这不是硬件厂商的事吗?我为一家硬件厂商工作的机会本来就低,更何况几千个员工里轮到我去写驱动的概率更是低到不可思议的程度。但世事就这么难料。我刚进第一家公司,自以为VC 6.0用得多么熟练,准备大干一场的时候,老板说:“我这里有个无盘驱动,你去做试试看……”

当时,他们需要的是一种类似“网络邻居”的共享盘。硬盘的主体在服务器上,上面有很多文件共享给所有的客户机。Windows本身的“网络邻居”不足以满足全部需求。他们要求每个客户机对这个磁盘都有读写的权力,可以新建、修改或者删除磁盘上的文件。如果直接用Windows的目录共享,很快这个磁盘上的文件就会被修改得乱七八糟。所以另一个要求是,任何人都可以修改,但任何人的修改都不得影响他人。

这听起来有点怪,其实很简单。大家共享一台服务器的磁盘上的所有文件,但各自对这些文件的修改都保存到本地。虽然听起来是很合理、简洁的一个需求,但是对我来说却完全摸不着头脑。我写过很多程序,但还从未写过一个东西能让计算机的硬盘的行为发生改变。这是因为我一直只会写用户软件,从没动过操作系统。

操作系统非常努力地提供了完善的功能,来应付各种用户的需求。但用户的需求真是取之不尽、用之不竭的,仅仅一家开发操作系统的公司,永远也无法满足用户的需求。是否允许第三方拥有操作系统的权限来满足这些需求呢?这就形成了两种截然不同的应对方案:Windows是允许的,任何第三方都可以通过开发驱动程序的形式来改变系统内核的行为;而像苹果的iOS这种操作系统是完全禁止的。

为了证明我的价值足够保底薪水,我不得不开始研究这个东西怎么实现。它肯定不是我以前实现过的任何一类工程。当时还是Windows 9x的时代,资料奇缺,甚至连开发用的工具包都不知道去哪里找。具体的过程我已经记不太清了,侯捷翻译后又免费放出电子版的一本专门讲VXD的书起了很大的作用。

最后我把这个东西做了出来。那时,我每天加班到晚上,早晨一睁眼就想往公司里赶。我敢保证任何人换了是我也会一样:第一次参加工作,到手的第一个任务,谁都想证实自己的价值。我不记得有多少知识被我“囫囵吞枣”了,但我确实满足了用户的需求。离奇的是,那时我还根本不会用WinDbg,整个过程只靠“蓝屏试验”,压根就没像样地调试过。这根本无须任何学习方法。在有如此强烈需求的境况下,一切的不合理都会顺理成章。

开发驱动程序类似于为普通的软件开发一个“组件”。与别人约定好调用的接口,你就可以和别人协同合作,开发一个“dll”之类的组件去给别人使用。对操作系统内核也是如此,只不过这个接口由操作系统硬性规定,容不得协商。

在那个项目中我们写了种种功能来“愚弄”操作系统。这听起来像是一个磁盘相关的驱动,实际上却是一个文件系统过滤驱动。它过滤文件系统的行为,比如:读取文件时,我们让操作系统以为在操作普通的本地文件系统,其实却是去网络上取文件内容;而修改文件时,我们也让操作系统以为修改成功了,实际上数据并没有写入到网络上的服务器中,而是写到本地了。这是我第一次接触这类驱动程序。

有了这些项目的经验,后来就有了《天书夜读——从汇编语言到Windows内核编程》《寒江独钓——Windows内核安全编程》之类的书,也有了本书。虽然这个跨度有点长,一晃七八年过去了,但这和我的拖拖拉拉有很大的关系。《寒江独钓——Windows内核安全编程》绝版之后,编辑一直催促我修改出新的版本。但我继续磨蹭,直到我到了腾讯电脑管家的团队,这里遇到的优秀同事愿意帮我整理已经乱七八糟的稿子,并填充最新的章节,最后耐心地审校和完善代码,本书才能最终得以面世。至于如何学习,我已经说了自己的糟糕的例子。我可以大概总结如下:

有计划和毅力是最好的。耐心地读完本书,调通上边所有的例子。虽然工作中不一定真会用到,但里面的东西都是别人实际用到过的。

没有必要害怕接受自己不熟悉的工作任务。泰山压顶的工作压力也是学习最好的动力——好吧,因为我没有前面一条,所以这一条就成了我唯一的动力了。碰到急需完成的任务,本书上有时也有可以参考的现成代码,不妨翻一翻看看。懂不懂没关系,先用了再说。

理想是美好的,可以创造一些令人意外的东西。但最后还是要着眼于实际。

写代码是一件很爽快的事,但调代码会很烦。读者如果买了本书并且打算从事这方面的工作,希望不要为调试的各种困难而烦躁,因为以后这就是工作的主要部分了。我因为第一个任务的缘故,一不小心就陷入十多年。开头几年里大多数时间我都很烦躁,常常被BUG逼得感觉走投无路。现在好多了,差不多有七分自信能将事做成。当然,剩下三分还是要靠天意的。谭文2015年5月基础篇

第1章 内核上机指导

请注意,因为大部分Windows驱动程序都是内核驱动(Kernel Driver),所以本书中,不区分“驱动编程”与“内核编程”。同时,也不区分“内核模块”(Kernel Module)与“驱动程序”(Driver),这两个词汇都指本书中编译出的扩展名为“.sys”的可执行文件。

但是本书和一般“驱动开发”书籍不同的是,本书专注于较通用的内核程序的开发,并不介绍针对某种硬件,比如声卡、显卡、USB等的各种驱动程序的开发。

本书的许多内容涉及各种不同的内核驱动程序,比如文件系统驱动(File System Driver)、存储设备驱动(Storage Driver)及网络驱动(Network Driver)。但是开发目的,并不是为了驱动某个硬件,而是在通用的Windows上实现某种功能。

Windows上内核(Kernel Model)编程和用户(User Model)应用编程有很多不同的地方。初次学习,很多读者会关心如何开始动手实践。为此本章专门讲述如何在Windows的PC上,下载和安装必要的工具,并动手开始内核编程。值得庆幸的是,在Windows上进行内核编程、编译、调试、安装、显示调试信息的全部必要工具(不包括为了编程方便而使用的Visual Studio),都是免费的,因此任何读者都可以在不花费任何金钱的情况下开始学习这一章节。

对实际上机暂时没有兴趣,或者已经做过驱动开发的读者,则可以跳过第1章。

1.1 下载和使用WDK

1.1.1 下载并安装WDK

就像应用程序使用开发包SDK一样,内核编程使用“Windows Driver Kit”,简称WDK。WDK已经自带所有需要的头文件、库、C/C++语言及汇编语言的编译器与连接器,所以完全可以在不安装Visual Studio的情况下进行编程。只是工程管理会不太方便,读者可以使用记事本或者自己喜欢的其他文本编辑器进行编程。习惯使用Visual Studio的读者会感觉这很酷,因为只有传说中的骨灰级程序员才使用记事本编程。

建议读者下载一个能显示行号的文本编辑器,以便出现编译错误时能迅速找到错误。Linux爱好者当然可以直接用vim。

有些读者可能听说过DDK或者IFSDDK,但是那已经是历史了,请遗忘它。同时,下面的描述也可能成为历史,所以请读者进入主页后应该随机应变。

首先请打开网页:

https://connect.microsoft.com/default.aspx

这个网页必须先登录。登录拦住了不少访客,有些访问者会以为是收费注册的,其实使用Windows Live账号就可以登录(即用MSN账号登录)。如果没有MSN账号,可以去免费注册一个。

有了Live账号之后,还必须用这个账号向Connect注册,才能下载WDK。用Live账号登录之后,下面出现“立即注册Connect!”链接。

注册很简单,只要填写名字、地区和邮箱就可以了。虽然要填写邮箱,但是笔者并没有去打开发送到邮箱中的文件,这个ID就直接可以下载了。笔者不确定是否真的如此,请读者自己尝试一下。

登录之后出现一个“配置控制面板”页面,但是笔者没有使用它,单击上面的“主页”链接,回到主页,能看见显示自己已经登录了。大致画面如图1-1所示。图1-1 connect.microsoft.com的主页页面

请单击图中用圈圈住的“查看所有站点”。

下面就比较简单了,左边会显示类别,在类别中请选择“开发人员工具”。选择之后右边就有“Windows Driver Kit”可以下载,请按网页的提示逐步下载即可。这个开发包非常大,下载之后有几GB的内容(注:最新版本的WDK已经缩减,只有几百MB了)。在下载WDK之前,请先根据此时页面的提示下载并安装FTM(File Transfer Manager),可以大大加快下载速度。

安装过程没有需要特别注意的地方,只有两点:(1)安装到一个简单一点的路径下,避免在特殊情况下需要配置路径时麻烦,比如C:\WinDDK。尤其要避免在路径上有空格,否则可能出现编译问题。(2)一定要选择“完全安装”,否则可能错过一些代码例子。1.1.2 编写第一个C文件

现在请打开记事本(或者读者喜欢的任何工具)来创建一个文件,我们把这个文件命名为first.c,以表示这是我们编写的第一个内核编程文件。在进行内核编程时,读者必须打开WDK的帮助。在WDK安装之后,单击“开始”菜单→“所有程序”,会发现增加了“Windows Driver Kits”和“Windows Driver Kits Documentation”两个子菜单(注:最新版本这两个菜单已经合并为一个)。

选择“Windows Driver Kits Documentation”下面的子菜单来打开帮助。在使用任何一个函数之前,请在帮助里查询这个函数是否存在、使用的环境要求及输入/输出。

因为这不是应用程序编程,所以所有的Win32 API函数都不能使用;部分C Runtime函数也不能使用,但是文档中说明的函数则都可以使用。本书将在文档中有说明且在内核下调用的System Routine称为内核API函数,以便和Win32 API函数区分开。

我们编写first.c内容如下:

上面的DriverEntry是每个内核模块的入口,在加载这个模块时被系统进程System调用一次。在其中我们设置了DriverUnload的函数指针,这样这个模块可以被动态地卸载(这将方便我们调试程序);如果没有设置DriverUnload函数指针,则一个内核模块一旦被加载就不能卸载了。

现在请先建立新目录first,然后把first.c文件保存在此目录下。下面我们就介绍编译的方法。1.1.3 编译一个工程

前面已经建立了工程first,虽然这个工程只有一个first.c文件作为代码文件。现在必须在这个目录下增加两个文件,以便WDK的build工具可以build它。其中一个文件的名字必须为makefile,这个文件的内容很无聊,永远也不需要改动,内容如下:

如果读者不想自己写这个文件,那么请到WDK的src目录下随便寻找一个例子,然后拷贝一个出来。大部分例子的makefile都和这个一样。

另外,还需要一个名字为SOURCES的文件,这个文件的内容关系到这个模块要编译哪些文件,以及编译出来的.sys文件的名字。举例内容如下:

其中TARGETNAME表示名字,编译出来之后,模块的名字为first.sys;SOURCES表示要编译的.c文件(对于初学者,必须提醒一点,不要加入.h文件,因为.h是被包含在.c文件中编译的),如果.c文件有多个,请用空格分隔。

下面请从“开始”菜单中打开WDK的build环境配置,如图1-2所示。图1-2 从“开始”菜单中打开WDK的build环境配置

从“开始”菜单中选择“所有程序”,然后选择“Windows Driver Kits”→WDK的版本(这里是“WDK 6001 18001”)→“Build Enviroments”→“Windows XP”→“Launch Windows XP x86 Checked Build Enviroment”。出现一个控制台,这个控制台已经配置好编译环境。现在输入“cd”命令,进入我们先前建立的first目录;进入之后,输入“build”命令。笔者这里编译的结果如图1-3所示。图1-3 first编译的结果

现在编译结束,first.sys出现在\first\objchk_wxp_x86\i386下。这个文件并不像普通的exe文件一样可以直接双击执行,它需要一个安装工具进行安装。下面讲解如何安装并运行它。

1.2 安装与运行

1.2.1 下载一个安装工具

有很多工具可以安装内核模块,但是笔者不大敢随便下载推荐给读者,因为现在网站上病毒实在太多了。请读者搜索srvinstw.exe。这个小软件还有汉化版,笔者在华军软件园找到的地址如下:

http://www.onlinedown.net/soft/36059.htm

如果这个地址已经失效了,请读者自己在网上搜索这个小工具。(1)执行这个工具,把我们编写的first.sys安装到自己的计算机上。刚开始打开的界面如图1-4所示。(2)选择“安装服务”并单击“下一步”按钮。然后选择“本地计算机”,单击“下一步”按钮,这时要输入服务名称,这里输入文件的名字“first”。但这个名称不一定要和文件名相同,可以随意输入,只是不能和已经存在的服务冲突。(3)输入sys文件的路径:这里只能手工输入,请不要去单击下面的“浏览”按钮。因为只能浏览到exe文件,却无法找到sys文件。(4)选择“设备驱动”。(5)输入“NT驱动器目标名”:不需要输入任何内容,直接单击“下一步”按钮即可。(6)选择启动类型:请一定选择“手动”(见图1-5)。选择手动可以方便调试,可以在所需要的时间进行启动和停止。

至此,就安装成功了。图1-4 执行srvinstw.exe的开始界面图1-5 srvinstw.exe安装到最后一步选择“手动”1.2.2 运行与查看输出信息

现在这个内核模块已经可以运行了,但是我们不会看到任何现象。虽然在前面的代码中,调用了DbgPrint来打印一些信息,但是因为这是内核模块,不能指望它弹出一个窗口,或者显示一个控制台来输出那些信息。

可以在WinDbg中看到内核模块的输出(也就是调用DbgPrint)。但是我们目前还没有讲到如何调试内核代码,现在用DbgView.exe来查看输出是个不错的选择。可以从微软的网站上下载DebugView.exe,笔者下载时使用的地址如下:

http://technet.microsoft.com/zh-cn/sysinternals/bb896647(en-us).aspx

如果这个地址已经失效了,请读者自己搜索。

打开DebugView.exe之后,界面如图1-6所示。注意:DebugView可以捕获各种输出,所以要把“Capture Kernel”勾上,才能看到内核输出。图1-6 DebugView的界面

由于前面已经安装了服务,所以,现在打开控制台(单击“所有程序”→“附件”→“命令提示符”),输入“net start first”就可以启动first.sys了。反之,可以输入“net stop first”来停止它的运行。请注意,“net start”之后跟的是服务名(在前面安装时的第2步指定的),而不是文件名。这个驱动安装时用的服务名和驱动文件的名字刚好一致,容易引起误解。读者要记住,如果前面输入了不同于文件名的服务名,这里就必须用安装时输入的服务名。对于这个例子,控制台输入/输出的结果如图1-7所示。图1-7 first的运行和停止

与此同时,笔者在DebugView中看到的输出结果如图1-8所示。图1-8 first运行的输出结果1.2.3 在虚拟机中运行

虽然按照前面的设置,读者已经可以编译一个内核程序并在自己的计算机上运行了,但是在本机上直接加载刚刚编写的内核模块是非常不明智的。如果模块中有错误,很容易导致操作系统立刻蓝屏,这时工作文件可能还没有保存,导致代码丢失。

笔者的做法是,一般都安装一个虚拟机,把编译好的sys文件放到虚拟机中运行。这样,即使操作系统崩溃,也不会导致自己手忙脚乱。

请去VMware的官方主页上下载VMware的30天免费试用版本。官方网站网址如下:

http://www.vmware.com/download/ws/

官方网站不一定始终提供试用版本下载。如果已经无法找到的话,读者可以自己搜索,一定有其他软件下载网站提供。

没有使用过虚拟机的读者可能觉得很有意思,因为在自己的Windows XP系统上又运行了另一个Windows XP系统(也可以运行其他系统,比如Linux),就好像有了两台计算机一样。

打开VMware之后,选择“文件”→“新建虚拟机”,然后按照向导操作即可。用于调试的虚拟机和一般的虚拟机没什么区别,读者需要Windows XP的安装光盘,像安装普通计算机一样在虚拟机上安装Windows XP。

安装完毕之后,碰到的另一个问题可能是如何从外面(本机)将文件拷贝到虚拟机中。这有很多方法,其中一种方法是让虚拟机也正常上网,这样两台计算机之间可以用网络邻居访问。

另一种方法是可以从外面用鼠标直接将文件拖到虚拟机中,或者从里面拖到外面。这个操作类似于段誉的六脉神剑,强大但是时灵时不灵。

还有一种方法是选择“编辑该虚拟机设置”,然后选择“Options”。在左边选中“Shared Folders”,在右边增加一个共享目录,这个目录在本机上。选中之后,在虚拟机中也可以访问这个目录,但是访问的方法比较离奇:必须在虚拟机的“我的电脑”中输入“\\.host”,按回车键后才能看见外面共享的目录。

1.3 调试内核模块

1.3.1 下载和安装WinDbg

能够调试Windows内核模块的调试工具不多,其中一个选择是微软提供的WinDbg。这个工具的下载地址如下:

http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx

这个工具似乎是Windows的御用调试工具,不但可以调试内核,也可以调试应用程序。但是它调试内核时,被设计为双机调试,需要另一台计算机(下面称之为调试机)来调试被调试的计算机(下面称之为被调试机)。WinDbg必须安装在调试机上,调试机与被调试机通过串口相连接。请读者按照上面的地址下载WinDbg并安装在调试机上。

除了WinDbg之外,Softice也可以调试内核,并且可以进行单机调试。但是,由于这个工具已经停止升级,因此本书就不做介绍了。

此外,吴岩峰等人开发的Syser也是一种可以进行单机调试内核的调试器,而且是100%的国产,有兴趣的读者可以自己下载研究。

在没有两台计算机的情况下,在调试机上安装一个虚拟机,在虚拟机内安装一个操作系统作为被调试机也是一个不错的选择。本书以此为例子进行讲解。

下载WinDbg后,直接双击安装包执行安装即可。1.3.2 设置Windows XP调试执行

安装好虚拟机之后,必须把这个虚拟机上的Windows设置为调试执行。在被调试系统为Windows 2000、2003或者XP的情况下,打开虚拟机中Windows的系统盘,在文件夹选项中设置为显示所有文件,不隐藏系统保护的文件,然后可以在系统盘下看到一个boot.ini文件。

将最后一行复制一下,并加上新的参数使之以调试方法启动。修改结果如下:

保存这个.ini文件(这个文件若无法保存,请用鼠标右键单击这个文件,选择“属性”,然后取消勾选“只读”),重启系统,在启动时就可以看到菜单,可以进入正常的Windows XP,也可以进入Debug模式的Windows XP。1.3.3 设置Vista调试执行

下面是Vista及以后系统的情况。这里以Vista系统为例(Windows 7以及Windows 8与Vista的配置方式相同)。Vista已经不再使用boot.ini文件了,而是在Vista启动之后,打开控制台(在“运行”中输入“cmd”并按回车键,如果打开了UAC,则需要以管理员身份运行cmd),首先输入:

这会显示一段眼花缭乱的帮助文字,不管能看懂多少,请先了解一下。然后我们需要列举出现在本机上所有“操作系统加载器”的情况,请输入:

如果是刚刚安装的Vista,一般只有一个标识为{current}的OSLOADER,这就是当前的启动配置。现在所需要的是建立一个新的启动配置,从完全空白开始建立非常麻烦,拷贝是一个简单的方案。

拷贝之后会提示已经建立了一个新的配置。新配置标识非常长,是一个GUID字符串。要设置新的配置简直是一个噩梦(每次都要设法输入那个GUID字符串),但是幸好设置当前配置不需要输入配置标识。输入以下两条指令即可:

输入结束之后,还可以输入一条指令看一下当前的调试配置:

一般来说,会显示出使用的第一个串口,波特率为115200bps,和期望的一致,所以不需要修改。最后指定选择菜单的超时,太长(30秒)在无人启动时会太慢,太短则在试图选择时下手不及。笔者觉得7秒非常合适:

然后重新启动,原来的配置就是调试模式了。如果不进入调试模式,那么选择“Windows Vista Copy”进入即可。WinDbg和VMware上的配置不需要修改,和调试Windows XP的情况完全相同。1.3.4 设置VMware的管道虚拟串口

调试机与被调试机用串口相连,但是在被调试机是虚拟机的情况下,就不可能用真正的串口来连接了。但是可以在虚拟机上生成一个用管道虚拟的串口。

用VMware打开所建立的虚拟机,但是不要启动。按以下的步骤操作:(1)在左边的“Commands”栏中单击“Edit virtual machine settings”,出现Hardware页,单击下面的“Add”按钮,出现Add Hardware Wizard,单击“下一步”按钮。(2)“Hardware types”选择“Serial Port”(串口),单击“下一步”按钮。(3)选择“Output to named pipe”,单击“下一步”按钮。(4)这时有3个框可以选择:前2个保持默认,分别为“\\.\pipe\com_1”和“This end is the server.”,第3个修改为“The other end is an application.”(注:最新版的VMware和这个默认不同,第2个为“this end is the client.”,第3个为“this other end is an application.”,请读者随机应变),然后单击“完成”按钮即可。设置好之后可以看到的效果如图1-9所示。图1-9 设置VMware虚拟机使用虚拟串口

虚拟机这样设置就可以了,下面是调试机上WinDbg的启动参数,使之连接一个管道,并把这个管道当作一个串口来处理:

上面的命令是在控制台(cmd窗口)执行的,在执行之前必须先用“cd”命令进入windbg.exe所在的路径。更简单的做法是,在桌面上建立一个windbg.exe的快捷方式,单击右键并选择“属性”,在“快捷方式”选项卡中,在“目标”中的“…windbg.exe”后增加前面的启动参数。注意:windbg.exe的全路径一般是用双引号引住的,但是后面的命令行参数应该放在引号外。

打开虚拟机,启动到调试模式下的Windows之后,马上在命令行中输入上面的命令来启动windbg.exe,或者用快捷方式打开WinDbg,就可以开始调试了。windbg.exe会显示连接上的信息。

以上的方案最早出自国外的论坛,感谢jiurl将它翻译成中文,从而得以在国内被广泛使用。

刚刚连接上的时候,虚拟机里的Windows系统会被中断,貌似死机,这时,请在WinDbg的命令提示符“kd>”后面输入“g”并按回车键。1.3.5 设置Windows内核符号表

现在虚拟机里的操作系统进入了调试模式,那么怎样调试之前编译的first呢?实际上,没有必要告诉WinDbg需要调试的是first,WinDbg把内核视为一个整体,我们只要告诉它代码的路径和符号表的路径就可以了。

在调试连接上之后,打开WinDbg的主菜单“File”下的“Symbol File Path”,在这里输入符号表位置。符号表和sys文件产生在同一个目录下,所以只要指定本机上编译结果所在的objchk_wxp_x86\i386目录就可以了。

如果有多个驱动需要调试,那么可以指定多个路径,路径之间用分号分隔。

此外,需要指定Windows的内核符号表。Windows的每一个sys文件都有自己的符号表,这些符号表需要从网上下载,但是没有必要自己去下载。可以在“Symbol File Path”中增加如下一条设置,用分号与其他路径隔开:

这条设置使WinDbg自动用HTTP协议从微软的网站上下载所需要的符号表。首次使用会使WinDbg变得极慢,接近死机,但是没有关系,实际上,WinDbg正在下载符号表,可以打开c:\symbols查看,这个路径也可以指定为其他的位置。

请注意,下载并不一定总是成功。如果发现符号表并没有下载下来,请多试几次。笔者有时也试过多次才成功。

下载完成后执行就很快了。读者可以在调试过程中看见微软提供的所有的函数名,也可以随时查看调用栈。

如果调试时总是看不见可懂的函数名,这是符号表设置问题,请正确设置参数并保持网络畅通。

下面是用WinDbg开始调试虚拟机的情形,如图1-10所示。图1-10 用WinDbg开始调试虚拟机的情形1.3.6 实战调试first

下面来实战调试一下前面已经编译过的first。请读者按照前面几个小节的介绍准备并设置好虚拟机和WinDbg,然后编译本机上的第一个内核模块first。注意:在此之前要做的工作是把由本机编译好的first所在的objchk_wxp_x86\i386文件夹中的first.sys拷贝到虚拟机中,在虚拟机中用srvinstw.exe把first.sys按照1.2.1节介绍成功安装在虚拟机中。

现在请启动虚拟机里的操作系统,并使之与WinDbg连接调试。当WinDbg断下来时,输入“g”并按回车键,使之继续运行,直到Windows启动完毕。

笔者的WinDbg符号表路径设置如下:

笔者的源代码路径设置如下:

请注意,这是和笔者的工程路径相关的。读者自己调试时应该换成自己的工程所在的路径。

first这个驱动什么事情都没有做,所以加载之后DriverEntry会被执行一次,之后就只有卸载时会执行DriverUnload了。这样就没什么可以调试了,为此只能在DriverEntry中设置一个断点。

在驱动加载之前,设置断点不方便,所以笔者手工在DriverEntry中加入一个断点如下:

这里的int 3是一条汇编指令,执行到它的时候程序会断下来,等于手工设置了一个断点。但是这样的代码如果不是调试状态执行就会直接蓝屏,所以加上宏DBG测试,保证只有调试版本这条语句才被编译。这是一个非常有用的技巧。

重新编译,并把first.sys拷贝到虚拟机里,按照前面介绍过的方法执行。如果WinDbg设置正确,那么马上就会弹出断点,效果如图1-11所示。图1-11 调试first.sys出现的第一个断点

断点弹出后,就可以设置新的断点,同时可以打开Watch窗口观察和修改所有变量的值。设置断点、单步进入和单步前进等操作都和VC是一样的,请读者打开菜单多尝试几次。笔者常用的操作如下:(1)在“kd>”后输入“g”后按回车键,能使中断的程序继续执行。(2)选择菜单“Debug”→“Break”使当前被调试系统中断下

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载