exist next NT api - NtQueryVirtualMemory
__kernel_entry NTSYSCALLAPI NTSTATUS NtQueryVirtualMemory(
[in] HANDLE ProcessHandle,
[in, optional] PVOID BaseAddress,
[in] MEMORY_INFORMATION_CLASS MemoryInformationClass,
[out] PVOID MemoryInformation,
[in] SIZE_T MemoryInformationLength,
[out, optional] PSIZE_T ReturnLength
);
where MEMORY_INFORMATION_CLASS
can have next values:
enum MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation, // MEMORY_BASIC_INFORMATION
MemoryWorkingSetInformation, // MEMORY_WORKING_SET_INFORMATION
MemoryMappedFilenameInformation, // UNICODE_STRING
MemoryRegionInformation, // MEMORY_REGION_INFORMATION
MemoryWorkingSetExInformation, // MEMORY_WORKING_SET_EX_INFORMATION // since VISTA
MemorySharedCommitInformation, // MEMORY_SHARED_COMMIT_INFORMATION // since WIN8
MemoryImageInformation, // MEMORY_IMAGE_INFORMATION
MemoryRegionInformationEx, // MEMORY_REGION_INFORMATION
MemoryPrivilegedBasicInformation,
MemoryEnclaveImageInformation, // MEMORY_ENCLAVE_IMAGE_INFORMATION // since REDSTONE3
MemoryBasicInformationCapped, // 10
MemoryPhysicalContiguityInformation, // MEMORY_PHYSICAL_CONTIGUITY_INFORMATION // since 20H1
MemoryBadInformation, // since WIN11
MemoryBadInformationAllProcesses, // since 22H1
MaxMemoryInfoClass
} ;
both VirtualQueryEx
and QueryVirtualMemoryInformation
is thin shell over NtQueryVirtualMemory
.
the VirtualQueryEx
call NtQueryVirtualMemory
with MemoryInformationClass = MemoryBasicInformation
SIZE_T
WINAPI
VirtualQueryEx(
_In_ HANDLE hProcess,
_In_opt_ LPCVOID VirtualAddress,
_Out_writes_bytes_to_(dwLength,return) PMEMORY_BASIC_INFORMATION lpBuffer,
_In_ SIZE_T dwLength
)
{
NTSTATUS status = NtQueryVirtualMemory(hProcess, VirtualAddress, MemoryBasicInformation, dwLength, &dwLength);
if (0 > status)
{
RtlNtStatusToDosError(status);
return 0;
}
return dwLength;
}
the QueryVirtualMemoryInformation
call NtQueryVirtualMemory
with MemoryInformationClass = MemoryRegionInformationEx
. despite MemoryInformationClass
parameter still exist, it accept only single value.
BOOL
WINAPI
QueryVirtualMemoryInformation(
_In_ HANDLE Process,
_In_ const VOID* VirtualAddress,
_In_ WIN32_MEMORY_INFORMATION_CLASS MemoryInformationClass,
_Out_writes_bytes_(MemoryInformationSize) PVOID MemoryInformation,
_In_ SIZE_T MemoryInformationSize,
_Out_opt_ PSIZE_T ReturnSize
)
{
NTSTATUS status = MemoryRegionInfo != MemoryInformationClass ? STATUS_INVALID_INFO_CLASS :
NtQueryVirtualMemory(hProcess, VirtualAddress, MemoryRegionInformationEx, MemoryInformationSize, ReturnSize);
if (0 > status)
{
RtlNtStatusToDosError(status);
return FALSE;
}
return TRUE;
}
so because in both case the same NT api called internal - this 2 win32 api very similar.