Windows上の仮想メモリ割り当ては、64 KBの粒度で行われます。これはSYSTEM_INFO.dwAllocationGranularityの値です。しかし、仮想メモリページはSYSTEM_INFO.dwPageSizeの値である4096バイトです。
VirtualAllocで仮想メモリを割り当てると、BaseAddressがAllocationBaseに等しいチャンクバックが常に得られます。しかし、このチャンク内の1つ以上のページのページ保護を変更すると、このチャンクが別のBaseAddressで細分されていることがわかります。このプログラムの
#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
void showmem(void* mem) {
MEMORY_BASIC_INFORMATION info = {};
VirtualQuery(mem, &info, sizeof info);
printf("Alloc = %p, base = %p, size = %d, protect = %d\n",
info.AllocationBase, info.BaseAddress, info.RegionSize, info.Protect);
}
int main() {
BYTE* mem = (BYTE*)VirtualAlloc(0, 65536, MEM_COMMIT, PAGE_READWRITE);
printf("%s", "Initial allocation:\n");
showmem(mem);
DWORD oldprotect;
BOOL ok = VirtualProtect(mem + 4096, 4096, PAGE_NOACCESS, &oldprotect);
printf("%s", "\nAfter protection changes:\n");
showmem(mem);
showmem(mem + 4096);
showmem(mem + 4096 + 4096);
_getch();
return 0;
}
サンプル出力:
Initial allocation:
Alloc = 00ED0000, base = 00ED0000, size = 65536, protect = 4
After protection changes:
Alloc = 00ED0000, base = 00ED0000, size = 4096, protect = 4
Alloc = 00ED0000, base = 00ED1000, size = 4096, protect = 1
Alloc = 00ED0000, base = 00ED2000, size = 57344, protect = 4
とVirtualProtect()呼び出しは、元のチャンクが3つの領域に分割する必要がどのように注意してベストMSVC++でこれを実行して、サンプルプログラムを示しましたBaseAddressは異なるが、同じAllocationBaseを持つ。