超简单的windows驱动文件读写库 EzFile

  • Post author:
  • Post category:其他


弄了一个非常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 版权协议,转载请附上原文出处链接和本声明。