读书人

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

发布时间: 2013-02-24 17:58:56 作者: rapoo

驱动入门实战演练--在驱动下实现自己的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行业也就是这样,多动手比只看出好得多,毕竟“绝知此事要躬行”啊! 本文仅仅是驱动编程的冰山一脚,另外本人能力有限,也是初学驱动,难免有些遗漏及不足之处,还请大家多多指教!



读书人网 >编程

热点推荐