2013-10-19 16 views
7

In MSDN trovo quanto segue`Qual è la differenza tra BaseAddress e AllocationBase nella struttura MEMORY_BASIC_INFORMATION?

BaseAddress - Un puntatore all'indirizzo di base della regione di pagine.

AllocationBase - Un puntatore all'indirizzo di base di un intervallo di pagine assegnato dalla funzione VirtualAlloc. La pagina indicata dal membro BaseAddress è contenuta in questo intervallo di allocazione.

Ma non capisco davvero cosa sia la differenza. Qualcuno può dirmi la differenza? (Non come in MSDN :))

risposta

14

allocazioni di memoria virtuale su Windows sono realizzati con una granularità di 64 kilobyte, il valore di SYSTEM_INFO.dwAllocationGranularity. Ma le pagine di memoria virtuale sono 4096 byte, il valore di SYSTEM_INFO.dwPageSize.

Quando si assegna memoria virtuale con VirtualAlloc, si ottiene sempre un blocco il cui BaseAddress è uguale a AllocationBase. Ma se modifichi la protezione della pagina di una o più pagine all'interno di questo blocco, puoi osservare che questo blocco è suddiviso con un BaseAddress diverso. Miglior mostrato con un programma di esempio, eseguire questo su MSVC++:

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

Esempio di output di questo programma:

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 

E notare come il() chiamata VirtualProtect richiesto il pezzo originale da dividere in 3 regioni con BaseAddress diverso ma lo stesso AllocationBase.