C/C++ 扫描特定进程内存状态

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;
}

著作权归LyShark所有

作者:lyshark

源地址:https://www.cnblogs.com/LyShark/p/13707084.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值