首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >小型驱动程序不阻塞文件版本

小型驱动程序不阻塞文件版本
EN

Stack Overflow用户
提问于 2018-01-26 17:14:39
回答 1查看 1.9K关注 0票数 0

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

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

这是我的代码:

代码语言:javascript
复制
#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;
}

代码语言:javascript
复制
;;;
;;; 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

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

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

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

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

我运行以下命令:

pnputil /附加驱动程序FsFilter2.inf

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

代码语言:javascript
复制
Microsoft PnP Utility

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

Total driver packages:  1 
Added driver packages:  1

然后,我从以下几个方面开始:

净启动FsFilter2

并获得以下输出:

代码语言:javascript
复制
The FsFilter2 service was started successfully.

然而,我仍然可以写进OPENME.txt文件.在本教程中不可能.

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

有人知道我做错了什么吗?或者我能做些什么来找出我的问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-26 18:59:39

我当然希望Youtube视频没有教你这样做。这里有很多错误,所以我首先建议你去看看微软的小型机样本。它们位于这里,更具体地说,我建议您检查扫描仪样本,或者avscan,但后者稍微复杂一些。简而言之,以下是几点建议:

  1. 进行签入,因为文件对象尚未被您下面的文件系统打开,因此FltGetFileNameInformation本身将执行一个FltCreateFile来打开文件,以便查询文件名。
  2. 在PostCreate中,还可以决定是否允许打开该文件。您应该检查打开操作所用的DesiredAccess,如果它适合您的掩码,在本例中是一个简单的拒绝创建的DesiredAccess。见用什么API取消打开的文件所需访问的位置
  3. 不要忘记将数据->IoStatus.Status设置为STATUS_ACCESS_DENIED,因为STATUS_INVALID_PARAMETER非常模糊,而事实并非如此。
  4. 不要在PreWrite中对此进行任何处理,因为它不是,需要您已经阻止了创建。
  5. 不要使用不安全的字符串函数,比如wcsstr,也许可以考虑使用ntstrsafe.h.h中可用的API,它们根据提供的长度进行边界检查,而不是在末尾假设为空字符。

祝你好运,希望这能帮上忙。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48466308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档