win内核内部直接irp读取文件写入文件
#include <ntifs.h>
#include <ntddk.h>
#define TAG_NAME 'tlfF' // FltF in reverse
#define BUFFER_SIZE PAGE_SIZE
// 驱动设备扩展结构
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName;
UNICODE_STRING SymLinkName;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
// 文件上下文结构
typedef struct _FILE_CONTEXT {
PFILE_OBJECT FileObject;
LARGE_INTEGER FileSize;
PVOID Buffer;
ULONG BufferSize;
} FILE_CONTEXT, *PFILE_CONTEXT;
// 函数声明
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;
NTSTATUS CreateFileContext(_Out_ PFILE_CONTEXT* FileContext);
VOID FreeFileContext(_In_ PFILE_CONTEXT FileContext);
NTSTATUS CreateFileObject(_In_ PCWSTR FilePath, _In_ ACCESS_MASK DesiredAccess, _Out_ PFILE_OBJECT* FileObject);
NTSTATUS ReadFileDirectly(_In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER Offset, _In_ ULONG Length, _Out_ PVOID Buffer, _Out_ PIO_STATUS_BLOCK IoStatus);
NTSTATUS WriteFileDirectly(_In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER Offset, _In_ ULONG Length, _In_ PVOID Buffer, _Out_ PIO_STATUS_BLOCK IoStatus);
VOID CloseFileObject(_In_ PFILE_OBJECT FileObject);
NTSTATUS FileOperationExample(_In_ PCWSTR FilePath);
// 驱动入口函数
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
PDEVICE_OBJECT deviceObject = NULL;
PDEVICE_EXTENSION deviceExtension = NULL;
UNICODE_STRING deviceName;
UNICODE_STRING symLinkName;
UNREFERENCED_PARAMETER(RegistryPath);
// 初始化设备名和符号链接名
RtlInitUnicodeString(&deviceName, L"\\Device\\FileFilterDriver");
RtlInitUnicodeString(&symLinkName, L"\\??\\FileFilterDriver");
// 创建设备对象
status = IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
&deviceName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&deviceObject);
if (!NT_SUCCESS(status)) {
return status;
}
// 初始化设备扩展
deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
deviceExtension->DeviceObject = deviceObject;
deviceExtension->DeviceName = deviceName;
deviceExtension->SymLinkName = symLinkName;
// 创建符号链接
status = IoCreateSymbolicLink(&symLinkName, &deviceName);
if (!NT_SUCCESS(status)) {
IoDeleteDevice(deviceObject);
return status;
}
// 设置驱动卸载函数
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
// 驱动卸载函数
VOID
DriverUnload(
_In_ PDRIVER_OBJECT DriverObject
)
{
PDEVICE_EXTENSION deviceExtension;
deviceExtension = (PDEVICE_EXTENSION)DriverObject->DeviceObject->DeviceExtension;
// 删除符号链接
IoDeleteSymbolicLink(&deviceExtension->SymLinkName);
// 删除设备对象
IoDeleteDevice(DriverObject->DeviceObject);
}
// 创建文件上下文
NTSTATUS
CreateFileContext(
_Out_ PFILE_CONTEXT* FileContext
)
{
PFILE_CONTEXT context;
context = ExAllocatePoolWithTag(NonPagedPool, sizeof(FILE_CONTEXT), TAG_NAME);
if (NULL == context) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(context, sizeof(FILE_CONTEXT));
context->Buffer = ExAllocatePoolWithTag(NonPagedPool, BUFFER_SIZE, TAG_NAME);
if (NULL == context->Buffer) {
ExFreePoolWithTag(context, TAG_NAME);
return STATUS_INSUFFICIENT_RESOURCES;
}
context->BufferSize = BUFFER_SIZE;
*FileContext = context;
return STATUS_SUCCESS;
}
// 关闭文件对象
VOID
CloseFileObject(
_In_ PFILE_OBJECT FileObject
)
{
if (FileObject) {
PDEVICE_OBJECT deviceObject = FileObject->DeviceObject;
if (deviceObject) {
KEVENT event;
IO_STATUS_BLOCK ioStatus;
// 发送清理IRP
KeInitializeEvent(&event, NotificationEvent, FALSE);
PIRP irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp) {
irp->UserIosb = &ioStatus;
irp->UserEvent = &event;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->RequestorMode = KernelMode;
irp->Flags = IRP_SYNCHRONOUS_API;
PIO_STACK_LOCATION irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CLEANUP;
irpSp->FileObject = FileObject;
IoCallDriver(deviceObject, irp);
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
// 发送关闭IRP
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
if (irp) {
irp->UserIosb = &ioStatus;
irp->UserEvent = &event;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->RequestorMode = KernelMode;
irp->Flags = IRP_SYNCHRONOUS_API;
irpSp = IoGetNextIrpStackLocation(irp);
irpSp->MajorFunction = IRP_MJ_CLOSE;
irpSp->FileObject = FileObject;
IoCallDriver(deviceObject, irp);
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
}
}
}
ObDereferenceObject(FileObject);
}
}
// 释放文件上下文
VOID
FreeFileContext(
_In_ PFILE_CONTEXT FileContext
)
{
if (FileContext) {
if (FileContext->Buffer) {
ExFreePoolWithTag(FileContext->Buffer, TAG_NAME);
FileContext->Buffer = NULL;
}
if (FileContext->FileObject) {
CloseFileObject(FileContext->FileObject);
FileContext->FileObject = NULL;
}
ExFreePoolWithTag(FileContext, TAG_NAME);
}
}
// 创建文件对象
NTSTATUS
CreateFileObject(
_In_ PCWSTR FilePath,
_In_ ACCESS_MASK DesiredAccess,
_Out_ PFILE_OBJECT* FileObject
)
{
OBJECT_ATTRIBUTES objAttributes;
UNICODE_STRING fileName;
IO_STATUS_BLOCK ioStatus;
HANDLE fileHandle;
NTSTATUS status;
if (NULL == FilePath || NULL == FileObject) {
return STATUS_INVALID_PARAMETER;
}
RtlInitUnicodeString(&fileName, FilePath);
InitializeObjectAttributes(&objAttributes,
&fileName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
status = IoCreateFile(&fileHandle,
DesiredAccess,
&objAttributes,
&ioStatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
0,
NULL,
0,
CreateFileTypeNone,
NULL,
IO_NO_PARAMETER_CHECKING);
if (!NT_SUCCESS(status)) {
return status;
}
status = ObReferenceObjectByHandle(fileHandle,
DesiredAccess,
*IoFileObjectType,
KernelMode,
(PVOID*)FileObject,
NULL);
ZwClose(fileHandle);
return status;
}
// 直接读取文件
NTSTATUS
ReadFileDirectly(
_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER Offset,
_In_ ULONG Length,
_Out_ PVOID Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus
)
{
KEVENT event;
PIRP irp;
NTSTATUS status;
if (NULL == FileObject || NULL == Buffer || NULL == IoStatus) {
return STATUS_INVALID_PARAMETER;
}
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
FileObject->DeviceObject,
Buffer,
Length,
Offset,
&event,
IoStatus);
if (NULL == irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
IoGetNextIrpStackLocation(irp)->FileObject = FileObject;
status = IoCallDriver(FileObject->DeviceObject, irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
status = IoStatus->Status;
}
return status;
}
// 直接写入文件
NTSTATUS
WriteFileDirectly(
_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER Offset,
_In_ ULONG Length,
_In_ PVOID Buffer,
_Out_ PIO_STATUS_BLOCK IoStatus
)
{
KEVENT event;
PIRP irp;
NTSTATUS status;
if (NULL == FileObject || NULL == Buffer || NULL == IoStatus) {
return STATUS_INVALID_PARAMETER;
}
KeInitializeEvent(&event, NotificationEvent, FALSE);
irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
FileObject->DeviceObject,
Buffer,
Length,
Offset,
&event,
IoStatus);
if (NULL == irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
IoGetNextIrpStackLocation(irp)->FileObject = FileObject;
status = IoCallDriver(FileObject->DeviceObject, irp);
if (STATUS_PENDING == status) {
KeWaitForSingleObject(&event,
Executive,
KernelMode,
FALSE,
NULL);
status = IoStatus->Status;
}
return status;
}
// 文件操作示例
NTSTATUS
FileOperationExample(
_In_ PCWSTR FilePath
)
{
PFILE_CONTEXT fileContext = NULL;
IO_STATUS_BLOCK ioStatus;
LARGE_INTEGER offset = {0};
NTSTATUS status;
// 创建文件上下文
status = CreateFileContext(&fileContext);
if (!NT_SUCCESS(status)) {
return status;
}
__try {
// 创建文件对象
status = CreateFileObject(FilePath,
FILE_READ_DATA | FILE_WRITE_DATA,
&fileContext->FileObject);
if (!NT_SUCCESS(status)) {
__leave;
}
// 读取文件
status = ReadFileDirectly(fileContext->FileObject,
&offset,
fileContext->BufferSize,
fileContext->Buffer,
&ioStatus);
if (!NT_SUCCESS(status)) {
__leave;
}
// 这里可以处理读取的数据
// ...
// 写入文件
status = WriteFileDirectly(fileContext->FileObject,
&offset,
(ULONG)ioStatus.Information,
fileContext->Buffer,
&ioStatus);
}
__finally {
if (fileContext) {
FreeFileContext(fileContext);
}
}
return status;
}
如何使用
/*
* 文件操作测试函数
* 用于验证基本的文件操作功能
*/
NTSTATUS
TestFileOperations(
VOID
)
{
NTSTATUS status = STATUS_SUCCESS;
const PCWSTR testPath = L"\\??\\C:\\test.txt";
// 参数验证
if (NULL == testPath) {
return STATUS_INVALID_PARAMETER;
}
__try {
// 调用文件操作示例函数
status = FileOperationExample(testPath);
if (NT_SUCCESS(status)) {
DbgPrint("[TestFileOperations] File operation completed successfully\n");
} else {
DbgPrint("[TestFileOperations] File operation failed. Status: 0x%08X\n", status);
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
DbgPrint("[TestFileOperations] Exception occurred: 0x%08X\n", status);
}
return status;
}
/*
* 驱动程序入口点
*/
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
NTSTATUS status = STATUS_SUCCESS;
UNREFERENCED_PARAMETER(RegistryPath);
// 验证参数
if (NULL == DriverObject) {
return STATUS_INVALID_PARAMETER;
}
__try {
// 执行驱动初始化
status = InitializeDriver(DriverObject);
if (!NT_SUCCESS(status)) {
DbgPrint("[DriverEntry] Driver initialization failed: 0x%08X\n", status);
return status;
}
// 执行文件操作测试
status = TestFileOperations();
if (!NT_SUCCESS(status)) {
DbgPrint("[DriverEntry] File operations test failed: 0x%08X\n", status);
// 注意:这里选择继续执行,而不是直接返回错误
}
// 设置清理回调
DriverObject->DriverUnload = DriverUnload;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
DbgPrint("[DriverEntry] Exception occurred: 0x%08X\n", status);
}
return status;
}