首页
社区
课程
招聘
基于文件过滤驱动的文件保护问题
发表于: 2014-6-8 21:07 8860

基于文件过滤驱动的文件保护问题

2014-6-8 21:07
8860
FLT_PREOP_CALLBACK_STATUS
NPPreWrite
(
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
);

FLT_POSTOP_CALLBACK_STATUS
NPPostWrite
(
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in_opt PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags
);

//operation registration
const FLT_OPERATION_REGISTRATION Callbacks[] =
{
        {
                IRP_MJ_CREATE,
                0,
                NPPreCreate,
                NPPostCreate
        },
        {
                IRP_MJ_SET_INFORMATION,
                0,
                NPPreSetInformation,
                NPPostSetInformation
        },
        {
                IRP_MJ_READ,
                0,
                NPPreRead,
                NPPostRead
        },
        {
                IRP_MJ_WRITE,
                0,
                NPPreWrite,
                NPPostWrite
        },
        {
                IRP_MJ_OPERATION_END
        }
};

FLT_POSTOP_CALLBACK_STATUS NPPostWrite
(
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in_opt PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags
)
{
        return FLT_POSTOP_FINISHED_PROCESSING;
}

FLT_PREOP_CALLBACK_STATUS NPPreWrite
(
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
)
{
        UNREFERENCED_PARAMETER( FltObjects );
        UNREFERENCED_PARAMETER( CompletionContext );
        PAGED_CODE();
        {
                PFLT_FILE_NAME_INFORMATION nameInfo;
                //直接获得文件名并检查
                if( NT_SUCCESS( FltGetFileNameInformation( Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo ) ) )
                {
                        if( NT_SUCCESS( FltParseFileNameInformation( nameInfo ) ) )
                        {
                                WCHAR pTempBuf[ 512 ] = { 0 };
                                WCHAR *pNonPageBuf = NULL, *pTemp = pTempBuf;
                                if( nameInfo->Name.MaximumLength > 512 )
                                {
                                        pNonPageBuf = ExAllocatePool( NonPagedPool, nameInfo->Name.MaximumLength );
                                        pTemp = pNonPageBuf;
                                }
                                RtlCopyMemory( pTemp, nameInfo->Name.Buffer, nameInfo->Name.MaximumLength );
                                DbgPrint("[MiniFilter][IRP_MJ_WRITE]%wZ", &nameInfo->Name);
                                _wcsupr( pTemp );
                                if( NULL != wcsstr( pTemp, L"README.TXT" ) )  // 检查是不是要保护的文件
                                {
                                        //DbgPrint( "\r\nIn NPPreWrite(), FilePath{%wZ} is forbided.", &nameInfo->Name );
                                        if( NULL != pNonPageBuf )
                                                ExFreePool( pNonPageBuf );
                                        FltReleaseFileNameInformation( nameInfo );
                                        return FLT_PREOP_DISALLOW_FASTIO;
                                }
                                if( NULL != pNonPageBuf )
                                        ExFreePool( pNonPageBuf );
                        }
                        FltReleaseFileNameInformation( nameInfo );
                }
        }
        return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

部分关键代码,涉及到写文件内容方面的
驱动安装,加载后,手工对这个README.TXT修改可以拦截.用WINHEX修改也可以拦截.
但是用ASP脚本对这个README.TXT修改,虽然可以拦截,但是会将原来的内容清空.导致文件大小为0.
不知道还要处理什么?

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

收藏
免费 0
支持
分享
最新回复 (13)
雪    币: 796
活跃值: (1561)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
帮不上什么忙   顶一下
2014-6-8 23:21
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我目前只能感谢帮我顶的那位兄弟了
2014-6-9 14:13
0
雪    币: 3107
活跃值: (1249)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
4
不用看了,估计是在create的时候,truncate掉了
2014-6-9 14:45
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
FLT_POSTOP_CALLBACK_STATUS NPPostCreate
(
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __in_opt PVOID CompletionContext,
    __in FLT_POST_OPERATION_FLAGS Flags
)
{
        return FLT_POSTOP_FINISHED_PROCESSING;
}

FLT_PREOP_CALLBACK_STATUS NPPreCreate
(
    __inout PFLT_CALLBACK_DATA Data,
    __in PCFLT_RELATED_OBJECTS FltObjects,
    __deref_out_opt PVOID *CompletionContext
)
{
        UNREFERENCED_PARAMETER( FltObjects );
        UNREFERENCED_PARAMETER( CompletionContext );
        PAGED_CODE();
        {
                UCHAR MajorFunction = 0;
                ULONG Options = 0;
                PFLT_FILE_NAME_INFORMATION nameInfo;
                MajorFunction = Data->Iopb->MajorFunction;
                Options = Data->Iopb->Parameters.Create.Options;
                //如果是IRP_MJ_CREATE,且选项是FILE_DELETE_ON_CLOSE,并且能成功获得文件名信息
                if( IRP_MJ_CREATE == MajorFunction && FILE_DELETE_ON_CLOSE == Options &&
                        NT_SUCCESS( FltGetFileNameInformation( Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo ) ) )
                {
                        //如果解析文件信息成功
                        if( NT_SUCCESS( FltParseFileNameInformation( nameInfo ) ) )
                        {
                                WCHAR pTempBuf[ 512 ] = { 0 };
                                WCHAR *pNonPageBuf = NULL, *pTemp = pTempBuf;
                                if( nameInfo->Name.MaximumLength > 512 )
                                {
                                        pNonPageBuf = ExAllocatePool( NonPagedPool, nameInfo->Name.MaximumLength );
                                        pTemp = pNonPageBuf;
                                }
                                RtlCopyMemory( pTemp, nameInfo->Name.Buffer, nameInfo->Name.MaximumLength );
                                DbgPrint("[MiniFilter][IRP_MJ_CREATE]%wZ", &nameInfo->Name);
                                _wcsupr( pTemp );
                                if( NULL != wcsstr( pTemp, L"README.TXT" ) )  // 检查是不是要保护的文件
                                {
                                        //DbgPrint( "\r\nIn NPPreCreate(), FilePath{%wZ} is forbided.", &nameInfo->Name );
                                        if( NULL != pNonPageBuf )
                                                ExFreePool( pNonPageBuf );
                                        FltReleaseFileNameInformation( nameInfo );
                                        return FLT_PREOP_COMPLETE;
                                }
                                if( NULL != pNonPageBuf )
                                        ExFreePool( pNonPageBuf );
                        }
                        FltReleaseFileNameInformation( nameInfo );
                }
        }
        return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

拦截create的代码

不知道怎么修改呢?
2014-6-9 15:05
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
6
precreate判断打开是不是用下面的标志
        case FILE_SUPERSEDE:
        case FILE_OVERWRITE:
        case FILE_OVERWRITE_IF:
2014-6-9 15:36
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
UCHAR MajorFunction = 0;
                ULONG Options = 0;
                ULONG i;
                PFLT_FILE_NAME_INFORMATION nameInfo;
                MajorFunction = Data->Iopb->MajorFunction;
                Options = Data->Iopb->Parameters.Create.Options;
                //如果是IRP_MJ_CREATE,且选项是FILE_DELETE_ON_CLOSE,并且能成功获得文件名信息
                //                if( IRP_MJ_CREATE == MajorFunction && FILE_DELETE_ON_CLOSE == Options &&
                //                        NT_SUCCESS( FltGetFileNameInformation( Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo ) ) )
               
                if( IRP_MJ_CREATE == MajorFunction &&
                        NT_SUCCESS( FltGetFileNameInformation( Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo ) ) )
                {
                        if (
                                FILE_OPEN_IF== Options ||
                                FILE_CREATE== Options ||
                                FILE_DELETE_ON_CLOSE == Options ||
                                FILE_SUPERSEDE == Options ||  //新建/覆盖文件
                                FILE_OVERWRITE == Options ||   //覆盖文件
                                FILE_MAXIMUM_DISPOSITION == Options || //打开并覆盖
                                FILE_OVERWRITE_IF == Options   //不删除老文件,只是清空它的内容
                                )
                               
                               
                        {
                                //如果解析文件信息成功
                                if( NT_SUCCESS( FltParseFileNameInformation( nameInfo ) ) )
                                {
                                        WCHAR pTempBuf[ 512 ] = { 0 };
                                        WCHAR *pNonPageBuf = NULL, *pTemp = pTempBuf;
                                        if( nameInfo->Name.MaximumLength > 512 )
                                        {
                                                pNonPageBuf = ExAllocatePool( NonPagedPool, nameInfo->Name.MaximumLength );
                                                pTemp = pNonPageBuf;
                                        }
                                        RtlCopyMemory( pTemp, nameInfo->Name.Buffer, nameInfo->Name.MaximumLength );
                                        DbgPrint("[MiniFilter][IRP_MJ_CREATE]%wZ", &nameInfo->Name);
                                        _wcslwr( pTemp );
                                       

FLT_PREOP_CALLBACK_STATUS NPPreCreate  那处我这样改的,还是不行
2014-6-9 17:16
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
求大牛指点,到底应该怎么改?
2014-6-10 12:10
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
过了好几天了,不会无解了吧?
2014-6-11 12:17
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
而且测试在访问频繁的机器上,会把机器卡死
2014-6-22 05:49
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
11
必要的时候把Irp中相应的Flags或者Options的值修改掉,去除OVERWRITE等标志,然后callback 返回 FLT_PREOP_SUCCESS_NO_CALLBACK
没用过MiniFilter,不清楚调用PreCreate的时候,文件是否已经创建,如果未创建,这个方法应该会有效果,LZ试试看。
2014-6-22 07:49
0
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
PreCreate中判断是否以写权限打开而且是被保护的文件,如果是直接拒绝。光判断Options是不行的,还要判断DesiredAccess,
BOOLEAN IsFileOpenWrite = (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES))!=0;
2014-6-22 09:30
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
多谢LS的2位兄弟提醒!
现在的问题,在服务器上跑几个小时,机器就卡死了.

WCHAR pTempBuf[ 512 ] = { 0 };
        WCHAR *pNonPageBuf = NULL, *pTemp = pTempBuf;
        if( nameInfo->Name.MaximumLength > 512 )
        {
          pNonPageBuf = ExAllocatePool( NonPagedPool, nameInfo->Name.MaximumLength );
          pTemp = pNonPageBuf;
        }
        RtlCopyMemory( pTemp, nameInfo->Name.Buffer, nameInfo->Name.MaximumLength );
        DbgPrint("[MiniFilter][IRP_MJ_WRITE]%wZ", &nameInfo->Name);
        _wcsupr( pTemp );

这块申请未分页内存的原因?
2014-6-22 14:31
0
雪    币: 220
活跃值: (701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
突然发现外面放的代码,可以实现的功能有,但是能用的住的,没发现
2014-6-23 06:29
0
游客
登录 | 注册 方可回帖
返回
//