首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

驱动入门实战演练-在驱动上实现自己的CopyFile

2013-02-24 
驱动入门实战演练--在驱动下实现自己的CopyFile一、一些废话第一篇驱动类的博文,希望大家多多支持~!入门驱

驱动入门实战演练--在驱动下实现自己的CopyFile

   

一、一些废话

  第一篇驱动类的博文,希望大家多多支持~!

  入门驱动不久,感觉这一阶段还是遇到了挺多困难,看书的过程中书本上的知识多多少少会和亲身实践有差别,尤其是进到R0级后不再像R3下能那么'为所欲为'了,细节方面的东西特别多,而且一不小心就给蓝了,还好调试时在虚拟机下,鼠标点两下就能重启。其实驱动说难也难,说简单也简单,多动动手,多码几个字,多瞄两眼,熟悉了也就不难了。

  废话不多说,先推荐些Windows驱动入门必备利器:

  1.《天书夜读》Windows驱动编程基础教程  想要快速入门,这个当之无愧。

  2.《从汇编语言到Windows内核编程》  很经典的一本书,本文就是在其基础上写成的(个人很喜欢的一本书)

  3.《寒江独钓 Windows内核安全编程》.(谭文等)  相当不错的一本驱动入门书籍

  4.  竹林蹊径:深入浅出Windows驱动开发   这本书个人觉得不如前几本好,跳跃性有点大

  

  本文的目的是通过实现驱动下的CopyFile熟悉驱动编程。

  关键词: 驱动(内核)编程   内核字符串   应用层与驱动的通信   IRP请求  


二、前缀知识
  在上代码前让我们先快速回顾下驱动基础知识。①、驱动环境搭建  网上关于驱动环境搭建的教程已有很多,而且也并不复杂,无论是xp还是win7都有很好的教程,这里就不再重复了。  我搭建的驱动环境是: 主机--win7 64位  wdk vs2008  虚拟机--xp wdk vs2008,使用windbg双机调试 ②、Windbg常用命令  windbg是在windows平台下,强大的用户态和内核态调试工具。相比较于VS,它是一个轻量级的调试工具,所谓轻量级指的是它的安装文件大小较小,但是其调试功能,却比VS更为强大。它的另外一个用途是可以用来分析dump数据。 由于windbg命令很多,而在一般调试中很多都不会用到,这里仅仅介绍一些最基本也是最常用的一些命令
 最常用的一些命令如下:  dv  -- 查看局部变量             dv /i    --查看局部变量, 并显示符号的类型和参数类型 bl   -- 查看所有断点             bc*      --清除所有断点 bu FileName!Function                  --下延迟断点 bp FileName!Function  /  bp +地址    --设置条件断点
③、内核中的UNICODE_STRING  出于对安全的考虑,在驱动中几乎是UNICODE_STRING的天下,UNICODE_STRING是结构体类型,具体结构如下:
VOID   InitializeObjectAttributes(    OUT POBJECT_ATTRIBUTES  InitializedAttributes, //被初始化的OBJECT_ATTRIBUTES结构体    IN PUNICODE_STRING  ObjectName, //如果是操作文件则为文件名    IN ULONG  Attributes,     IN HANDLE  RootDirectory, //相对目录    IN PSECURITY_DESCRIPTOR  SecurityDescriptor    );
  主要内容已经注释,这里有一定要特别注意: 在内核中文件路径不能像在应用层那样 写"C:\\aa.txt" 而是写成"\\??\\C:\\aa.txt" 或 "\\DosDevices\\C:\\aa.txt" ,因为在内核中使用对象路径,"C:\\"只是一个符号链接对象(仅仅对用户而言有意义),链接对象一般都在\\??\\ (也可写成\\DosDevices\\) 所以在内核中要写完整的对象路径。


⑤、使用DeviceIoControl与驱动交互  说到驱动与应用层的交互当然不能不提IRP(I/O Request Package),相当于R3层的消息,与消息的消息处理函数对应,IRP也有相应的处理例程(驱动下可以简单认为例程就是函数啦)。不同IRP当然就该有不同的标示符,这个标示符就是IRP的“控制码”,我们也可以自定义控制码,定义控制码方法如下:
#include <stdio.h>#include <Windows.h>//用户自定义控制码 用于和应用层的通信#define MYCOPYFILE_CODE \(ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,\0xa01,METHOD_BUFFERED,FILE_READ_DATA|FILE_WRITE_DATA)typedef struct mymessage{PWSTR SourceFileName;PWSTR DestinFileName;}MyMessage,*PMyMessage;int main(){BOOL ret;DWORD length=0;MyMessage input_buffer;//用CreateFile打开驱动HANDLE device=CreateFileW(L"\\\\.\\MyCF", //应用层应写成这种形式GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);if (device==INVALID_HANDLE_VALUE){printf("open device error!  %d",GetLastError());system("pause");return -1;}//填写自定义bufferinput_buffer.DestinFileName=L"D:\\MyCopyFile.txt";input_buffer.SourceFileName=L"D:\\output.txt";printf("%d",sizeof(input_buffer)); ret=DeviceIoControl(device,MYCOPYFILE_CODE,//我们自定义的控制码(PVOID)&input_buffer,//输入缓冲区sizeof(input_buffer),NULL,//没有输出缓冲区0,//输出缓冲区的长度&length,NULL);if (!ret){printf("Device IO error!");return -2;}CloseHandle(device);system("pause");return 0;}



四、总结  本文通过实现驱动下的CopyFile让大家熟悉了驱动下的基本操作。驱动编程只有自己实际动手写写才会知道自己错在哪,其实IT行业也就是这样,多动手比只看出好得多,毕竟“绝知此事要躬行”啊!  本文仅仅是驱动编程的冰山一脚,另外本人能力有限,也是初学驱动,难免有些遗漏及不足之处,还请大家多多指教!



热点排行