五、 在驱动中读写文件

五、
在驱动中读写文件
对文件的读写操作一直是程序开发人员需要熟练掌握的内容,在ring3我们可以使用CreateFile、ReadFile、WriteFile等API,在ring0同样很相似,不过函数变成了ZwCreateFile、ZwReadFile、ZwWriteFile等内核函数。
5.1 使用OBJECT_ATTRIBUTES
ZwCreateFile与ring3的CreateFile函数有所不同,它不能直接将需要打开或创建的文件路径传递过去,我们必须首先填写一个OBJECT_ATTRIBUTES结构,这个结构在内核中被广泛使用,例如后面我们将要介绍的操作注册表函数也会用到它。
这个结构很容易使用,初始化后就可以使用了,初始化过程如下所示:
UNICODE_STRINGstr;
OBJECT_ATTRIBUTESobj_attrib;
RtlInitUnicodeString(&str,L"\\??\\C:\\windows\\notepad.exe");
InitializeObjectAttributes(&obj_attrib,
&str, // 需要操作的对象、比如文件或注册表路径等
Windows 下设备驱动程序的开发方法 2120080411 计算机应用 赖锡盛
16
OBJ_CASE_INSENSITIVE| OBJ_KERNEL_HANDLE,
NULL,
NULL);
第三个参数OBJ_CASE_INSENSITIVE表示不区分大小写,OBJ_KERNEL_HANDLE表示将要打开的句柄为内核句柄。
内核句柄比起应用层句柄有很多的好处,例如它可以不受进程或线程的限制,而且在需要打开一个内核句柄时不需要考虑当前是否有权限访问该文件的问题。
5.2 创建、打开文件
创建和打开文件都可使用ZwCreateFile函数,它的第一个参数将返回一个文件句柄,所有后续操作都可以通过这个句柄完成,在操作结束后,需要调用ZwClose关闭句柄。
ZwCreateFile函数的第三个参数就是使用我们此前填写的OBJECT_ATTRIBUTES结构;它返回的信息通过第四个IO_STATUS_BLOCK返回;第八、九个参数联合指明了如何打开或创建文件,详细用法请参考DDK帮助文档或Google查询。
其中IO_STATUS_BLOCK的定义如下所示:
typedefstruct_IO_STATUS_BLOCK{
NTSTATUS Status;
ULONG Information;
}IO_STATUS_BLOCK,*PIO_STATUS_BLOCK;
其中Status指明了函数的执行结果,如果执行成功它的值将是STATUS_SUCCESS,否则它将会是一个形如STATUS_XXX的错误提示。
此外,DDK还提供了一个函数ZwOpenFile用来简化打开文件的操作,它所需要的参数比ZwCreateFile更加简洁,使用更加简单。
5.3 读写文件操作
在内核中读写文件与用户模式下十分相似,它们分别使用ZwReadFile和
Windows 下设备驱动程序的开发方法 2120080411 计算机应用 赖锡盛
17
ZwWriteFile函数完成。
这两个函数的参数大抵相同,因此我们这里只对ZwReadFile的参数作简单介绍,该函数的原型如下所示:
NTSTATUS
ZwReadFile(
INHANDLE FileHandle,
INHANDLE Event OPTIONAL,
INPIO_APC_ROUTINE ApcRoutine OPTIONAL,
INPVOID ApcContext OPTIONAL,
OUTPIO_STATUS_BLOCK IoStatusBlock,
OUTPVOID Buffer,
INULONG Length,
INPLARGE_INTEGER ByteOffset OPTIONAL,
INPULONG Key OPTIONAL);
各参数的简要介绍如下所示:
FileHandle:函数ZwCreateFile返回的句柄。如果它是一个内核句柄,则ZwReadFile和ZwCreateFile并不需要在同一个进程中,因为内核句柄是各进程通用的。
Event :一个事件,用于异步完成读时;我们忽略这个参数。
ApcRoutineApc:回调例程,用于异步完成读时;我们忽略这个参数。
IoStatusBlock:返回结果状态,与ZwCreateFile中的同名参数相同。
Buffer:缓冲区,如果读取文件的内容成功,则内容将被读取到这里。
Length:描述缓冲区的长度,即试图读取文件的长度。
ByteOffset:要读取的文件的偏移量,也就是要读取的内容在文件中的位置。一般来说,不要将其设置为NULL,文件句柄不一定支持直接读取当前偏移。
Key:读取文件时用的一种附加信息,一般不使用。
当函数执行成功时返回STATUS_SUCCESS,实际上只要能够读取到任意字节的数据(不管它是否符合参数Length的要求),都返回成功;但是,如果仅读取文件长度之外的部分,则返回STATUS_END_OF_FILE。
ZwWriteFile的参数与ZwReadFile基本相同,不再进行介绍。
Windows 下设备驱动程序的开发方法 2120080411 计算机应用 赖锡盛
18
5.4 文件的其它相关操作
除了上述介绍过的一些函数,DDK还提供了一些函数用以文件操作。
ZwQueryInformationFile、ZwSetInformationFile可以分别用来获取和设置文件属性,包括文件大小、文件指针位置、文件属性(如只读、隐藏)、文件创建/修改日期等。
这两个函数的参数基本完全相同,只是功能不完全相同而已,因此这里我们仅以ZwSetInformationFile函数为例进行介绍,这个函数的原型声明如下所示:
NTSTATUS
ZwSetInformationFile(
INHANDLE FileHandle,
OUTPIO_STATUS_BLOCK IoStatusBlock,
INPVOID FileInformation,
INULONG Length,
INFILE_INFORMATION_CLASS FileInformationClass
);
第一、二、四个参数就不介绍了,相信大家都应该能猜到,下面我们仅重点介绍说明FileInformationClass这个参数,FileInformationClass指定修改或查询的类别。
在内核模式下操作文件的函数不像用户模式下那样丰富,想复制文件就调用CopyFile、想删除文件就调用DeleteFile等,在内核模式下除了读写文件的其他所有操作都是通过这两个ZwQueryInformation和ZwSetInformationFile函数完成的,而如何使这两个函数精确完成我们需要的功能,就需要通过FileInformationClass参数来指定。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值