c++winapi

VirtualProtect with PAGE_READONLY not working on variable


I am trying to set a variable to read only with VirtualProtect, however VirtualProtect returns 0 and GetLastError() gives 487 which is attempt to access invalid address. changing myVar = 77 confirms that VirtualProtect errors out.

int myVar = 42;
LPVOID address = &myVar;

SYSTEM_INFO si;
GetSystemInfo(&si);
SIZE_T pageSize = si.dwPageSize;

DWORD oldprotect;
int result = VirtualProtect(address,pageSize,PAGE_READONLY, &oldprotect);

cout << GetLastError() << " " << result << endl;
myVar = 77;
cout << myVar << endl;

Solution

  • Local variables exist on the call stack or in CPU registers (in this case, a register is not used since you are taking the address of the variable). You can't make either one read-only.

    If you dynamically allocate the variable instead, you should then be able to make it read-only (just note that the entire memory page will be read-only, and likely will hold more data than just your variable).

    int *myVar = new int(42);
    
    DWORD oldprotect;
    int result = VirtualProtect(myVar, sizeof(*myVar), PAGE_READONLY, &oldprotect);
    
    cout << GetLastError() << " " << result << endl;
    
    *myVar = 77;
    cout << *myVar << endl;
    
    VirtualProtect(myVar, sizeof(*myVar), oldprotect, &oldprotect);
    delete myVar;