C/C++ 扫描特定进程内存状态
扫描内存分页情况:
#include <iostream>
#include <windows.h>
VOID ScanMemory(HANDLE hProc)
{
SIZE_T stSize = 0;
PBYTE pAddress = (PBYTE)0;
SYSTEM_INFO sysinfo;
MEMORY_BASIC_INFORMATION mbi = { 0 };
//获取页的大小
ZeroMemory(&sysinfo, sizeof(SYSTEM_INFO));
GetSystemInfo(&sysinfo);
// 得到的镜像基地址
pAddress = (PBYTE)sysinfo.lpMinimumApplicationAddress;
// 判断只要当前地址小于最大地址就循环
while (pAddress < (PBYTE)sysinfo.lpMaximumApplicationAddress)
{
ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION));
stSize = VirtualQueryEx(hProc, pAddress, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (stSize == 0)
{
pAddress += sysinfo.dwPageSize;
continue;
}
printf("开始地址: 0x%08X \t 结束地址: 0x%08X \t 大小: %10d K \t 状态: ", mbi.BaseAddress,
((DWORD)mbi.BaseAddress + (DWORD)mbi.RegionSize),mbi.RegionSize>>10);
switch (mbi.State)
{
case MEM_FREE: printf("空闲 \n"); break;
case MEM_RESERVE: printf("保留 \n"); break;
case MEM_COMMIT: printf("提交 \n"); break;
default: printf("未知 \n"); break;
}
// 每次循环累加内存块的位置
pAddress = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
}
}
int main(int argc, char* argv[])
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
ScanMemory(hProc);
return 0;
}
枚举自身进程内存权限: 枚举出自身内存的内存分配权限.
#include <stdio.h>
#include <ShlObj.h>
#include <Windows.h>
void ScanMemoryAttribute()
{
DWORD Addres = 0, Size = 0;
MEMORY_BASIC_INFORMATION Basicinfo = {};
// 遍历进程所有分页, 输出内容
while (VirtualQuery((LPCVOID)Addres, &Basicinfo, sizeof(MEMORY_BASIC_INFORMATION)))
{
Size = Basicinfo.RegionSize;
printf("地址: %08p 类型: %7d 大小: %7d 状态: ", Basicinfo.BaseAddress,Basicinfo.Type,Basicinfo.RegionSize);
switch (Basicinfo.State)
{
case MEM_FREE: printf("空闲 \n"); break;
case MEM_RESERVE: printf("保留 \n"); break;
case MEM_COMMIT: printf("提交 \n"); break;
default: printf("未知 \n"); break;
}
// 如果是提交状态的内存区域,那么遍历所有块中的信息
if (Basicinfo.State == MEM_COMMIT)
{
// 遍历所有基址是 Address
LPVOID BaseBlockAddress = (LPVOID)Addres;
DWORD BlockAddress = Addres;
DWORD dwBlockSize = 0;
// 遍历大内存块中的小内存块
while (VirtualQuery((LPVOID)BlockAddress, &Basicinfo, sizeof(Basicinfo)))
{
if (BaseBlockAddress != Basicinfo.AllocationBase)
{
break;
}
printf("--> %08X", BlockAddress);
// 查看内存状态,映射方式
switch (Basicinfo.Type)
{
case MEM_PRIVATE: printf("私有 "); break;
case MEM_MAPPED: printf("映射 "); break;
case MEM_IMAGE: printf("镜像 "); break;
default: printf("未知 "); break;
}
if (Basicinfo.Protect == 0)
printf("---");
else if (Basicinfo.Protect & PAGE_EXECUTE)
printf("E--");
else if (Basicinfo.Protect & PAGE_EXECUTE_READ)
printf("ER-");
else if (Basicinfo.Protect & PAGE_EXECUTE_READWRITE)
printf("ERW");
else if (Basicinfo.Protect & PAGE_READONLY)
printf("-R-");
else if (Basicinfo.Protect & PAGE_READWRITE)
printf("-RW");
else if (Basicinfo.Protect & PAGE_WRITECOPY)
printf("WCOPY");
else if (Basicinfo.Protect & PAGE_EXECUTE_WRITECOPY)
printf("EWCOPY");
printf("\n");
// 计算所有相同块大小
dwBlockSize += Basicinfo.RegionSize;
// 累加内存块的位置
BlockAddress += Basicinfo.RegionSize;
}
// 内有可能大小位空
Size = dwBlockSize ? dwBlockSize : Basicinfo.RegionSize;
}
// 下一个区域内存信息
Addres += Size;
}
}
int main(int argc, char * argv[])
{
ScanMemoryAttribute();
system("pause");
return 0;
}
枚举大内存块:
#include <iostream>
#include <windows.h>
#include <Psapi.h>
#pragma comment(lib,"psapi.lib")
VOID ScanProcessMemory(HANDLE hProc)
{
SIZE_T stSize = 0;
PBYTE pAddress = (PBYTE)0;
SYSTEM_INFO sysinfo;
MEMORY_BASIC_INFORMATION mbi = { 0 };
//获取页的大小
ZeroMemory(&sysinfo, sizeof(SYSTEM_INFO));
GetSystemInfo(&sysinfo);
// 得到的镜像基地址
pAddress = (PBYTE)sysinfo.lpMinimumApplicationAddress;
printf("------------------------------------------------------------------------ \n");
printf("开始地址 \t 结束地址 \t\t 大小 \t 状态 \t 内存类型 \n");
printf("------------------------------------------------------------------------ \n");
// 判断只要当前地址小于最大地址就循环
while (pAddress < (PBYTE)sysinfo.lpMaximumApplicationAddress)
{
ZeroMemory(&mbi, sizeof(MEMORY_BASIC_INFORMATION));
stSize = VirtualQueryEx(hProc, pAddress, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
if (stSize == 0)
{
pAddress += sysinfo.dwPageSize;
continue;
}
printf("0x%08X \t 0x%08X \t %8d K \t ", mbi.BaseAddress,
((DWORD)mbi.BaseAddress + (DWORD)mbi.RegionSize),mbi.RegionSize>>10);
switch (mbi.State)
{
case MEM_FREE: printf("空闲 \t"); break;
case MEM_RESERVE: printf("保留 \t"); break;
case MEM_COMMIT: printf("提交 \t"); break;
default: printf("未知 \t"); break;
}
switch (mbi.Type)
{
case MEM_PRIVATE: printf("私有 \t"); break;
case MEM_MAPPED: printf("映射 \t"); break;
case MEM_IMAGE: printf("镜像 \t"); break;
default: printf("未知 \t"); break;
}
if (mbi.Protect == 0)
printf("---");
else if (mbi.Protect & PAGE_EXECUTE)
printf("E--");
else if (mbi.Protect & PAGE_EXECUTE_READ)
printf("ER-");
else if (mbi.Protect & PAGE_EXECUTE_READWRITE)
printf("ERW");
else if (mbi.Protect & PAGE_READONLY)
printf("-R-");
else if (mbi.Protect & PAGE_READWRITE)
printf("-RW");
else if (mbi.Protect & PAGE_WRITECOPY)
printf("WCOPY");
else if (mbi.Protect & PAGE_EXECUTE_WRITECOPY)
printf("EWCOPY");
printf("\n");
// 每次循环累加内存块的位置
pAddress = (PBYTE)mbi.BaseAddress + mbi.RegionSize;
}
}
int main(int argc, char* argv[])
{
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
ScanProcessMemory(hProc);
CloseHandle(hProc);
system("pause");
return 0;
}
另一种扫描方式: 以下这段代码来源于网络,仅用于收藏。
#include <iostream>
#include <windows.h>
#include <TCHAR.H>
// 显示一个进程的内存状态 dwPID为进程ID
BOOL ShowProcMemInfo(DWORD dwPID)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,dwPID);
if (hProcess == NULL)
return FALSE;
MEMORY_BASIC_INFORMATION mbi;
PBYTE pAddress = NULL;
TCHAR szInfo[200] = _T("BaseAddr Size Type State Protect \n");
_tprintf(szInfo);
while (TRUE)
{
if (VirtualQueryEx(hProcess, pAddress, &mbi, sizeof(mbi)) != sizeof(mbi))
break;
if ((mbi.AllocationBase != mbi.BaseAddress) && (mbi.State != MEM_FREE))
_stprintf(szInfo, _T(" %08X %8dK "),mbi.BaseAddress,mbi.RegionSize >> 10);
else
_stprintf(szInfo, _T("%08X %8dK "),mbi.BaseAddress,mbi.RegionSize >> 10);
LPCTSTR pStr = _T("");
switch (mbi.Type)
{
case MEM_IMAGE: pStr = _T("MEM_IMAGE "); break;
case MEM_MAPPED: pStr = _T("MEM_MAPPED "); break;
case MEM_PRIVATE: pStr = _T("MEM_PRIVATE"); break;
default: pStr = _T("-----------"); break;
}
_tcscat(szInfo, pStr);
_tcscat(szInfo, _T(" "));
switch (mbi.State)
{
case MEM_COMMIT: pStr = _T("MEM_COMMIT "); break;
case MEM_RESERVE: pStr = _T("MEM_RESERVE"); break;
case MEM_FREE: pStr = _T("MEM_FREE "); break;
default: pStr = _T("-----------"); break;
}
_tcscat(szInfo, pStr);
_tcscat(szInfo, _T(" "));
switch (mbi.AllocationProtect)
{
case PAGE_READONLY: pStr = _T("PAGE_READONLY "); break;
case PAGE_READWRITE: pStr = _T("PAGE_READWRITE "); break;
case PAGE_WRITECOPY: pStr = _T("PAGE_WRITECOPY "); break;
case PAGE_EXECUTE: pStr = _T("PAGE_EXECUTE "); break;
case PAGE_EXECUTE_READ: pStr = _T("PAGE_EXECUTE_READ "); break;
case PAGE_EXECUTE_READWRITE: pStr = _T("PAGE_EXECUTE_READWRITE"); break;
case PAGE_EXECUTE_WRITECOPY: pStr = _T("PAGE_EXECUTE_WRITECOPY"); break;
case PAGE_GUARD: pStr = _T("PAGE_GUARD "); break;
case PAGE_NOACCESS: pStr = _T("PAGE_NOACCESS "); break;
case PAGE_NOCACHE: pStr = _T("PAGE_NOCACHE "); break;
default: pStr = _T("----------------------"); break;
}
_tcscat(szInfo, pStr);
_tcscat(szInfo, _T("\n"));
_tprintf(szInfo);
pAddress = ((PBYTE)mbi.BaseAddress + mbi.RegionSize);
}
CloseHandle(hProcess);
return TRUE;
}
int main(int argc, char* argv[])
{
ShowProcMemInfo(3620);
system("pause");
return 0;
}
文章出处:https://www.cnblogs.com/LyShark/p/13707084.html
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2019-09-21 驱动开发:恢复SSDT内核钩子