弄了一个非常simple,甚至naive的驱动文件读写库,只有读文件,覆盖写文件,删除文件三个函数。
平平淡淡才是真。
EzFile.h
#ifndef EZ_FILE_H_
#define EZ_FILE_H_
#include <ntddk.h>
// 以覆盖的方式写文件
NTSTATUS EzWriteFile(IN const char* FileName, IN char* Data, IN SIZE_T Size);
// 读文件,如果文件不存在,则什么都读不到
// 读取的数据存储在非分页内存中,需要调用者释放
NTSTATUS EzReadFile(IN const char* FileName, OUT char** Data, OUT SIZE_T* DataSize);
// 常规方式删除文件
NTSTATUS EzDeleteFile(IN const char* FileName);
#endif
EzFile.c
#include "EzFile.h"
NTSTATUS EzWriteFile(IN const char* FileName, IN char* Data, IN SIZE_T Size)
{
HANDLE hFile = NULL;
OBJECT_ATTRIBUTES object_attr = { 0 };
ANSI_STRING anFilePath = { 0 };
UNICODE_STRING unFilePathName = { 0 };
NTSTATUS status = 0;
IO_STATUS_BLOCK sb = { 0 };
// 覆盖方式打开文件
RtlInitAnsiString(&anFilePath, FileName);
status = RtlAnsiStringToUnicodeString(&unFilePathName, &anFilePath, TRUE);
if (!NT_SUCCESS(status))
{
return status;
}
InitializeObjectAttributes(&object_attr, &unFilePathName, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwCreateFile(&hFile, GENERIC_ALL, &object_attr, &sb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0);
if (!NT_SUCCESS(status))
{
return status;
}
RtlFreeUnicodeString(&unFilePathName);
// 写文件
LARGE_INTEGER Offset = { 0 };
status = ZwWriteFile(hFile, NULL, NULL, NULL, &sb, (PVOID)Data, Size, &Offset, NULL);
if (!NT_SUCCESS(status))
{
return status;
}
return ZwClose(hFile);
}
NTSTATUS EzReadFile(IN const char* FileName, OUT char** Data, OUT SIZE_T* DataSize)
{
HANDLE hFile = NULL;
IO_STATUS_BLOCK sb = { 0 };
NTSTATUS status = 0;
LARGE_INTEGER Offset = { 0 };
OBJECT_ATTRIBUTES object_attr = { 0 };
ANSI_STRING anFilePath = { 0 };
UNICODE_STRING unFilePathName = { 0 };
FILE_STANDARD_INFORMATION fsi = { 0 };
LARGE_INTEGER Size = { 0 };
// 打开文件,获取句柄
RtlInitAnsiString(&anFilePath, FileName);
status = RtlAnsiStringToUnicodeString(&unFilePathName, &anFilePath, TRUE);
if (!NT_SUCCESS(status))
{
return status;
}
InitializeObjectAttributes(&object_attr, &unFilePathName, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwCreateFile(&hFile, GENERIC_READ, &object_attr, &sb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0);
RtlFreeUnicodeString(&unFilePathName);
if (!NT_SUCCESS(status))
{
return status;
}
// 获取文件大小
memset(&sb, 0, sizeof(sb));
status = ZwQueryInformationFile(hFile, &sb, &fsi, sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation);
if (!NT_SUCCESS(status))
{
ZwClose(hFile);
return status;
}
Size.QuadPart = fsi.EndOfFile.QuadPart;
// 申请内存
*Data = ExAllocatePool(NonPagedPool, Size.QuadPart);
if (*Data == NULL)
{
ZwClose(hFile);
return STATUS_INSUFFICIENT_RESOURCES;
}
// 读文件
status = ZwReadFile(hFile, NULL, NULL, NULL, &sb, (PVOID)*Data, Size.QuadPart, &Offset, NULL);
if (!NT_SUCCESS(status))
{
return status;
}
*DataSize = Size.QuadPart;
return ZwClose(hFile);
}
NTSTATUS EzDeleteFile(IN const char* FileName)
{
HANDLE hFile = NULL;
IO_STATUS_BLOCK sb = { 0 };
FILE_DISPOSITION_INFORMATION dinfo = { 0 };
NTSTATUS status = 0;
ANSI_STRING anFilePath = { 0 };
UNICODE_STRING unFilePathName = { 0 };
OBJECT_ATTRIBUTES object_attr = { 0 };
// 打开文件,获取句柄
RtlInitAnsiString(&anFilePath, FileName);
status = RtlAnsiStringToUnicodeString(&unFilePathName, &anFilePath, TRUE);
if (!NT_SUCCESS(status))
{
return status;
}
InitializeObjectAttributes(&object_attr, &unFilePathName, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = ZwCreateFile(&hFile, GENERIC_ALL, &object_attr, &sb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, NULL, 0);
RtlFreeUnicodeString(&unFilePathName);
if (!NT_SUCCESS(status))
{
return status;
}
dinfo.DeleteFile = TRUE;
status = ZwSetInformationFile(hFile, &sb, &dinfo, sizeof(FILE_DISPOSITION_INFORMATION), FileDispositionInformation);
if (!NT_SUCCESS(status))
{
return status;
}
return ZwClose(hFile);
}
测试用例
#include<ntifs.h>
#include "EzFile.h"
VOID Unload(PDRIVER_OBJECT pDriver)
{
//NTSTATUS status = 0;
//status = EzWriteFile("\\??\\C:\\1.txt", "驱动卸载", sizeof("驱动卸载"));
//if (!NT_SUCCESS(status))
//{
// DbgPrintEx(77, 0, "写文件失败 %d\r\n", status);
//}
EzDeleteFile("\\??\\C:\\1.txt");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
NTSTATUS status = 0;
status = EzWriteFile("\\??\\C:\\1.txt", "简单文件API", sizeof("简单文件API"));
if (!NT_SUCCESS(status))
{
DbgPrintEx(77, 0, "写文件失败 %d\r\n", status);
}
char* Data = NULL;
SIZE_T Size = 0;
status = EzReadFile("\\??\\C:\\1.txt", &Data, &Size);
if (!NT_SUCCESS(status))
{
DbgPrintEx(77, 0, "读文件失败 %d\r\n", status);
}
else
{
DbgPrintEx(77, 0, "读取字节 %d, 内容: %s\r\n", Size, Data);
}
if (Data != NULL)
{
ExFreePool(Data);
}
pDriver->DriverUnload = Unload;
return STATUS_SUCCESS;
}
版权声明:本文为Kwansy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。