bool NTQUERYVIRTUALMEMORY__ (int PID)
{
BOOLEAN querySucceeded; // cha询结果状态(未实际使用)
PVOID64 baseAddress; // 当前cha询的内存基地址
MEMORY_BASIC_INFORMATION basicInfo; // 存储内存基础信息的结构体
// 动态加载ntdll.dll获取NtQueryVirtualMemory函数地址
HMODULE hModule = LoadLibrary (L"ntdll.dll");
auto NtQueryVirtualMemory = (NTQUERYVIRTUALMEMORY)GetProcAddress (hModule, "NtQueryVirtualMemory");
FreeLibrary (hModule); // 立即释放DLL
baseAddress = (PVOID)0; // 从地址0开始遍历内存区域
// 打开目标进程(PID=4588),请求cha询权限和内存读取权限
HANDLE processHandle = OpenProcess (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, PID);
std::cout << processHandle << endl;
if (NULL == processHandle) {
// 如果失败,尝试仅用cha询权限再次打开
processHandle = OpenProcess (PROCESS_QUERY_INFORMATION, 0, PID);
if (NULL == processHandle) {
std::cout << processHandle << endl;
//return -1; // 完全失败则退出程序
}
}
// 循环遍历进程内存区域
while (NT_SUCCESS (NtQueryVirtualMemory (
processHandle,
baseAddress,
MemoryBasicInformation, // cha询基础信息
&basicInfo, // 输出到basicInfo结构体
sizeof (MEMORY_BASIC_INFORMATION),
NULL
))) {
do { // 使用do-while实现一次性循环,方便用break跳过逻辑
if ( (basicInfo.State & MEM_FREE) == MEM_FREE) {
break; // 跳过空闲内存区域
}
// 打印内存块基本信息
printf ("基地址 :%I64x 区域大小: %x", baseAddress, basicInfo.RegionSize);
// 调试断点(当扫描到0x60000地址时触发调试器)
if ( (ULONG)baseAddress == 0x60000) {
DebugBreak ();
}
// cha询共享提交信息
MEMORY_SHARED_COMMIT_INFORMATION sharedCommitInfo;
NTSTATUS sharedStatus = NtQueryVirtualMemory (
processHandle,
baseAddress,
MemorySharedCommitInformation,
&sharedCommitInfo,
sizeof (sharedCommitInfo),
NULL
);
if (NT_SUCCESS (sharedStatus)) {
printf (" 共享页面: %I64u", sharedCommitInfo.SharedCommitUsage);
}
else {
printf (" 共享页面: N/A (0x%X)", sharedStatus);
}
// 解析内存保护属性
if ( (basicInfo.AllocationProtect & PAGE_EXECUTE_WRITECOPY) == PAGE_EXECUTE_WRITECOPY) {
printf (" PAGE_EXECUTE_WRITECOPY 可执行写入复制页");
}
if ( (basicInfo.AllocationProtect & PAGE_NOACCESS) == PAGE_NOACCESS) {
printf (" PAGE_NOACCESS 禁止访问");
}
if ( (basicInfo.AllocationProtect & PAGE_EXECUTE) == PAGE_EXECUTE) {
printf (" PAGE_EXECUTE 执行");
}
if ( (basicInfo.AllocationProtect & PAGE_READONLY) == PAGE_READONLY) {
printf (" PAGE_READONLY 只读");
}
if ( (basicInfo.AllocationProtect & PAGE_READWRITE) == PAGE_READWRITE) {
printf (" PAGE_READWRITE 读写");
}
// 解析内存状态
if ( (basicInfo.State & MEM_COMMIT) == MEM_COMMIT) {
printf (" MEM_COMMIT 已提交内存"); // 已提交内存
}
if ( (basicInfo.State & MEM_RESERVE) == MEM_RESERVE) {
printf (" MEM_RESERVE 保留内存"); // 保留内存
}
// 解析内存类型
if ( (basicInfo.Type & MEM_PRIVATE) == MEM_PRIVATE) {
printf (" MEM_PRIVATE 私有内存(进程独占)"); // 私有内存(进程独占)
}
if ( (basicInfo.Type & MEM_MAPPED) == MEM_MAPPED) {
printf (" MEM_MAPPED 内存映射文件"); // 内存映射文件
}
if ( (basicInfo.Type & MEM_IMAGE) == MEM_IMAGE) { // 原代码有误,应为MEM_IMAGE
printf (" MEM_IMAGE 可执行镜像 "); // 可执行镜像
}
printf ("\n\n");
} while (0);
// 移动到下一个内存区域
baseAddress = (PVOID64) ( (ULONG64)baseAddress + basicInfo.RegionSize);
}
getchar (); // 暂停程序,防止控制台关闭
return 0;
}