这篇文章 是根据张帆老师 一书 《Windows 驱动开发技术详解》 写出的
买这本书 很久了 一直 都感觉看视频好一些 偶然 翻了这本书 发现真的是神书
然后 先说文件的创建
文件创建 也就是
NTSTATUS ZwCreateFile(
_Out_ PHANDLE FileHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_opt_ PLARGE_INTEGER AllocationSize,
_In_ ULONG FileAttributes,
_In_ ULONG ShareAccess,
_In_ ULONG CreateDisposition,
_In_ ULONG CreateOptions,
_In_opt_ PVOID EaBuffer,
_In_ ULONG EaLength
);
第一个参数 是 返回打开文件的句柄
第二个 是指定的操作 一般是 对文件的描述 读是 GENERIC_READ 然后写的话 是 GENERIC_WRITE
第三个参数 是 OBJECT_ATTRIBUTES的地址 这个结构包含了 要打开的文件名
第四个参数是 指向一个IO_STATUS_BLOCK结构 该结构接收的是 zwcreatfile 的操作结果状态
然后第五个 参数是 一个指针 指向初始文件分配大小如果是0 那么文件长度 从0 开始 并随着 写入而增加
第六个 是 0或者FILE_ATTRIBUFE_NORMAL 指定新创建文件的属性
第七个 指定文件的属性 0 或者FILE_SHARE_READ 指定共享属性
第八个 是 指定文件存在或不存在 怎么处理 FILE_OPEN 就是 打开文件 如果错误 就返回失败 FILE_OVERWRITE_IF
第九个是 指定 控制打开的操作 一般是FILE_SYNCHRONOUS_IO_NONALERT
第十个是 一个指针 可以指向 可选的扩展属性区
第十一个 是扩展属性区的长度
然后根据 第三个长度 可以 用 initializeObjectAttributes 来初始化
然后文件的打开 可以用上面的 也可以用 zwopenfile 参数的话 就不一一介绍了
可以用 zwsetinformationfile 来获取文件属性 可以用 zwquertinformationfile 来修改文件属性
然后也可以用文件写的话 可以用 ZwWritefile 然后 读的话 可以用 zwreadfile
然后下面就是代码实例
#include<ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT driver)
{
KdPrint(("驱动开始卸载!"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
OBJECT_ATTRIBUTES object;
IO_STATUS_BLOCK io;
HANDLE hfile;
UNICODE_STRING log;
//初始化字符串
RtlInitUnicodeString(&log, L"\\??\\C:\\1.log");
//初始化objectattributes
InitializeObjectAttributes(&object, &log, OBJ_CASE_INSENSITIVE, NULL, NULL);
//创建文件
NTSTATUS NT = ZwCreateFile(&hfile,
GENERIC_WRITE,
&object,
&io,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
//如果第二个参数 换成GENERIC_READ 第八个参数 换成 FILE_OPEN 的话 那么这个就是打开程序了
if (NT_SUCCESS(NT))
{
KdPrint(("文件创建成功!"));
}
else
{
KdPrint(("文件创建失败!"));
}
ZwClose(hfile);
}
然后下面的话 是 ZwOpenFile
这个其实还是蛮简单的 就注意第二个参数 是打开的权限 一般设为 GENERIC_ALL
然后 我们编写代码 如下
#include<ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT driver)
{
KdPrint(("驱动开始卸载!"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
OBJECT_ATTRIBUTES object;
IO_STATUS_BLOCK io;
HANDLE hfile;
UNICODE_STRING log;
//初始化字符串
RtlInitUnicodeString(&log, L"\\??\\C:\\1.log");
//初始化objectattributes
InitializeObjectAttributes(&object, &log, OBJ_CASE_INSENSITIVE, NULL, NULL);
//创建文件
/* NTSTATUS NT = ZwCreateFile(&hfile,
GENERIC_WRITE,
&object,
&io,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);*/
NTSTATUS NT = ZwOpenFile(&hfile,
GENERIC_ALL,
&object,
&io,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
//如果第二个参数 换成GENERIC_READ 第八个参数 换成 FILE_OPEN 的话 那么这个就是打开程序了
if (NT_SUCCESS(NT))
{
KdPrint(("文件打开成功!"));
}
else
{
KdPrint(("文件打开失败!"));
}
ZwClose(hfile);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
然后下面的是 修改或 获取文件属性 获取 和修改的函数 参数其实差不多 唯一要注意的是 第三个 参数
算是一个输出数据 或者输入数据 里面存储这 有三个不同的结构 根据结构不同 输出的也不同
第一个结构体是 FILEStandardInformation
为文件分配的大小 然后有多少文件链接 是否准备删除 是否为目录
第二个 是FilebasicInformation
文件创建的时间 最后访问时间 最后写时间 修改修改时间 文件属性
第三个是filenameInformation 这个是
文件长度 文件名 。
第四个是FilePositionInformation
里面就有一个当前文件指针的位置
然后 演示 ZwQueryInformationFile 函数 查询 修改文件属性
#include<ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT driver)
{
KdPrint(("驱动开始卸载!"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
OBJECT_ATTRIBUTES object;
IO_STATUS_BLOCK io;
HANDLE hfile;
UNICODE_STRING log;
//初始化字符串
RtlInitUnicodeString(&log, L"\\??\\C:\\1.log");
//初始化objectattributes
InitializeObjectAttributes(&object, &log, OBJ_CASE_INSENSITIVE, NULL, NULL);
//创建文件
NTSTATUS NT = ZwCreateFile(&hfile,
GENERIC_READ,
&object,
&io,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(NT))
{
KdPrint(("文件打开成功!"));
}
else
{
KdPrint(("文件打开失败!"));
ZwClose(hfile);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
FILE_STANDARD_INFORMATION fsi;
NT = ZwQueryInformationFile(hfile,
&io,
&fsi,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (NT_SUCCESS(NT))
{
KdPrint(("file length:%u\n", fsi.EndOfFile.QuadPart));
}
else
{
KdPrint(("获取文件信息失败!"));
}
FILE_POSITION_INFORMATION fpi;
fpi.CurrentByteOffset.QuadPart = 100i64;
NT = ZwSetInformationFile(hfile,
&io,
&fpi,
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation);
if (NT_SUCCESS(NT))
{
KdPrint(("文件指针已经确定!"));
}
ZwClose(hfile);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
下面就是文件的读写操作
直接撸代码把 这里面的参数 都挺简单明了的
#include<ntddk.h>
#define BUFFER_SIZE 1024
VOID DriverUnload(PDRIVER_OBJECT driver)
{
KdPrint(("驱动开始卸载!"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
OBJECT_ATTRIBUTES object;
IO_STATUS_BLOCK io;
HANDLE hfile;
UNICODE_STRING log;
//初始化字符串
RtlInitUnicodeString(&log, L"\\??\\C:\\1.log");
//初始化objectattributes
InitializeObjectAttributes(&object, &log, OBJ_CASE_INSENSITIVE, NULL, NULL);
//创建文件
NTSTATUS NT = ZwCreateFile(&hfile,
GENERIC_WRITE,
&object,
&io,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_WRITE,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(NT))
{
KdPrint(("文件打开成功!"));
}
else
{
KdPrint(("文件打开失败!"));
ZwClose(hfile);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
PUCHAR pbuffer = (PUCHAR)ExAllocatePool(PagedPool, BUFFER_SIZE);//在堆中分配内存
RtlFillMemory(pbuffer, BUFFER_SIZE, 0xaa);
KdPrint(("我们要写入%d字节", BUFFER_SIZE));
ZwWriteFile(hfile, NULL, NULL, NULL, &io, pbuffer, BUFFER_SIZE, NULL, NULL);
KdPrint(("实际写入了%d 字节", io.Information));
RtlFillMemory(pbuffer, BUFFER_SIZE, 0xbb);
KdPrint(("我们要追加写入%d字节", BUFFER_SIZE));
LARGE_INTEGER number;//这个是倒数第二个参数 表示 文件从那里写
number.QuadPart = 1024i64;
ZwWriteFile(hfile, NULL, NULL, NULL, &io, pbuffer, BUFFER_SIZE, &number, NULL);
KdPrint(("这个实际写了%d字节", io.Information));
ZwClose(hfile);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
#include<ntddk.h>
#define BUFFER_SIZE 1024
VOID DriverUnload(PDRIVER_OBJECT driver)
{
KdPrint(("驱动开始卸载!"));
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
OBJECT_ATTRIBUTES object;
IO_STATUS_BLOCK io;
HANDLE hfile;
UNICODE_STRING log;
//初始化字符串
RtlInitUnicodeString(&log, L"\\??\\C:\\1.log");
//初始化objectattributes
InitializeObjectAttributes(&object, &log, OBJ_CASE_INSENSITIVE, NULL, NULL);
//创建文件
NTSTATUS NT = ZwCreateFile(&hfile,
GENERIC_READ,
&object,
&io,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (NT_SUCCESS(NT))
{
KdPrint(("文件打开成功!"));
}
else
{
KdPrint(("文件打开失败!"));
ZwClose(hfile);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
FILE_STANDARD_INFORMATION fsi;
NT = ZwQueryInformationFile(hfile,
&io,
&fsi,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
KdPrint(("这次我们想读%d 字节",fsi.EndOfFile.QuadPart));
PUCHAR pbuffer = (PUCHAR)ExAllocatePool(PagedPool, (LONG)fsi.EndOfFile.QuadPart);//在堆中分配内存
ZwReadFile(hfile,
NULL,
NULL,
NULL,
&io,
pbuffer,
(LONG)fsi.EndOfFile.QuadPart,
NULL,
NULL);
KdPrint(("这次真正读了%d bytes\n", io.Information));
ZwClose(hfile);
ExFreePool(pbuffer);
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
这里是效果图 。。。
在xp下 完美运行 其它 不好说 最好在 搞个快照 看看
不要脸的 挂个原创 嘿嘿。。