【问题标题】:Calling VirtualProtect on a mapped file在映射文件上调用 VirtualProtect
【发布时间】:2011-03-18 00:49:08
【问题描述】:

我正在使用 CreateFileMapping 和 MapViewOfFile 函数将文件映射到内存中。在某一点之后,我调用 VirtualProtect 将其保护从只读更改为读写。此调用失败,GetLastError 给出 ERROR_INVALID_PARAMETER。

这是我演示问题的代码的简化版本。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main() {
    HANDLE fd, md;
    char *addr;
    DWORD old;
    BOOL ok;

    fd = CreateFile("filename", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    md = CreateFileMapping(fd, NULL, PAGE_READWRITE, 0, 100, NULL);
    addr = MapViewOfFile(md, FILE_MAP_READ, 0, 0, 100);
    ok = VirtualProtect(addr, 100, PAGE_READWRITE, &old);
    if (!ok) {
        // we fall into this if block
        DWORD err = GetLastError();
        // this outputs "error protecting: 87"
        printf("error protecting: %u\n", err);
        return 1;
    }
    UnmapViewOfFile(addr);
    CloseHandle(md);
    CloseHandle(fd);
    return 0;
}

我在这里做错了什么?我是否不允许在包含映射文件的区域上调用 VirtualProtect?

【问题讨论】:

  • 之前的函数是否返回了预期值?我意识到您只发布了一个 sn-p ...但请确保您测试来自 MapViewOfFile、CreateFileMapping、CreateFile、...的 ALL 返回值...
  • 是的,我确信其他功能没有失败。为简单起见,我省略了其他错误检查。

标签: c windows winapi


【解决方案1】:

首先使用 FILE_MAP_READ | 创建视图FILE_MAP_WRITE 并使用 PAGE_READONLY 进行保护。现在您可以轻松地稍后将其设为 PAGE_READWRITE:

addr = MapViewOfFile(md, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 100);
ok = VirtualProtect(addr, 100, PAGE_READONLY, &old);
//...
ok = VirtualProtect(addr, 100, PAGE_READWRITE, &old);

【讨论】:

  • 好的,所以我想以将来可能需要的最大访问权限调用 CreateFileMapping 和 MapViewOfFile。我要补充一点:如果我不是最初打开文件句柄的人,有没有办法找出该文件句柄上可用的最高访问级别?
  • A FALSE return 和 GetLastError() 告诉你,同样的想法。
  • 您是否建议我先尝试最高访问权限,然后再降低到不会给我错误的最低访问权限?我想这可能行得通,但似乎应该有更好的方法。
  • 另外,在hostile environment :-) - 在尝试 VirtualProtect 之前,您可以调用 VirtualQuery 并查看原始内存保护选项(MEMORY_BASIC_INFORMATION 结构的 AllocationProtect 成员)
【解决方案2】:

在您的代码中发生的情况是 VirtualProtectEx(由您的 VirtualProtect 调用)失败并出现错误 STATUS_SECTION_PROTECTION (0xC000004E) - “一个部分的视图指定了一个保护与初始视图的保护不兼容”,这似乎是您通过创建具有更多限制性保护 (FILE_MAP_READ) 的剖面视图所做的事情。

这个话题似乎没有足够的细节记录,所以我认为你最好按照汉斯的建议去做。

【讨论】:

    【解决方案3】:

    根据http://msdn.microsoft.com/en-us/library/aa366556(v=vs.85).aspx,这应该是合法的。根据 VirtualProtect 文档,新标志必须与“VirtualAlloc”标志兼容——如果这转移到“MapViewOfFile”标志,我怀疑你可以加强但不能放松保护。尝试将读写映射并将保护更改为只读。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 1970-01-01
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 2017-04-03
      • 1970-01-01
      相关资源
      最近更新 更多