虚拟内存遍历 VMView
来源:互联网 发布:苹果手机安装不了淘宝 编辑:程序博客网 时间:2024/04/30 08:57
本代码由15PB创始人A1Pass原创,网络资源稀少,转载请注明出处,尊重作者劳动成果!
VMQuery.h:
#pragma once#include <windows.h>#include <vector>using std::vector;typedef struct _VMQUERYEX{ int nRgnSize; // 预定区域大小 DWORD dwRgnStorage; // 预划分区域的物理存储器类型(MEM_*: Free, Image, Mapped, Private) DWORD dwRgnBlocks; // 区域中块的数量 DWORD dwRgnGuardBlks; // 具有PAGE_GUARD保护属性的块的数量,如果>0,则此区域是为线程栈而预定的 BOOL bRgnIsAStack; // 此区域是否包含线程栈,是的话则此区域是为线程栈而预定的}VMQUERYEX;typedef struct _VMQUERY{ // 区域信息 PVOID lpRgnBaseAddress; // 预划分内存区域的起始地址 DWORD dwRgnProtection; // 预划分此内存区域时的原始保护属性(PAGE_*) int nRgnSize; // 预划分区域大小 DWORD dwRgnStorage; // 预划分区域的物理存储器类型(MEM_*: Free, Image, Mapped, Private) DWORD dwRgnBlocks; // 预划分区域中块的数量 DWORD dwRgnGuardBlks; // 具有PAGE_GUARD保护属性的块的数量,如果>0,则此区域是为线程栈而预定的 BOOL bRgnIsAStack; // 此区域是否包含线程栈,是的话则此区域是为线程栈而预定的 // 块信息 PVOID lpBlkBaseAddress; // 内存块的起始地址 DWORD dwBlkProtection; // 内存块的保护属性(PAGE_*) int nBlkSize; // 内存块的大小 DWORD dwBlkStorage; // 内存块的存储类型(MEM_*: Free, Reserve, Image, Mapped, Private) // 文本信息 BOOL bIsExpandInfo; // 此条信息是否为区域展开后的块信息 WCHAR szRgnBaseAddress[16]; // [文本]预划分内存区域的起始地址 WCHAR szRgnProtection[16]; // [文本]原始保护属性 WCHAR szRgnSize[16]; // [文本]区域大小 WCHAR szRgnStorage[16]; // [文本]物理存储器类型 WCHAR szRgnBlocks[8]; // [文本]块的数量 WCHAR szRgnGuardBlks[8]; // [文本]具有PAGE_GUARD保护属性的块的数量 WCHAR szBlkBaseAddress[10]; // [文本]内存块的起始地址 WCHAR szBlkProtection[16]; // [文本]内存块的保护属性 WCHAR szBlkSize[16]; // [文本]内存块的大小 WCHAR szBlkStorage[16]; // [文本]内存块的存储类型} VMQUERY, *PVMQUERY;class CVMQuery{public: CVMQuery(); ~CVMQuery();public: BOOL GetVMInfo(HANDLE hProcess, LPCVOID lpAddress, PVMQUERY pVMQ);protected: BOOL GetVMBlockInfo(HANDLE hProcess, LPCVOID lpAddress, VMQUERYEX *pVMBlock); void GetProtectText(DWORD dwProtect, PTSTR szBuf, int nSize, BOOL bShowFlags); void GetMemStorageText(DWORD dwStorage, PTSTR szBuf, int nSize);private: vector<VMQUERY> m_vecVMInfoList;};
#include "stdafx.h"#include "VMQuery.h"#include <Strsafe.h>CVMQuery::CVMQuery(){}CVMQuery::~CVMQuery(){}void CVMQuery::GetProtectText(DWORD dwProtect, PTSTR szBuf, int nSize, BOOL bShowFlags){ PCTSTR p = L"[Unknown]"; switch ( dwProtect & ~(PAGE_GUARD|PAGE_NOCACHE|PAGE_WRITECOMBINE) ) { case PAGE_READONLY: p = L"[ -R-- ]"; break; case PAGE_READWRITE: p = L"[ -RW- ]"; break; case PAGE_WRITECOPY: p = L"[ -RWC ]"; break; case PAGE_EXECUTE: p = L"[ E--- ]"; break; case PAGE_EXECUTE_READ: p = L"[ ER-- ]"; break; case PAGE_EXECUTE_READWRITE: p = L"[ ERW- ]"; break; case PAGE_EXECUTE_WRITECOPY: p = L"[ ERWC ]"; break; case PAGE_NOACCESS: p = L"[ ---- ]"; break; } StringCchCopy(szBuf, nSize, p); if (bShowFlags) { StringCchCat(szBuf, nSize, L" "); StringCchCat(szBuf, nSize, (dwProtect&PAGE_GUARD) ? L"G":L"-"); StringCchCat(szBuf, nSize, (dwProtect&PAGE_NOCACHE) ? L"N":L"-"); StringCchCat(szBuf, nSize, (dwProtect&PAGE_WRITECOMBINE) ? L"W":L"-"); }}void CVMQuery::GetMemStorageText(DWORD dwStorage, PTSTR szBuf, int nSize){ PCTSTR p = L"Unknown"; switch (dwStorage) { case MEM_FREE: p = L"Free "; break; // 闲置:未被预订的区域 case MEM_RESERVE: p = L"Reserve"; break; // 预订:已预订区域 case MEM_IMAGE: p = L"Image "; break; // 映像:保存执行映像 case MEM_MAPPED: p = L"Mapped "; break; // 映射:文件映射区域 case MEM_PRIVATE: p = L"Private"; break; // 私有:数据保存在页交换文件中的区域 } StringCchCopy(szBuf, nSize, p);}// 将区域内的块信息保存到VMQUERY_HELP中BOOL CVMQuery::GetVMBlockInfo(HANDLE hProcess, LPCVOID lpAddress, VMQUERYEX *pVMBlock){ ZeroMemory(pVMBlock, sizeof(*pVMBlock)); // 1. 获取地址空间中内存地址信息,并将其保存到 MEMORY_BASIC_INFORMATION 结构体中 MEMORY_BASIC_INFORMATION mbiRgn; if ( !( VirtualQueryEx(hProcess,lpAddress,&mbiRgn,sizeof(mbiRgn)) == sizeof(mbiRgn) ) ) return false; // 错误的内存地址 // 2. 保存基地址与第一个内存块的基址 PVOID pvRgnBaseAddress = mbiRgn.AllocationBase; // 预划分内存区域基址 PVOID pvAddressBlk = mbiRgn.AllocationBase; // 第一个内存块的基址 // 3. 循环遍历此区域内的内存块,并统计其个数及总大小 MEMORY_BASIC_INFORMATION mbiBlk; while (true) { // 3.1 获取内存块的相关信息 if ( !( VirtualQueryEx(hProcess,pvAddressBlk,&mbiBlk,sizeof(mbiBlk)) == sizeof(mbiBlk) ) ) break; // 3.2 判断是否需要结束循环,如果此数据块的基址仍等于此内存区域的基址,则代 // 表此数据块是属于此区域内的(继续循环),否则则代表此内存块是其他内存 // 区域的(结束循环) // 注1:使用MEM_RESERVE方式调用VirtualAlloc即可预定内存区域 // 注2:使用MEM_COMMIT方式调用VirtualAlloc即可分配内存块 if (mbiBlk.AllocationBase != pvRgnBaseAddress) break; // 3.3 累加此预划分内存区域内的内存块数量 、预划分域的总大小与具有PAGE_GUARD // 保护属性的块的数量 pVMBlock->dwRgnBlocks++; // 内存块数量加1 pVMBlock->nRgnSize += mbiBlk.RegionSize; // 将此内存块的体积纳入到此内存区域中 if ( (mbiBlk.Protect&PAGE_GUARD)==PAGE_GUARD ) pVMBlock->dwRgnGuardBlks++; // 统具有PAGE_GUARD保护属性的块的数量 // 3.4 保存此内存块的理存储器类型 // 注1:由于内存块可以从MEM_IMAGE转换到MEM_PRIVATE,或从MEM_MAPPED转换到 // MEM_PRIVATE,也就是说如果预划分内存区域如果为MEM_PRIVATE的话,那么此 // 内存区域的数据块就可以是任意的内存类型,我们就可以认为在这里取到的内 // 存块的类型信息是有效的,当然,这一切都只是一种合理的猜测,实际上内存 // 块在实际使用时完全有可能并非是我们获取到的类型 if ( MEM_PRIVATE == mbiRgn.Type ) pVMBlock->dwRgnStorage = mbiBlk.Type; // 3.5 获取下一个内存块的基址 pvAddressBlk = (PVOID)((PBYTE)pvAddressBlk+mbiBlk.RegionSize); } // 设置栈标志位 // 注1:具有PAGE_GUARD保护属性的块的数量大于0,则此区域是为线程栈而预定的 pVMBlock->bRgnIsAStack = (pVMBlock->dwRgnGuardBlks > 0); return(TRUE);}BOOL CVMQuery::GetVMInfo(HANDLE hProcess, LPCVOID lpAddress, PVMQUERY pVMQ){ // 1. 清空结构体 ZeroMemory(pVMQ, sizeof(*pVMQ)); // 2. 获取地址空间中内存地址信息,并将其保存到 MEMORY_BASIC_INFORMATION 结构体中 MEMORY_BASIC_INFORMATION mbi; if ( !( VirtualQueryEx(hProcess,lpAddress,&mbi,sizeof(mbi)) == sizeof(mbi) ) ) return false; // 3. 填写区域成员信息 VMQUERYEX VMQHelp; switch (mbi.State) { case MEM_FREE: /** 空闲块(不保留) **********************************/ pVMQ->lpRgnBaseAddress = mbi.BaseAddress; // 由于空闲块的mbi.Protect是无效的,因此这里将使用此内存块分配时的保护属性 pVMQ->dwRgnProtection = mbi.AllocationProtect; pVMQ->nRgnSize = mbi.RegionSize; pVMQ->dwRgnStorage = MEM_FREE; pVMQ->dwRgnBlocks = 0; pVMQ->dwRgnGuardBlks = 0; pVMQ->bRgnIsAStack = FALSE; break; case MEM_RESERVE: /** 在虚拟内存中保留虚拟地址,但并不分配实际物理内存 **/ pVMQ->lpRgnBaseAddress = mbi.AllocationBase; // 由于未提交块的mbi.Protect是无效的,因此这里将使用此内存块分配时的保护属性 pVMQ->dwRgnProtection = mbi.AllocationProtect; // 迭代获取所有块的详细信息 GetVMBlockInfo(hProcess, lpAddress, &VMQHelp); pVMQ->nRgnSize = VMQHelp.nRgnSize; pVMQ->dwRgnStorage = VMQHelp.dwRgnStorage; pVMQ->dwRgnBlocks = VMQHelp.dwRgnBlocks; pVMQ->dwRgnGuardBlks = VMQHelp.dwRgnGuardBlks; pVMQ->bRgnIsAStack = VMQHelp.bRgnIsAStack; break; case MEM_COMMIT: /** 保留且分配物理地址 ********************************/ pVMQ->lpRgnBaseAddress = mbi.AllocationBase; pVMQ->dwRgnProtection = mbi.AllocationProtect; // 迭代获取所有块的详细信息 GetVMBlockInfo(hProcess, lpAddress, &VMQHelp); pVMQ->nRgnSize = VMQHelp.nRgnSize; pVMQ->dwRgnStorage = VMQHelp.dwRgnStorage; pVMQ->dwRgnBlocks = VMQHelp.dwRgnBlocks; pVMQ->dwRgnGuardBlks = VMQHelp.dwRgnGuardBlks; pVMQ->bRgnIsAStack = VMQHelp.bRgnIsAStack; break; default: DebugBreak(); break; } // 4. 解析为文本信息 GetProtectText(pVMQ->dwRgnProtection, pVMQ->szRgnProtection, _countof(pVMQ->szRgnProtection), true); GetMemStorageText(pVMQ->dwRgnStorage, pVMQ->szRgnStorage, _countof(pVMQ->szRgnStorage)); StringCchPrintf(pVMQ->szRgnBaseAddress,_countof(pVMQ->szRgnBaseAddress), L"0x%08x", pVMQ->lpRgnBaseAddress ); StringCchPrintf(pVMQ->szRgnSize, _countof(pVMQ->szRgnSize), L"%10d", pVMQ->nRgnSize ); StringCchPrintf(pVMQ->szRgnBlocks, _countof(pVMQ->szRgnBlocks), L"%3d", pVMQ->dwRgnBlocks ); return true;}
// VMView.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include "VMQuery.h"bool ShowVM(DWORD dwProcessId){ CVMQuery objVM; HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId); PVOID lpAddress = NULL; VMQUERY stcVMQ = {0}; while ( objVM.GetVMInfo(hProcess, lpAddress, &stcVMQ) ) { wprintf(L"%s %s %s %s %s\n", stcVMQ.szRgnBaseAddress, stcVMQ.szRgnStorage, stcVMQ.szRgnSize, stcVMQ.szRgnBlocks, stcVMQ.szRgnProtection); lpAddress = ((PBYTE)stcVMQ.lpRgnBaseAddress + stcVMQ.nRgnSize); ZeroMemory(&stcVMQ,sizeof(VMQUERY)); } CloseHandle(hProcess); return true;}int _tmain(int argc, _TCHAR* argv[]){ ShowVM( GetCurrentProcessId() ); system("pause"); return 0;}
0 0
- 虚拟内存遍历 VMView
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 虚拟内存
- 五、线程通信
- 第六周项目二 建立链栈算法库
- Java 299之输出二维数组中的最大值
- Intent scheme URL attack
- LayoutInflater的获取与使用
- 虚拟内存遍历 VMView
- 排序(2015-10-20)
- java 修饰符全解
- 学生成绩同一行显示或者课程安排按照一周星期的显示
- 小用hibernate二级缓存
- Hibernate常见错误
- Spark-IDEA源码阅读环境搭建(Windows)
- UI2_UILabel
- Servlet学习笔记--生成网站表单验证码