梦织未来Windows驱动编程 第06课 驱动对磁盘文件的操作
代码部分:
实现一个文件C:\\text.txt,并读取写入内容到文件,然后将文件设置为只读,并隐藏文件。代码如下:
//MyCreateFile.c
//2016.07.22
#include <ntddk.h> NTSTATUS MyCreateFile()
{
HANDLE hFile; NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING usFileName;
OBJECT_ATTRIBUTES FileObjAttr;
IO_STATUS_BLOCK IoStatusBlock; memset (&FileObjAttr, , sizeof(OBJECT_ATTRIBUTES)); RtlInitUnicodeString (&usFileName, L"\\??\\c:\\test.txt");
InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); //OBJ_CASE_INSENSITIVE 大小写不敏感 Status = ZwCreateFile (&hFile,
GENERIC_ALL,
&FileObjAttr,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF, //如果没有文件,创建文件。如果有文件,直接打开
FILE_NON_DIRECTORY_FILE, //不是目录
NULL,
);
if (!NT_SUCCESS(Status))
{
return Status;
} KdPrint(("Create File Success!")); ZwClose (hFile); return Status;
} NTSTATUS MyOpenFile()
{
HANDLE hFile; UNICODE_STRING usFileName;
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES FileObjAttr;
IO_STATUS_BLOCK IoStatusBlock; RtlInitUnicodeString (&usFileName, L"\\??\\c:\\test.txt");
memset (&FileObjAttr, , sizeof(OBJECT_ATTRIBUTES)); InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenFile(&hFile,
GENERIC_ALL,
&FileObjAttr,
&IoStatusBlock,
FILE_SHARE_READ,
FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(Status))
{
KdPrint(("Open File Failed:0x%X", Status));
return Status;
} KdPrint(("Open File Success!")); ZwClose(hFile); return Status;
} NTSTATUS MyZwSetInfomationFile()
{
HANDLE hFile; UNICODE_STRING usFileName;
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES FileObjAttr;
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION fbi; RtlInitUnicodeString (&usFileName, L"\\??\\c:\\test.txt");
memset (&FileObjAttr, , sizeof(OBJECT_ATTRIBUTES)); InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenFile(&hFile,
GENERIC_ALL,
&FileObjAttr,
&IoStatusBlock,
FILE_SHARE_READ,
FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(Status))
{
KdPrint(("Open File Failed:0x%X", Status));
return Status;
} KdPrint(("Open File Success!")); Status = ZwQueryInformationFile (hFile, &IoStatusBlock, &fbi, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); //查看FileBasicInformation
if (!NT_SUCCESS(Status))
{
KdPrint(("Query Information Error code: %X", Status));
ZwClose (hFile);
return Status;
} KdPrint(("CreationTime:0x%X Attributes:0x%X", fbi.CreationTime, fbi.FileAttributes));
fbi.FileAttributes |= FILE_ATTRIBUTE_HIDDEN; //隐藏文件
fbi.FileAttributes |= FILE_ATTRIBUTE_READONLY; //只读属性 Status = ZwSetInformationFile (hFile, &IoStatusBlock, &fbi, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation);
if (!NT_SUCCESS(Status))
{
KdPrint(("Set Information Error:0x%X", Status));
ZwClose(hFile);
return Status;
} ZwClose(hFile); return Status;
} NTSTATUS MyReadFile()
{
HANDLE hFile; UNICODE_STRING usFileName;
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES FileObjAttr;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER ReadBuffer; char strBuffer[] = {}; RtlInitUnicodeString (&usFileName, L"\\??\\c:\\test.txt");
memset (&FileObjAttr, , sizeof(OBJECT_ATTRIBUTES)); InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenFile(&hFile,
GENERIC_ALL,
&FileObjAttr,
&IoStatusBlock,
FILE_SHARE_READ,
FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(Status))
{
KdPrint(("Open File Failed:0x%X", Status));
return Status;
} KdPrint(("Open File Success!"));
ReadBuffer.QuadPart = ; Status = ZwReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, (PVOID)strBuffer, , &ReadBuffer, NULL); //从文件的0位置读取16个字节到strBuffer
if (!NT_SUCCESS(Status))
{
KdPrint(("ReadFile Failed, Error Code:0x%X", Status));
ZwClose(hFile);
return Status;
} KdPrint(("strBuffer:<%s>", strBuffer)); ZwClose(hFile);
return Status;
} NTSTATUS MyWriteFile()
{
HANDLE hFile; UNICODE_STRING usFileName;
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES FileObjAttr;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER WriteBuffer; char strBuffer[] = "ahuakndkaj.;'?"; RtlInitUnicodeString (&usFileName, L"\\??\\c:\\test.txt");
memset (&FileObjAttr, , sizeof(OBJECT_ATTRIBUTES)); InitializeObjectAttributes(&FileObjAttr, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwOpenFile(&hFile,
GENERIC_ALL,
&FileObjAttr,
&IoStatusBlock,
FILE_SHARE_READ,
FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(Status))
{
KdPrint(("Open File Failed:0x%X", Status));
return Status;
} KdPrint(("Open File Success!")); WriteBuffer.QuadPart = ; Status = ZwWriteFile(hFile, NULL, NULL, NULL, &IoStatusBlock, (PVOID)strBuffer, , &WriteBuffer, NULL); //将strBuffer中的前16个字节写入文件,从文件的0位置开始写
if (!NT_SUCCESS(Status))
{
KdPrint(("WriteFile Failed, Error Code:0x%X", Status));
ZwClose(hFile);
return Status;
} ZwClose(hFile);
return Status;
} VOID MyUnload(PDRIVER_OBJECT pDriverObject)
{
KdPrint(("Unload MyCreateFile.sys Success"));
} NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
pDriverObject->DriverUnload = MyUnload; MyOpenFile();
MyCreateFile();
MyOpenFile(); MyReadFile();
MyWriteFile();
MyReadFile(); MyZwSetInfomationFile(); return STATUS_SUCCESS;
}
MyCreateFile.c
文件的操作函数有:
ZwCreateFile //创建文件或者打开文件
ZwOpenFile //打开文件
ZwQueryInformationFile //查看文件信息
ZwSetInformationFile //设置文件信息
ZwReadFile //读取文件
ZwWriteFile //写入文件
创建或打开文件ZwCreateFile:
NTSTATUS ZwCreateFile(
_Out_ PHANDLE FileHandle, //文件句柄
_In_ ACCESS_MASK DesiredAccess, //访问权限,一般为GENERIC_ALL,即所有权限
_In_ POBJECT_ATTRIBUTES ObjectAttributes, //文件对象的属性,需要用InitializeObjectAttributes来初始化
_Out_ PIO_STATUS_BLOCK IoStatusBlock, //用于接收返回信息
_In_opt_ PLARGE_INTEGER AllocationSize,
7 _In_ ULONG FileAttributes, //FILE_ATTRIBUTE_NORMAL
_In_ ULONG ShareAccess, //FILE_SHARE_READ
_In_ ULONG CreateDisposition, //FILE_OPEN_IF 如果没有文件,创建文件。如果有文件,直接打开
_In_ ULONG CreateOptions, //FILE_NON_DIRECTORY_FILE 不是目录
_In_opt_ PVOID EaBuffer, //NULL
_In_ ULONG EaLength //
);
其中的第三个参数ObjectAttributes需要使用函数InitializeObjectAttributes来初始化,函数参数:
VOID InitializeObjectAttributes(
[out] POBJECT_ATTRIBUTES InitializedAttributes, //文件对象指针
[in] PUNICODE_STRING ObjectName, //文件路径及名称
[in] ULONG Attributes, //flag,一般是OBJ_CASE_INSENSITIVE(大小写不敏感)
[in] HANDLE RootDirectory, //根目录,如果ObjectName是绝对路径的话,那么根目录就是NULL
[in, optional] PSECURITY_DESCRIPTOR SecurityDescriptor //默认为NULL
);
打开文件函数ZwOpenFile:
NTSTATUS ZwOpenFile(
_Out_ PHANDLE FileHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ ULONG ShareAccess,
_In_ ULONG OpenOptions //和ZwCreateFile的CreateOptions参数相同. FILE_NON_DIRECTORY_FILE 不是目录
);
获取文件属性函数ZwQueryInformationFile:
NTSTATUS ZwQueryInformationFile(
_In_ HANDLE FileHandle,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_Out_ PVOID FileInformation, //接收文件相应FileInformationClass信息的结构
_In_ ULONG Length, //FileInformation的大小
_In_ FILE_INFORMATION_CLASS FileInformationClass //指定获取文件什么信息(FileInformation)的枚举值
);
设置文件属性函数ZwSetInformationFile:
NTSTATUS ZwSetInformationFile(
_In_ HANDLE FileHandle,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ PVOID FileInformation,
_In_ ULONG Length,
_In_ FILE_INFORMATION_CLASS FileInformationClass
);
读取文件函数ZwReadFile:
NTSTATUS ZwReadFile(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_Out_ PVOID Buffer, //保存读取到的
_In_ ULONG Length, //从文件读取多少个字节
_In_opt_ PLARGE_INTEGER ByteOffset, //从文件的哪个位置开始读取,传入一个LARGE_INTEGER的指针
_In_opt_ PULONG Key //NULL
);
写入文件函数ZwWriteFile:
NTSTATUS ZwWriteFile(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ PVOID Buffer,
_In_ ULONG Length,
_In_opt_ PLARGE_INTEGER ByteOffset,
_In_opt_ PULONG Key
);
有些地方可能现在还不太清楚,以后再回来补吧。
操作部分:
启动并按章MyCreateFile.sys驱动后,C盘生成了test.txt的文件

这个文件是只读的,并且是隐藏的:

test.txt文件中写着“ahuakndkaj.;'? "

DbgView输出:

0. 没有相应文件时,MyOpenFile里 ZwOpenFile打开文件失败
1. MyCreateFile里 ZwCreateFile创建文件成功
2. MyOpenFile里 ZwOpenFile打开文件成功
3. MyReadFile里 ZwOpenFile打开文件成功
4. MyReadFile里 ZwReadFile读取文件失败 这时文件中还没有数据
5. MyWriteFile里 ZwOpenFile打开文件成功 没输出错误 说明ZwWriteFile也成功了
6. MyReadFile里 ZwReadFile读取文件成功
7. MyReadFile里 读取到了数据
8. MyZwQueryInfomationFile里 打开文件成功
9. 获取文件属性成功 没输出错误 说明MyZwSetInfomationFile也成功了
10. 驱动卸载成功
梦织未来Windows驱动编程 第06课 驱动对磁盘文件的操作的更多相关文章
- 梦织未来Windows驱动编程 第03课 驱动的编程规范
最近根据梦织未来论坛的驱动教程学习了一下Windows下的驱动编程,做个笔记备忘.这是第03课<驱动的编程规范>. 驱动部分包括基本的驱动卸载函数.驱动打开关闭读取写入操作最简单的分发例程 ...
- 梦织未来Windows驱动编程 第05课 小结(读取另一驱动,遍历所有驱动)
读取另一驱动 驱动通过"\\Driver\\XueTr"获取到了XueTr工具的驱动,并Hook了XueTr驱动的分发函数. 具体的驱动代码如下: //FilterDriver.c ...
- 梦织未来Windows驱动编程 第04课 驱动相关的数据结构
- 《天书夜读:从汇编语言到windows内核编程》五 WDM驱动开发环境搭建
(原书)所有内核空间共享,DriverEntery是内核程序入口,在内核程序被加载时,这个函数被调用,加载入的进程为system进程,xp下它的pid是4.内核程序的编写有一定的规则: 不能调用win ...
- Linux设备驱动编程之复杂设备驱动
这里所说的复杂设备驱动涉及到PCI.USB.网络设备.块设备等(严格意义而言,这些设备在概念上并不并列,例如与块设备并列的是字符设备,而PCI.USB设备等都可能属于字符设备),这些设备的驱动中又涉及 ...
- (转)Windows驱动编程基础教程
版权声明 本书是免费电子书. 作者保留一切权利.但在保证本书完整性(包括版权声明.前言.正文内容.后记.以及作者的信息),并不增删.改变其中任何文字内容的前提下,欢迎任何读者 以任何形式(包括 ...
- Windows游戏编程之从零开始d
Windows游戏编程之从零开始d I'm back~~恩,几个月不见,大家还好吗? 这段时间真的好多童鞋在博客里留言说或者发邮件说浅墨你回来继续更新博客吧. woxiangnifrr童鞋说每天都在来 ...
- 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
- 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
随机推荐
- 蚂蚁金服HR电话面
1.先自我介绍一下. 2.问到项目问题.(项目介绍,用到哪些技术,如何测试的.) 3.一些基础知识. a) list.map.set是继承了collection的吗? List:1.可以允许重复的对 ...
- Mathematics Base - 期望、方差、协方差、相关系数总结
参考:<深度学习500问> 期望 在概率论和统计学中,数学期望(或均值,亦简称期望)是试验中每次可能结果的概率乘以其结果的总和.它反映随机变量平均取值的大小. 线性运算: \(E(ax+ ...
- sqlserver2012——.Net
1.Connection 属性: ConnectionString:获取或者设置用于打开SQLServer数据库的字符串 Database:获取当前数据库或者连接打开后要使用的数据库名称 State: ...
- window下安装composer步骤(linux待研究)
window下安装composer步骤--注意(安装完之后需要重启电脑才能生效) 转发:https://blog.csdn.net/wengedexiaozao/article/details/798 ...
- MATLAB解决常微分方程
首先得介绍一下,在matlab中解常微分方程有两种方法,一种是符号解法,另一种是数值解法.在本科阶段的微分数学题,基本上可以通过符号解法解决. 用matlab解决常微分问题的符号解法的关键命令是d ...
- 依托http-headers的 sql注入和时间盲注
机缘巧合接触了一点关于sql注入的网络安全问题 依托 headers 的 sql 注入 一般来说大家都很清楚用户输入的危险性,通常会对用户表单提交的数据进行过滤(引号转码). 但是如果写过网络爬虫,那 ...
- 【转至hejinde的专栏】Axure RP 8最新激活码(可用注册码)
Licensee:米 业成 (STUDENT)Key:nFmqBBvEqdvbiUjy8NZiyWiRSg3yO+PtZ8c9wdwxWse4WprphvSu9sohAdpNnJK5 亲测可用
- Hadoop集群配置免密SSH登录方法
Hadoop集群包含1个主节点和3个从节点,需要实现各节点之间的免密码登录,下面介绍具体的实现方法. 一.Hadoop集群环境 二.免密登录原理 每台主机authorized_keys文件里面包含的主 ...
- 继承、super、this、抽象类
继承.super.this.抽象类 继承.super.this.抽象类 继承.super.this.抽象类 继承.super.this.抽象类 继承.super.this.抽象类
- Educational Codeforces Round 48 (Rated for Div. 2) B 1016B Segment Occurrences (前缀和)
B. Segment Occurrences time limit per test 2 seconds memory limit per test 256 megabytes input stand ...