Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling VirtualProtect on a mapped file

Tags:

c

windows

winapi

I'm using the CreateFileMapping and MapViewOfFile functions to map a file into memory. After a certain point, I call VirtualProtect to change its protection from read-only to read and write. This call fails and GetLastError gives ERROR_INVALID_PARAMETER.

Here is a simplified version of my code that demonstrates the problem.

#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;
}

What am I doing wrong here? Am I not allowed to call VirtualProtect on a region containing a mapped file?

like image 667
Evan Shaw Avatar asked Mar 18 '11 00:03

Evan Shaw


2 Answers

Start out by creating the view with FILE_MAP_READ | FILE_MAP_WRITE and protect with PAGE_READONLY. Now you have no trouble making it PAGE_READWRITE later:

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);
like image 63
Hans Passant Avatar answered Sep 20 '22 23:09

Hans Passant


What happens in your code is that VirtualProtectEx (invoked by VirtualProtect of yours) fails with error STATUS_SECTION_PROTECTION (0xC000004E) - "A view to a section specifies a protection that is incompatible with the protection of the initial view" and this seems to be what you did indeed by creating a section view with more restrictive protection (FILE_MAP_READ).

This topic doesn't seem to be documented with enough details, so I think you'd better simply follow what Hans suggested.

like image 27
Andrey Avatar answered Sep 19 '22 23:09

Andrey