代码网上都有,就讲一下解决安装问题:
1,mini filter 的安装,一开始还是像普通的 legacy driver一样,通过命令行 "sc create servicenam binPath type=kernel"发现一直报错:错误2,找不到文件;然后调整"sc create servicename binPath type=filesys";驱动可以起来,FltRegisterFilter失败,报错找不到对象(0xc0000034).原来mini filter driver 安装需要通过inf 文件来,就是要在注册表中添加一下额外的键值。
2,下载微软开源项目中的nullfilter.inf,修改一下:https://github.com/microsoft/Windows-driver-samples/blob/master/filesys/miniFilter/nullFilter/nullFilter.inf
之后驱动服务可以正常起来,发现注册的回调函数没有触发;一顿google 发现是inf 文件中的:
Instance1.Flags = 0x1 ; Suppress automatic attachments 阻止自动附加,导致回调函数没有立马生效
把这个标志设为0,然后重启服务,回调函数马上就被触发了。
以下FltPreOperationCallback/FltPostOperationCallback为错误样例
#include"common.h"
#pragma comment(lib,"FltMgr.lib")
#pragma warning(disable:4100)
#pragma warning(disable:4189)
PFLT_FILTER gRetFilter;
/*
typedef FLT_PREOP_CALLBACK_STATUS
(FLTAPI *PFLT_PRE_OPERATION_CALLBACK) (
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_Outptr_result_maybenull_ PVOID *CompletionContext
);
typedef FLT_POSTOP_CALLBACK_STATUS
(FLTAPI *PFLT_POST_OPERATION_CALLBACK) (
_Inout_ PFLT_CALLBACK_DATA Data,
_In_ PCFLT_RELATED_OBJECTS FltObjects,
_In_opt_ PVOID CompletionContext,
_In_ FLT_POST_OPERATION_FLAGS Flags
);
typedef NTSTATUS
(FLTAPI *PFLT_FILTER_UNLOAD_CALLBACK) (
FLT_FILTER_UNLOAD_FLAGS Flags
);
*/
NTSTATUS FltFilterUnload(FLT_FILTER_UNLOAD_FLAGS Flags)
{
DbgPrint("[***]majic is 0x%x\n", majic);
DbgPrint("[***]mini filter unloaded!");
return STATUS_SUCCESS;
}
FLT_PREOP_CALLBACK_STATUS FltPreOperationCallback(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext)
{
FLT_PREOP_CALLBACK_STATUS status = 0;
majic = 0x87654321;
DbgPrint("[***]enter FltPreOperationCallback");
return status;
}
FLT_POSTOP_CALLBACK_STATUS FltPostOperationCallback(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects,
PVOID CompletionContext, FLT_POST_OPERATION_FLAGS Flags)
{
FLT_POSTOP_CALLBACK_STATUS status = 0;
majic = 0x12345678;
DbgPrint("[***]enter FltPostOperationCallback");
return status;
}
NTSTATUS RegisterMiniFilter()
{
NTSTATUS status = STATUS_SUCCESS;
PFLT_FILTER RetFilter = NULL;
FLT_REGISTRATION FltRegistration = { 0 };
const FLT_CONTEXT_REGISTRATION FltContext[] = {
{
FLT_STREAMHANDLE_CONTEXT,
0,
0,
1,
0X31323334,
NULL,
NULL,
NULL
},
{
FLT_CONTEXT_END
}
};
const FLT_OPERATION_REGISTRATION FltOperation[] = {
{
IRP_MJ_CREATE,
0,
FltPreOperationCallback,
FltPostOperationCallback,
NULL
},
{
IRP_MJ_READ,
0,
FltPreOperationCallback,
FltPostOperationCallback,
NULL
},
{
IRP_MJ_WRITE,
0,
NULL,
FltPostOperationCallback,
NULL
},
{
IRP_MJ_OPERATION_END
}
};
FltRegistration.Size = sizeof(FLT_REGISTRATION);
FltRegistration.Version = FLT_REGISTRATION_VERSION;
FltRegistration.ContextRegistration = FltContext;
FltRegistration.OperationRegistration = FltOperation;
FltRegistration.FilterUnloadCallback = FltFilterUnload;
status=FltRegisterFilter(gDriverObject, &FltRegistration, &RetFilter);
if (NT_SUCCESS(status))
{
gRetFilter = RetFilter;
//
status=FltStartFiltering(RetFilter);
if (NT_SUCCESS(status))
{
DbgPrint("[***]mini filter is started!");
}
else
{
DbgPrint("[***]failed to start mini filter,status:0x%x\n", status);
}
}
else
{
DbgPrint("[***]failed to register mini filter,status:0x%x\n", status);
}
return status;
}
正确的FltPreOperationCallback/FltPostOperationCallback样例,如下
FLT_PREOP_CALLBACK_STATUS FltPreOperationCallback(PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects,
PVOID* CompletionContext)
{
FLT_PREOP_CALLBACK_STATUS status = FLT_PREOP_SUCCESS_NO_CALLBACK;
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
majic = 0x87654321;
if ((Data->Iopb->IrpFlags & IRP_PAGING_IO) || (Data->Iopb->IrpFlags & IRP_SYNCHRONOUS_PAGING_IO) || IoGetTopLevelIrp())
{
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
if ((FltObjects->FileObject) != NULL)
{
status = FltGetFileNameInformation(Data,
FLT_FILE_NAME_NORMALIZED,
&nameInfo);
if (NT_SUCCESS(status))
{
status = FltParseFileNameInformation(nameInfo);
if (NT_SUCCESS(status))
{
DbgPrint("file name:%wZ", &nameInfo->Name);
}
FltReleaseFileNameInformation(nameInfo);
}
}
//DbgPrint("[***]enter FltPreOperationCallback");
return FLT_PREOP_SUCCESS_NO_CALLBACK;
}
FLT_POSTOP_CALLBACK_STATUS FltPostOperationCallback(PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects,
PVOID CompletionContext,
FLT_POST_OPERATION_FLAGS Flags)
{
FLT_POSTOP_CALLBACK_STATUS status = FLT_POSTOP_FINISHED_PROCESSING;
majic = 0x12345678;
//DbgPrint("[***]enter FltPostOperationCallback");
return status;
}
20220617
关于FltRegisterFilter内部逻辑,如下图:
在FltpLinkFilterIntoFrame中对FltFilter->Base.PrimaryLink进行赋值。