QQ u don't learn le 2018-05-09 14:23 采纳率: 66.7%
浏览 3334
已结题

WindowsMiniFilter 文件过滤驱动开发之文件操作

最近一直在做操作系统的大作业,作业的要求是开发一个Windows文件过滤驱动,对某一个文本文件xxxx.txt进行保护。首先,驱动要读取权限记录文件user.txt,文件内记录有read_false/read_true,write_false/write_true,delete_false/delete_true,每个文件记录有三个操作的其中一个,true或者false,
图片说明
然后驱动在根据相应的权限进行下一步操作。
我们现在遇到的问题是,可以对文本文件xxxx.txt进行相应的保护,即防止删除,防止写,防止读,但是问题在于读取不了权限记录文件.我们使用的是FLTxxxFile()系列函数。但是每次驱动运行后,电脑马上就蓝屏了。。。
具体代码如下:(环境:Visual Studio2017)
1.先放出一个IRP_MJ_WRITE,pre函数为WritePreOperation()
图片说明
2.读取权限文件的相关函数ReadFileTest(PVOID buffer)
打开权限文件,然后读取内容到buffer.

 NTSTATUS ReadFileTest(PVOID buffer)

{
    NTSTATUS status = STATUS_UNSUCCESSFUL;

    //PVOID buffer = NULL;

    ULONG total_len = 0;

    ULONG readbytes = 0;

    ULONG byteswritten = 0;

    HANDLE FileHandle = NULL;

    PFILE_OBJECT FileObject = NULL;

    OBJECT_ATTRIBUTES ObjectAttributes;

    IO_STATUS_BLOCK IoStatus;

    PFLT_VOLUME Volume = NULL;

    PFLT_INSTANCE Instance = NULL;

    PUNICODE_STRING FullFileName = NULL;
    RtlInitUnicodeString(FullFileName, L"\C:\user.txt");
    InitializeObjectAttributes(
        &ObjectAttributes,
        FullFileName,
        OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
        NULL,
        NULL
    );
    status = FltCreateFileEx(
        gFilterHandle,
        Instance,
        &FileHandle,
        &FileObject,
        GENERIC_READ,
        &ObjectAttributes,
        &IoStatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        FILE_OPEN,
        FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY | FILE_COMPLETE_IF_OPLOCKED,
        NULL,
        0,
        IO_NO_PARAMETER_CHECKING
    );

    if (FileObject)
    {
        //read the file
        //get the volume
        status = FltGetVolumeFromFileObject(gFilterHandle, FileObject, &Volume);
        if (NT_SUCCESS(status))
        {
            status = FltGetVolumeInstanceFromName(
                gFilterHandle,
                Volume,
                NULL,
                &Instance
            );
            //  if (NT_SUCCESS(status))
            //  {
            //      while (STATUS_END_OF_FILE != FltReadFile(Instance, FileObject, NULL, 4096,
            //          buffer, FLTFL_IO_OPERATION_NON_CACHED, &readbytes, NULL, NULL))
            //      {
            //          total_len += readbytes;
            //          PT_DBG_PRINT(PTDBG_TRACE_ROUTINES, ("SSMF:Read length is %u,total len is %u\n", readbytes, total_len));
            //          FltWriteFile(Instance, FileObject2, NULL, readbytes, buffer, FLTFL_IO_OPERATION_NON_CACHED, &byteswritten, NULL, NULL);
            //      }
            //  }

            FltReadFile(Instance, FileObject, NULL, 4096,
                buffer, FLTFL_IO_OPERATION_NON_CACHED, &readbytes, NULL, NULL);

            if (Volume)
            {
                FltObjectDereference(Volume);
            }
            if (Instance)
            {
                FltObjectDereference(Instance);
            }

        }
        if (FileObject)
        {
            FltClose(FileHandle);
            ObDereferenceObject(FileObject);
        }
        return status;
    }
}

3.WritePreOperation()
我们是这样想的,得到在函数ReadFileTest中读取到了内容的buffer,然后再调用wcsstr(buffer,L"WRITE_FALSE") 看看buffer 里面有没有相应的权限子串,再进行相应的操作。

 FLT_PREOP_CALLBACK_STATUS
WritePreOperation(
    _Inout_ PFLT_CALLBACK_DATA Data,
    _In_ PCFLT_RELATED_OBJECTS FltObjects,
    _Flt_CompletionContext_Outptr_ PVOID *CompletionContext
)
{
    UNREFERENCED_PARAMETER(FltObjects);
    UNREFERENCED_PARAMETER(CompletionContext);
    PAGED_CODE();
    {
        PFLT_FILE_NAME_INFORMATION nameInfo;
        WCHAR buffer[64] = { 0 };
        ReadFileTest(buffer);

        //直接获得文件名并检查  
        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);
                _wcsupr(buffer);
                if (NULL != wcsstr(pTemp, L"XXXX.TXT")&& NULL != wcsstr(buffer,L"WRITE_FALSE"))
                {
                    if (NULL != pNonPageBuf)
                        ExFreePool(pNonPageBuf);
                    if (buffer != NULL)
                        {
                        ExFreePool(buffer);
                        }
                    FltReleaseFileNameInformation(nameInfo);
                    return FLT_PREOP_DISALLOW_FASTIO;
                }
                if (NULL != pNonPageBuf)
                    ExFreePool(pNonPageBuf);
                if (buffer != NULL)
                    {
                        ExFreePool(buffer);
                    }
            }
            FltReleaseFileNameInformation(nameInfo);
        }
    }
    return FLT_PREOP_SUCCESS_NO_CALLBACK;
}

工程全景:
代码都是在cFilter.c里面写的,然后测试环境是虚拟机Windows7,没有读取权限文件操作时,可以进行相应的保护,加上后,一运行就蓝屏了。还望有高人指导~
图片说明

  • 写回答

1条回答 默认 最新

  • devmiao 2018-05-09 14:43
    关注
    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!