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