欢迎来到天天文库
浏览记录
ID:37463150
大小:85.50 KB
页数:24页
时间:2019-05-24
《Windows驱动编程入门》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、Windows驱动编程入门1前言 我经常在网上遇到心如火燎的提问者。他们碰到很多工作中的技术问题,是关于驱动开发的。其实绝大部分他们碰到的“巨大困难”是被老牛们看成初级得不能再初级的问题。比如经常有人定义一个空的UNICODE_STRING,然后往里面拷贝字符串。结果无论如何都是蓝屏。也有人在堆栈中定义一个局部SPIN_LOCK,作为下面的同步用——这样用显然没有任何意义。我无法一一回答这些问题:因为往往要耐心的看他们的代码,才能很不容易的发现这些错误。而且我又不是总是空闲的,可以无休止的去帮网友阅读代码和查找初级错误。但是归根结底,这些问题的出现,
2、是因为现在写驱动的同行越来越多,但是做驱动开发又没有比较基础的,容易读懂的资料。为此我决定从今天开始连载一篇超级入门级的教程,来解决那些最基本的开发问题。老牛们就请无视这篇教程,一笑而过了。Windows驱动编程基础教程(1.1-1.3)1.1使用字符串结构 常常使用传统C语言的程序员比较喜欢用如下的方法定义和使用字符串: char *str={“myfirststring”}; //ansi字符串 wchar_t *wstr={L”myfirststring”}; //unicode字符串 size_tlen=strlen
3、(str); //ansi字符串求长度 size_twlen=wcslen(wstr); //unicode字符串求长度 printf(“%s%ws%d%d”,str,wstr,len,wlen); //打印两种字符串 但是实际上这种字符串相当的不安全。很容易导致缓冲溢出漏洞。这是因为没有任何地方确切的表明一个字符串的长度。仅仅用一个’ ’字符来标明这个字符串的结束。一旦碰到根本就没有空结束的字符串(可能是攻击者恶意的输入、或者是编程错误导致的意外),程序就可能陷入崩溃。 使用高级C++特性的编码者则容易忽略这
4、个问题。因为常常使用std::string和CString这样高级的类。不用去担忧字符串的安全性了。 在驱动开发中,一般不再用空来表示一个字符串的结束。而是定义了如下的一个结构: typedefstruct_UNICODE_STRING{ USHORTLength; //字符串的长度(字节数) USHORTMaximumLength; //字符串缓冲区的长度(字节数) PWSTR Buffer; //字符串缓冲区 }UNICODE_STRING,*PUNICODE_STRING; 以上是Uni
5、code字符串,一个字符为双字节。与之对应的还有一个Ansi字符串。Ansi字符串就是C语言中常用的单字节表示一个字符的窄字符串。 typedefstruct_STRING{ USHORTLength; USHORTMaximumLength; PSTRBuffer; }ANSI_STRING,*PANSI_STRING; 在驱动开发中四处可见的是Unicode字符串。因此可以说:Windows的内核是使用Uincode编码的。ANSI_STRING仅仅在某些碰到窄字符的场合使用。而且这种场合非常罕见。UNICODE_STRING
6、并不保证Buffer中的字符串是以空结束的。因此,类似下面的做法都是错误的,可能会会导致内核崩溃: UNICODE_STRINGstr; … len=wcslen(str.Buffer); //试图求长度。 DbgPrint(“%ws”,str.Buffer); //试图打印str.Buffer。 如果要用以上的方法,必须在编码中保证Buffer始终是以空结束。但这又是一个麻烦的问题。所以,使用微软提供的Rtl系列函数来操作字符串,才是正确的方法。下文逐步的讲述这个系列的函数的使用。1.2字符串的初始化 请回顾之前的UN
7、ICODE_STRING结构。读者应该可以注意到,这个结构中并不含有字符串缓冲的空间。这是一个初学者常见的出问题的来源。以下的代码是完全错误的,内核会立刻崩溃: UNICODE_STRINGstr; wcscpy(str.Buffer,L”myfirststring!”); str.Length=str.MaximumLength=wcslen(L”myfirststring!”)*sizeof(WCHAR); 以上的代码定义了一个字符串并试图初始化它的值。但是非常遗憾这样做是不对的。因为str.Buffer只是一个未初始化的指针。它并没有指
8、向有意义的空间。相反以下的方法是正确的: //先定义后,再定义空间UNICOD
此文档下载收益归作者所有