如何在Minifilter驱动的IRP中获取操作文件路径?

文件路径

在minifilter中,主要处理的是各种IRP,做DLP也好,做加解密也好。文件路径总是绕不开的。比如在IRP_MJ_WRITE中,绝大多数情况都得知道当前这次操作的文件路径。

普通办法

Minifilter框架有个函数:FltGetFileNameInformation
这个函数可以用来获取文件路径,比如下面是段常用的获取文件路径的代码

UNICODE_STRING ExtractFileName(_In_ PFLT_CALLBACK_DATA Data)
{
	NTSTATUS status;
	UNICODE_STRING ret = { 0 };

    KIRQL irql = KeGetCurrentIrql();
    if (irql > APC_LEVEL) {
        PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
            ("OOOOOOOOOOOOOOPS, IRQL > APC_LEVEL, Can't call FltGetFileNameInformation. current irql: %d\n", irql));
        return ret;
    }

	if (Data)
	{
		PFLT_FILE_NAME_INFORMATION  pNameInfo = NULL;

		status = FltGetFileNameInformation(Data,
			FLT_FILE_NAME_NORMALIZED |
			FLT_FILE_NAME_QUERY_DEFAULT,
			&pNameInfo);                              // <= APC_LEVEL

		if (NT_SUCCESS(status) && pNameInfo)
		{
            status = FltParseFileNameInformation(pNameInfo);
            if (NT_SUCCESS(status))   // <= APC_LEVEL
            {
                Init(&ret, pNameInfo->Name.MaximumLength);
                CopyUnicodeString(&ret, &(pNameInfo->Name));
            }
            else {
                PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
                    ("Calling FltParseFileNameInformation() failed, err: %d\n", status));
            }

			FltReleaseFileNameInformation(pNameInfo);  // <= APC_LEVEL
		}
	}

	return ret;
}

ok,那么这么就完了吗?对于普通WRITE请求,确实可以。比如WriteFile触发的IRP.
但是如何是FileMapping,你就会发现FltGetFileNameInformation会失败。
查一下msdn就会发现:
在这里插入图片描述
其中有一条,FileGetNameInformation cannot get file name information in the paging I/O path.
好,FileMapping就是paging IO, 所以失败。

如何获取FileMapping操作在IRP_MJ_WRITE等IRP中的文件路径呢?

既然直接获取不到,那么就曲线救国呗。
一般FileMapping的写法如下:

void TestIOFileMapping() {
    HANDLE  hFile;
    hFile = CreateFile(L"testfilemapping.foo",
        GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        return;
    }

    HANDLE hMapping = CreateFileMapping(hFile,
        NULL,
        PAGE_READWRITE,
        0,
        MAX_FILESIZE,
        NULL);

    if (hMapping == NULL)
    {
        CloseHandle(hFile);
        return;
    }

    char* puchData = (char*)MapViewOfFile(hMapping,
        FILE_MAP_WRITE,
        0,
        0,
        0);

    if (puchData == NULL)
    {
        CloseHandle(hMapping);
        CloseHandle(hFile);
        return;
    }

    for (int i = 0; i < 10; i++)
    {
        OutputDebugStringW(L"Try to write data with memset()");
        memset(puchData + i * 1024, 0x41 + i, 1024);
    }

    UnmapViewOfFile(puchData);

//    FlushFileBuffers(hFile);
    CloseHandle(hMapping);
    CloseHandle(hFile);
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值