概述
MiniFilter文件过滤驱动整体代码都比较死板,没有太多的流程内容,它的建立本质也是为了方便处理IRP请求,通过注册相应的前回调和后回调以对相应的文件做过滤操作处理,以下代码示例为阻止一个名为name.txt文件的写入操作
注意事项
使用inf配置文件,需要将Class、ClassGuid、Altitude等属性设置一下,随后将其与sys放在一起安装后,使用命令net start ServiceName
和 net stop ServiceName
进行启用和关闭服务,其中ServiceName
为创建的服务名
代码
#include <fltKernel.h>
#include <dontuse.h>
FLT_POSTOP_CALLBACK_STATUS MiniPostCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FlstObjects, PVOID* CompletionContext, FLT_POST_OPERATION_FLAGS flags);
FLT_PREOP_CALLBACK_STATUS MiniPreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FlstObjects, PVOID* CompletionContext);
FLT_PREOP_CALLBACK_STATUS MiniPreWrite(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FlstObjects, PVOID* CompletionContext);
NTSTATUS MiniUnload(FLT_FILTER_UNLOAD_FLAGS Flags);
const FLT_OPERATION_REGISTRATION Callbacks[] = {
{IRP_MJ_CREATE,0,MiniPreCreate,MiniPostCreate},
{IRP_MJ_WRITE,0,MiniPreWrite,NULL},
{IRP_MJ_OPERATION_END}
};
FLT_REGISTRATION registration = { sizeof(FLT_REGISTRATION),FLT_REGISTRATION_VERSION,0,NULL,Callbacks,MiniUnload,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
PFLT_FILTER retfilter = NULL;
NTSTATUS MiniUnload(FLT_FILTER_UNLOAD_FLAGS Flags)
{
KdPrint(("过滤驱动已卸载!\n"));
FltUnregisterFilter(retfilter);
return STATUS_SUCCESS;
}
FLT_POSTOP_CALLBACK_STATUS MiniPostCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FlstObjects, PVOID* CompletionContext,FLT_POST_OPERATION_FLAGS flags)
{
KdPrint(("Create File Post\r\n"));
return FLT_POSTOP_FINISHED_PROCESSING;
}
FLT_PREOP_CALLBACK_STATUS MiniPreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FlstObjects, PVOID* CompletionContext)
{
PFLT_FILE_NAME_INFORMATION filenameinfo = { 0 };
WCHAR Name[260] = { 0 };
NTSTATUS status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &filenameinfo);
if (NT_SUCCESS(status))
{
status = FltParseFileNameInformation(filenameinfo);
if (NT_SUCCESS(status))
{
if (filenameinfo->Name.MaximumLength < 260)
{
RtlCopyMemory(Name, filenameinfo->Name.Buffer,filenameinfo->Name.MaximumLength);
KdPrint(("Create File :%ws \r\n", Name));
}
}
FltReleaseFileNameInformation(filenameinfo);
}
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
FLT_PREOP_CALLBACK_STATUS MiniPreWrite(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FlstObjects, PVOID* CompletionContext)
{
PFLT_FILE_NAME_INFORMATION filenameinfo = { 0 };
WCHAR Name[260] = { 0 };
NTSTATUS status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &filenameinfo);
if (NT_SUCCESS(status))
{
status = FltParseFileNameInformation(filenameinfo);
if (NT_SUCCESS(status))
{
if (filenameinfo->Name.MaximumLength < 260)
{
RtlCopyMemory(Name, filenameinfo->Name.Buffer, filenameinfo->Name.MaximumLength);
_wcsupr(Name);
if (wcsstr(Name, L"NAME.TXT") != NULL)
{
//锁定目标文件写入操作
KdPrint(("Block File Name:%ws\r\n",Name));
Data->IoStatus.Status = STATUS_INVALID_PARAMETER;
Data->IoStatus.Information = 0;
FltReleaseFileNameInformation(filenameinfo);
return FLT_PREOP_COMPLETE;
}
KdPrint(("Write File :%ws \r\n", Name));
}
}
FltReleaseFileNameInformation(filenameinfo);
}
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT Driverobject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
status = FltRegisterFilter(Driverobject, ®istration, &retfilter);
if (NT_SUCCESS(status))
{
status = FltStartFiltering(retfilter);
if (!NT_SUCCESS(status))
{
FltUnregisterFilter(retfilter);
}
}
return status;
}