核心驱动的文件操作主要有以下一个函数
NTSTATUS
ZwCreateFile(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength
);
NTSTATUS
ZwQueryInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
NTSTATUS
ZwSetInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
NTSTATUS
ZwWriteFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
NTSTATUS
ZwReadFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
);
打开/创建/读/写文件 的操作基本上和 SDK API 的使用差不多,但是文件指针的移动,属性的修改比 SDK API 稍复杂一些,主要使用 ZwQueryInformationFile 和 ZwSetInformationFile 这两个函数完成,下面举个例子大概说明一下这两个函数的使用。
//Create the log file IO_STATUS_BLOCK file_status; OBJECT_ATTRIBUTES obj_attrib; CCHAR ntNameFile[64] = "//DosDevices//c://temp.txt"; STRING ntNameString; UNICODE_STRING uFileName; FILE_STANDARD_INFORMATION fsi; FILE_POSITION_INFORMATION fpi;
RtlInitAnsiString( &ntNameString, ntNameFile); RtlAnsiStringToUnicodeString(&uFileName, &ntNameString, TRUE ); InitializeObjectAttributes(&obj_attrib, &uFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); Status = ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,GENERIC_WRITE,&obj_attrib,&file_status, NULL,FILE_ATTRIBUTE_NORMAL,FILE_SHARE_READ,FILE_OPEN_IF,FILE_SYNCHRONOUS_IO_NONALERT,NULL,0); RtlFreeUnicodeString(&uFileName);
ZwQueryInformationFile(pKeyboardDeviceExtension->hLogFile, &file_status, &fsi, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);
fpi.CurrentByteOffset = fsi.EndOfFile;
ZwSetInformationFile(pKeyboardDeviceExtension->hLogFile, &file_status, &fpi, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation);
if (Status != STATUS_SUCCESS) { DbgPrint("Failed to create log file.../n"); DbgPrint("File Status = %x/n",file_status); } else { DbgPrint("Successfully created log file.../n"); DbgPrint("File Handle = %x/n",pKeyboardDeviceExtension->hLogFile); DbgPrint("Move to Eof %d/n", fsi.EndOfFile); }
|
这段代码打开文件 C:/temp.txt 并将文件指针移动到文件末尾
在 SDK 编程中我们只需要
SetFilePointer(hAppend, 0, NULL, FILE_END);
就可以将文件指针移动到文件尾,但在 DDK 编程中我们需要使用 ZwQueryInformationFile 获得文件大小,然后使用 ZwSetInformationFile 将文件指针移动到需要的位置。