如何从内核模式设备驱动程序中打开一个文件以及如何读取或写入文件
对象名称来引用文件内核模式设备驱动程序对象名称来引用文件。 此名称是 /DosDevices 一起与该文件的完整路径。 是例如 C:/Windows/Examp...
对象名称来引用文件 内核模式设备驱动程序对象名称来引用文件。 此名称是 /DosDevices 一起与该文件的完整路径。 是例如 C:/Windows/Example.txt 文件的对象名称将是 /DosDevices/C:/Windows/Example.txt。 然后通过调用
InitializeObjectAttributes 函数到一个
OBJECT_ATTRIBUTES 结构封装对象名称。
请注意 如果早期加载设备驱动程序则
/DosDevices 命名空间可能不还存在。 因此,
/DosDevices 命名空间是设备驱动程序无法访问由于公开没有驱动器号。 唯一保证可用的文件系统的部分是
/SystemRoot 命名空间。
/SystemRoot 命名空间映射到其中的操作系统的安装的文件夹。 是例如此文件夹可能是 C:/Windows 或 D:/Winnt。
下面的代码示例说明如何引用按其对象名称的文件
UNICODE_STRING uniName; OBJECT_ATTRIBUTES objAttr; RtlInitUnicodeString(&uniName, L"//DosDevices//C://WINDOWS//example.txt"); // or L"//SystemRoot//example.txt" InitializeObjectAttributes(&objAttr, &uniName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
获得文件句柄
若要 to 文件句柄可以给
ZwCreateFile 函数传递了
OBJECT_ATTRIBUTES 结构。
DesiredAccess 参数可以设置
GENERIC _ READ 、
GENERIC WRITE ,或
GENERIC_ALL ,根据您要执行。 如果将
CreateOptions 参数设置为
FILE_SYNCHRONOUS_IO_NONALERT 或
FILE_SYNCHRONOUS_IO_ALERT ,文件系统跟踪的当前文件位置偏移量。 因此,您可以按顺序读取或更高版本写入该文件。 此外,可以访问该文件在随机位置。
下面的代码示例演示如何获取文件句柄
HANDLE handle; NTSTATUS ntstatus; IO_STATUS_BLOCK ioStatusBlock; // Do not try to perform any file operations at higher IRQL levels. // Instead, you may use a work item or a system worker thread to perform file operations. if(KeGetCurrentIrql() != PASSIVE_LEVEL) return STATUS_INVALID_DEVICE_STATE; ntstatus = ZwCreateFile(&handle, GENERIC_WRITE, &objAttr, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
读取或写入到文件
您现在可以调用
ZwReadFile 函数或
ZwWriteFile 函数。 完成修改文件后,请使用
ZwClose 函数关闭此句柄。
下面的代码示例阐释如何编写到文件
#define BUFFER_SIZE 30 CHAR buffer[BUFFER_SIZE]; size_t cb; if(NT_SUCCESS(ntstatus)) { ntstatus = RtlStringCbPrintfA(buffer, sizeof(buffer), "This is %d test/r/n", 0x0); if(NT_SUCCESS(ntstatus)) { ntstatus = RtlStringCbLengthA(buffer, sizeof(buffer), &cb); if(NT_SUCCESS(ntstatus)) { ntstatus = ZwWriteFile(handle, NULL, NULL, NULL, &ioStatusBlock, buffer, cb, NULL, NULL); } } ZwClose(handle); }
下面的代码示例说明如何从文件中读取
LARGE_INTEGER byteOffset; ntstatus = ZwCreateFile(&handle, GENERIC_READ, &objAttr, &ioStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if(NT_SUCCESS(ntstatus)) { byteOffset.LowPart = byteOffset.HighPart = 0; ntstatus = ZwReadFile(handle, NULL, NULL, NULL, &ioStatusBlock, buffer, BUFFER_SIZE, &byteOffset, NULL); if(NT_SUCCESS(ntstatus)) { buffer[BUFFER_SIZE-1] = '/0'; DbgPrint("%s/n", buffer); } ZwClose(handle); }