首页
社区
课程
招聘
[原创]文件微过滤驱动学习笔记 + MzfFileMon(开源)
发表于: 2011-5-22 00:09 38449

[原创]文件微过滤驱动学习笔记 + MzfFileMon(开源)

2011-5-22 00:09
38449

打个广告: http://hi.baidu.com/hu3167343
这是本人刚申请的百度空间, 大家快来加我好友啊, 哈哈.

最近学习了下文件微过滤驱动的框架, 确实比文件过滤系统简单N多啊.

1.DriverEntry
NTSTATUS
DriverEntry (
    __in PDRIVER_OBJECT DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS status;  
    UNREFERENCED_PARAMETER( RegistryPath );

//  注册一个过虑器
    status = FltRegisterFilter( DriverObject,
                                &FilterRegistration,
                                &gFilterHandle );

    if (NT_SUCCESS( status )) {
        //  开启过滤
        status = FltStartFiltering( gFilterHandle );

        if (!NT_SUCCESS( status )) {
            //  开启不成功则注销过滤器
            FltUnregisterFilter( gFilterHandle );
        }
    }
    return status;
}

这里的主要函数是FltRegisterFilter,  原型如下:
NTSTATUS
  FltRegisterFilter(
    IN PDRIVER_OBJECT  Driver, //在DriverEntry中传入的参数
    IN CONST FLT_REGISTRATION  *Registration, //微过滤器注册结构, 这个是最重要的参数
    OUT PFLT_FILTER  *RetFilter //微顾虑句柄, 通常保存在全局变量中
    );

FLT_REGISTRATION的结构如下:
typedef struct _FLT_REGISTRATION {
  USHORT  Size;   //结构的大小, 一般为sizeof(FLT_REGISTRATION)
  USHORT  Version;  //结构的版本, 一般写FLT_REGISTRATION_VERSION即可
  FLT_REGISTRATION_FLAGS  Flags;  //标志位, 一般填0
  CONST FLT_CONTEXT_REGISTRATION  *ContextRegistration;  
  CONST FLT_OPERATION_REGISTRATION  *OperationRegistration; //操作注册函数集, 这个域是最重要的
  PFLT_FILTER_UNLOAD_CALLBACK  FilterUnloadCallback;  //卸载回调函数
  PFLT_INSTANCE_SETUP_CALLBACK  InstanceSetupCallback; //实例绑定回调函数, 在这里可以决定绑定哪些卷, 可以为NULL
  ...
} FLT_REGISTRATION, *PFLT_REGISTRATION;

其中第5个域FLT_OPERATION_REGISTRATION 结构如下:
typedef struct _FLT_OPERATION_REGISTRATION {
  UCHAR  MajorFunction;     //IRP的主功能号
  FLT_OPERATION_REGISTRATION_FLAGS  Flags; //标志位, 一般填0即可, 在读写IRP中可能会有特殊, 具体参看MSDN
  PFLT_PRE_OPERATION_CALLBACK  PreOperation; //预操作回调函数
  PFLT_POST_OPERATION_CALLBACK  PostOperation; //操作后回调函数
  PVOID  Reserved1;
} FLT_OPERATION_REGISTRATION, *PFLT_OPERATION_REGISTRATION;

实例如下:
const FLT_OPERATION_REGISTRATION Callbacks[] = {
    { IRP_MJ_CREATE,
      0,
      NPPreCreate,
      NPPostCreate },

    { IRP_MJ_OPERATION_END } //最后一项必须为这个, 否则过滤管理器,无法知道到底有多少个元素
};

const FLT_REGISTRATION FilterRegistration = {
    sizeof( FLT_REGISTRATION ),         //  Size
    FLT_REGISTRATION_VERSION,           //  Version
    0,                                  //  Flags
    NULL,                               //  Context
    Callbacks,                          //  Operation callbacks
    NPUnload,                           //  MiniFilterUnload
NULL,         
NULL,         
NULL,        
NULL,
    NULL,                             
    NULL,                              
    NULL                          
}

2.卸载例程:
NTSTATUS
NPUnload (
    __in FLT_FILTER_UNLOAD_FLAGS Flags
    )
{
    UNREFERENCED_PARAMETER( Flags );
    PAGED_CODE();
    //注销此过滤器
    FltUnregisterFilter( gFilterHandle );
    return STATUS_SUCCESS;
}

3.微过滤驱动与应用层通信
(1)在DriverEntry中建立一个通信端口
//建立一个默认安全的描述符
status  = FltBuildDefaultSecurityDescriptor( &sd, FLT_PORT_ALL_ACCESS );         

RtlInitUnicodeString( &uniString, MINISPY_PORT_NAME );
InitializeObjectAttributes( &oa,
       &uniString,
       OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
       NULL,
       sd );

//建立一个通信端口
status = FltCreateCommunicationPort( gFilterHandle,
          &gServerPort,
          &oa,
          NULL,
          NPMiniConnect, //R3连接通信端口时的回调例程
          NPMiniDisconnect, //R3断开连接时的回调例程
          NPMiniMessage, //R3发送数据时的回调函数
          1 );

//最后释放安全描述符
FltFreeSecurityDescriptor( sd );

其中比较重要的函数是NPMiniMessage . 此函数在我们调用R3层函数FilterSendMessage时被调用.
函数原型如下:
NTSTATUS
NPMiniMessage (
    __in PVOID ConnectionCookie,
    __in_bcount_opt(InputBufferSize) PVOID InputBuffer,
    __in ULONG InputBufferSize,
    __out_bcount_part_opt(OutputBufferSize,*ReturnOutputBufferLength) PVOID OutputBuffer,
    __in ULONG OutputBufferSize,
    __out PULONG ReturnOutputBufferLength
)

其中在输入的参数中, InputBuffer 和 OutputBuffer需要注意. 这两个参数使用的都是用户模式下的地址,
过滤管理器已经帮我们做了ProbedForRead (对于InputBuffer) 和 ProbedForWrite (对于OutputBuffer)的操作.
以防止R3层传入无效的地址.
但是当我们从InputBuffer中取数据, 或者往OutputBuffer写数据时, 要对他们使用try-catch.
如下;
_try{
    memcpy(OutputBuffer, strPath, strlen(strPath));
}
_except(EXCEPTION_EXECUTE_HANDLER)
{
    KdPrint(("catch error\r\n"));

}

(2)NPUnload例程中关闭通信端口
FltCloseCommunicationPort( gServerPort );

(3)R3程序中
不是用我们常用的DeviceIoControl, 而是有了两个新的函数
连接端口:
HRESULT
WINAPI
  FilterConnectCommunicationPort(
    IN LPCWSTR  lpPortName,
    IN DWORD  dwOptions,
    IN LPVOID  lpContext OPTIONAL,
    IN DWORD  dwSizeOfContext,
    IN LPSECURITY_ATTRIBUTES  lpSecurityAttributes OPTIONAL,
    OUT HANDLE  *hPort
    );

发送和接收数据:
HRESULT
WINAPI
  FilterSendMessage(
    __in HANDLE  hPort,
    __in_bcount LPVOID  lpInBuffer,
    __in DWORD  dwInBufferSize,
    __out_bcount_part_opt LPVOID  lpOutBuffer,
    __in DWORD  dwOutBufferSize,
    __out LPDWORD  lpBytesReturned
    );

在使用FilterSendMessage函数时, 我遇到了一个问题. 就是当我们不需要输入参数而把lpInBuffer传入NULL, dwInBufferSize传入0, 此函数调用会失败, R0层中的NPMiniMessage函数不会被回调. 不知道这是我个人对这个函数参数的理解问题, 还是函数本来就是这样的, 求解释~

其他我就不再累述了, 函数具体用法请参看MSDN

下面是我学习文件微过滤驱动时的实验产物, MzfFileMon, 界面如下:


Bin如下:
MzfFileMonBin.rar

R0和R3代码如下:
MzfFileMonSrc.rar


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (41)
雪    币: 52
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
半夜看贴,顶lz一个~
2011-5-22 00:14
0
雪    币: 2314
活跃值: (2205)
能力值: (RANK:400 )
在线值:
发帖
回帖
粉丝
3
多谢兄弟支持~嘿嘿~
2011-5-22 00:20
0
雪    币: 90
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
顶个~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2011-5-22 00:35
0
雪    币: 327
活跃值: (1268)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
文件微过滤驱动比较容易上手的。
2011-5-22 10:18
0
雪    币: 2362
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
5.22 22:22
支持一下
2011-5-22 22:22
0
雪    币: 2323
活跃值: (4113)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
7
支持,学习~~
2011-5-23 14:51
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
正好我也在看这个 顶了
2011-7-2 14:17
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
很不错,值得一看.有收获.
2011-7-2 16:18
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
是mini filter吧。微软还是挺考虑程序员的,越来越简化了。
2011-7-2 22:38
0
雪    币: 237
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
还是都看看比较好,有sfilter基础再看minifilter就更容易了。。
2011-7-3 08:05
0
雪    币: 965
活跃值: (89)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
文件微过滤驱动比较容易上手的。
2011-7-4 12:25
0
雪    币: 5334
活跃值: (3724)
能力值: ( LV13,RANK:283 )
在线值:
发帖
回帖
粉丝
13
这个必须顶一下
2011-7-7 19:15
0
雪    币: 228
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
谢谢lz分享,学习了
2011-7-8 16:21
0
雪    币: 62
活跃值: (72)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
15
谢谢lz分享,学习了
2011-7-11 16:53
0
雪    币: 178
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
路过一定要顶一下!

我刚接触驱动,我们总监给我发了个微过滤的文档让我看,还没有看,目前只了解简单的驱动模型,还没具体动手,呵呵!
2011-7-15 09:30
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
17
太帅了必须顶!!!!!!!!!
2011-7-15 09:54
0
雪    币: 1149
活跃值: (888)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
18
这框架 也让灵活性大打折扣
2011-7-18 14:33
0
雪    币: 88
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
FltMgr
--------
FileSystem
--------
Volume
--------
Disk
是这样吧?
2011-7-19 09:34
1
雪    币: 292
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
很不错,谢谢分享您的经验
2011-7-19 13:06
0
雪    币: 219
活跃值: (190)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
楼主实在是强大.学习一下先.
2011-8-6 02:09
0
雪    币: 437
活跃值: (110)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
22
支持一个。
2011-8-6 08:13
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
好文,学习了
2011-9-23 09:53
0
雪    币: 43
活跃值: (251)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
24
标记下 以后看
2011-9-23 10:05
0
雪    币: 768
活跃值: (530)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
25
层次分明:)
2011-9-23 10:58
0
游客
登录 | 注册 方可回帖
返回
//