| | | | lpBuffer As MEMORY_BASIC_INFORMATION, _ ByVal dwLength As Long _ ) As Long | | | | | | There is also VirtualQueryEx, an extended version of VirtualQuery that permits looking at foreign virtual address spaces: | | DWORD VirtualQueryEx( HANDLE hProcess, // handle to process LPCVOID lpAddress, // address of region PMEMORY_BASIC_INFORMATION lpBuffer, // address of information buffer DWORD dwLength // size of buffer ); | | | | Declare Function VirtualQueryEx Lib "kernel32" ( _ ByVal hProcess As Long, _ ByVal lpAddress As Long, _ lpBuffer As MEMORY_BASIC_INFORMATION, _ ByVal dwLength As Long _ ) As Long | | | | | | As expected, the hProcess parameter requires a process handle. The lpAddress parameter is the starting address on which to report, but it will be rounded down to the closest multiple of the page size (4KB). Both functions return information in the structure: | | struct _MEMORY_BASIC_INFORMATION { PVOID BaseAddress; // base address of region PVOID AllocationBase; // allocation base address DWORD AllocationBase; // initial access protection DWORD RegionSize; // size, in bytes, of region DWORD State; // committed, reserved, free DWORD Protect; // current access protection DWORD Type; // type of pages } Type MEMORY_BASIC_INFORMATION BaseAddress As Long base address of region AllocationBase As Long allocation base address AllocationProtect As Long initial access protection RegionSize As Long size, in bytes, of region State As Long committed, reserved, free Protect As Long current access protection Type As Long type of pages End type | | | | To understand the members of this structure, we need to describe what the function does. Unfortunately, the documentation does a rotten job of explaining this function, but it appears to perform as follows. To aid our discussion, let us refer to the page containing the address lpAddress as the specified page. Figure 13-11 will help define our terms. | | |