Minifilter驱动程序不阻止文件版本

时间:2018-01-26 17:14:40

标签: c++ minifilter

我正在尝试创建文件系统过滤器(Minifilter)驱动程序。为此,我遵循此处提供的教程:https://www.youtube.com/watch?v=ukUf3kSSTOU

简单地说,在本教程中,您将创建一个minifilter驱动程序,阻止您写入名为OPENME.txt的文件。

这是我的代码:

#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>

PFLT_FILTER FilterHandle = NULL;
NTSTATUS MiniUnload(FLT_FILTER_UNLOAD_FLAGS Flags);
FLT_POSTOP_CALLBACK_STATUS MiniPostCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContec, FLT_POST_OPERATION_FLAGS Flags);
FLT_PREOP_CALLBACK_STATUS MiniPreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContec);
FLT_PREOP_CALLBACK_STATUS MiniPreWrite(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContec);

const FLT_OPERATION_REGISTRATION Callbacks[] =
{
    { IRP_MJ_CREATE,0,MiniPreCreate, MiniPostCreate },
    { IRP_MJ_WRITE,0,MiniPreWrite, NULL },
    { IRP_MJ_OPERATION_END }
};

const FLT_REGISTRATION FilterRegistration =
{
    sizeof(FLT_REGISTRATION),
    FLT_REGISTRATION_VERSION,
    0,
    NULL,
    Callbacks,
    MiniUnload,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
};

NTSTATUS MiniUnload(FLT_FILTER_UNLOAD_FLAGS Flags)
{
    KdPrint(("driver unload \r\n"));
    FltUnregisterFilter(FilterHandle);

    return STATUS_SUCCESS;
}

FLT_POSTOP_CALLBACK_STATUS MiniPostCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContec, FLT_POST_OPERATION_FLAGS Flags)
{
    KdPrint(("post create running \r\n"));

    return FLT_POSTOP_FINISHED_PROCESSING;
}

FLT_PREOP_CALLBACK_STATUS MiniPreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContec)
{
    PFLT_FILE_NAME_INFORMATION FileNameInfo;
    NTSTATUS status;
    WCHAR Name[200] = { 0 };

    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: %wa \r\n", Name));
            }
        }

        FltReleaseFileNameInformation(FileNameInfo);
    }

    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}

FLT_PREOP_CALLBACK_STATUS MiniPreWrite(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContec)
{
    PFLT_FILE_NAME_INFORMATION FileNameInfo;
    NTSTATUS status;
    WCHAR Name[200] = { 0 };

    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"OPENME.txt") != NULL)
                {
                    KdPrint(("write file %ws blocked \r\n", Name));

                    Data->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    Data->IoStatus.Information = 0;

                    FltReleaseFileNameInformation(FileNameInfo);

                    return FLT_PREOP_COMPLETE;
                }

                KdPrint(("create file: %wa \r\n", Name));
            }
        }

        FltReleaseFileNameInformation(FileNameInfo);
    }

    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
    NTSTATUS status;

    status = FltRegisterFilter(DriverObject, &FilterRegistration, &FilterHandle);

    if (NT_SUCCESS(status))
    {
        status = FltStartFiltering(FilterHandle);

        if (!NT_SUCCESS(status))
        {
            FltUnregisterFilter(FilterHandle);
        }
    }

    return status;
}

;;;
;;; FsFilter2
;;;

[Version]
Signature   = "$Windows NT$"
; TODO - Change the Class and ClassGuid to match the Load Order Group value, see https://msdn.microsoft.com/en-us/windows/hardware/gg462963
; Class       = "ActivityMonitor"                         ;This is determined by the work this filter driver does
; ClassGuid   = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}    ;This value is determined by the Load Order Group value
Class = "ActivityMonitor"
ClassGuid = {b86dff51-a31e-4bac-b3cf-e8cfe75c9fc2}
Provider    = %ManufacturerName%
DriverVer = 01/26/2018,16.49.59.238
CatalogFile = FsFilter2.cat

[DestinationDirs]
DefaultDestDir          = 12
MiniFilter.DriverFiles  = 12            ;%windir%\system32\drivers

;;
;; Default install sections
;;

[DefaultInstall]
OptionDesc          = %ServiceDescription%
CopyFiles           = MiniFilter.DriverFiles

[DefaultInstall.Services]
AddService          = %ServiceName%,,MiniFilter.Service

;;
;; Default uninstall sections
;;

[DefaultUninstall]
DelFiles   = MiniFilter.DriverFiles

[DefaultUninstall.Services]
DelService = %ServiceName%,0x200      ;Ensure service is stopped before deleting

;
; Services Section
;

[MiniFilter.Service]
DisplayName      = %ServiceName%
Description      = %ServiceDescription%
ServiceBinary    = %12%\%DriverName%.sys        ;%windir%\system32\drivers\
Dependencies     = "FltMgr"
ServiceType      = 2                            ;SERVICE_FILE_SYSTEM_DRIVER
StartType        = 3                            ;SERVICE_DEMAND_START
ErrorControl     = 1                            ;SERVICE_ERROR_NORMAL
; TODO - Change the Load Order Group value
; LoadOrderGroup = "FSFilter Activity Monitor"
LoadOrderGroup = "FSFilter Activity Monitor"
AddReg           = MiniFilter.AddRegistry

;
; Registry Modifications
;

[MiniFilter.AddRegistry]
HKR,,"DebugFlags",0x00010001 ,0x0
HKR,,"SupportedFeatures",0x00010001,0x3
HKR,"Instances","DefaultInstance",0x00000000,%DefaultInstance%
HKR,"Instances\"%Instance1.Name%,"Altitude",0x00000000,%Instance1.Altitude%
HKR,"Instances\"%Instance1.Name%,"Flags",0x00010001,%Instance1.Flags%

;
; Copy Files
;

[MiniFilter.DriverFiles]
%DriverName%.sys

[SourceDisksFiles]
FsFilter2.sys = 1,,

[SourceDisksNames]
1 = %DiskId1%,,,

;;
;; String Section
;;

[Strings]
; TODO - Add your manufacturer
ManufacturerName        = "Template"
ServiceDescription      = "FsFilter2 Mini-Filter Driver"
ServiceName             = "FsFilter2"
DriverName              = "FsFilter2"
DiskId1                 = "FsFilter2 Device Installation Disk"

;Instances specific information.
DefaultInstance         = "FsFilter2 Instance"
Instance1.Name          = "FsFilter2 Instance"
; TODO - Change the altitude value, see https://msdn.microsoft.com/en-us/windows/hardware/drivers/ifs/load-order-groups-and-altitudes-for-minifilter-drivers
Instance1.Altitude       = "371000"
Instance1.Flags         = 0x0              ; Allow all attachments

然后,在项目属性中,我设置了以下配置:

  • Plataform:x64
  • C / C ++&gt;警告级别:级别1(/ W1)
  • 链接器&gt;将链接器警告视为错误:否(/ WX:否)
  • 驱动程序设置&gt;目标操作系统版本:Windows 10或更高版本
  • 驱动程序设置&gt;目标平台:桌面

然后,我构建了应用程序,并获得了成功的消息,并创建了.inf和.sys文件。

我的目标计算机是Windows 10 x64,我已经设置了允许使用未签名的驱动程序的选项。

我运行以下命令:

  

pnputil / add-driver FsFilter2.inf

驱动程序安装成功。我得到了输出:

Microsoft PnP Utility

Adding driver package:  FsFilter2.inf 
Driver package added successfully.
Published Name:         oem73.inf

Total driver packages:  1 
Added driver packages:  1

然后,我通过执行以下操作启动驱动器:

  

net start FsFilter2

获得以下输出:

The FsFilter2 service was started successfully.

然而,我仍然可以写入OPENME.txt文件......虽然在教程中它不可能......

我也在使用DebugView,但看不到我的任何消息...

有谁知道我做错了什么?或者我该怎么做才能找出问题所在?

1 个答案:

答案 0 :(得分:3)

我当然希望Youtube视频不会教你这样做。 这里有很多错误,很多我首先会建议你去查看微软的微过滤器样本。 他们位于here 更具体地说,我建议您查看扫描仪样本或avscan,但后者有点复杂。 总之,这里有一些建议:

  1. 由于文件系统尚未在您下面的文件系统打开,因此创建后检查不是预创建的,因此FltGetFileNameInformation本身会执行FltCreateFile来打开文件以查询名称
  2. 在PostCreate中还决定是否要允许打开此文件。您应该检查已完成打开的DesiredAccess以及它是否适合您的面具,在这种情况下, FILE_GENERIC_WRITE 只是拒绝创建。请参阅with what API to cancel a file openwhere the desired access is located
  3. 不要忘记将Data-&gt; IoStatus.Status设置为 STATUS_ACCESS_DENIED ,因为 STATUS_INVALID_PARAMETER 非常模糊,但事实并非如此。
  4. 请勿在PreWrite中进行任何处理,因为它不是,您需要已经阻止了创建。
  5. 不要使用像wcsstr这样的不安全字符串函数,也可以考虑使用 ntstrsafe.h 中提供的API,并且它们会根据提供的长度进行边界检查,而不是假设在结束。
  6. 祝你好运,希望这会有所帮助。