北京理工大学操作系统 实验三 遍历进程地址空间


Copyright © 2024 Squareroot_2, All rights reserved.

实验三 遍历进程地址空间

一、实验目的

通过设计程序实时显示某个进程的虚拟地址空间布局和工作集信息,加深对内存管理的理解。

二、实验内容

在Windows系统下设计程序,实时显示某个进程的虚拟地址空间布局和工作集信息。

三、程序设计与实现

实验环境:windows 10
开发环境:Visual Studio 2022
程序源码:

#include <cstdio>
#include <cstdlib>
#include <iostream> 
#include <windows.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <iomanip>
#pragma comment(lib,"Shlwapi.lib")
using namespace std;
void showMask(DWORD dwTarget, DWORD dwMask, string type) {
	if ((dwTarget & dwMask) == dwMask) {
		cout << ", " << type;
	}
}
void showProtection(DWORD dwTarget) {
	showMask(dwTarget, PAGE_READONLY, "PAGE_READONLY");
	showMask(dwTarget, PAGE_GUARD, "PAGE_GUARD");
	showMask(dwTarget, PAGE_NOCACHE, "PAGE_NOCACHE");
	showMask(dwTarget, PAGE_READWRITE, "PAGE_READWRITE");
	showMask(dwTarget, PAGE_WRITECOPY, "PAGE_WRITECOPY");
	showMask(dwTarget, PAGE_EXECUTE, "PAGE_EXECUTE");
	showMask(dwTarget, PAGE_EXECUTE_READ, "PAGE_EXECUTE_READ");
	showMask(dwTarget, PAGE_EXECUTE_READWRITE, "PAGE_EXECUTE_READWRITE");
	showMask(dwTarget, PAGE_EXECUTE_WRITECOPY, "PAGE_EXECUTE_WRITECOPY");
	showMask(dwTarget, PAGE_NOACCESS, "PAGE_NOACCESS");
}

//遍历整个虚拟内存,并显示各内存区属性的工作程序
void walkVM(HANDLE hProcess) {
	//系统信息
	SYSTEM_INFO si;
	ZeroMemory(&si, sizeof(si));
	GetSystemInfo(&si);	//获得系统信息

	//进程虚拟内存空间信息
	MEMORY_BASIC_INFORMATION mbi;
	ZeroMemory(&mbi, sizeof(mbi));

	//循环整个应用程序地址空间
	LPCVOID pBlock = (LPVOID)si.lpMinimumApplicationAddress;
	while (pBlock < si.lpMaximumApplicationAddress) {
		SIZE_T t = VirtualQueryEx(hProcess, pBlock, &mbi, sizeof(mbi));
		if (t == sizeof(mbi)) {
			//计算块的结尾及其长度
			LPCVOID pEnd = (PBYTE)pBlock + mbi.RegionSize;
			TCHAR szSize[MAX_PATH];

			//将数字转换成字符串
			StrFormatByteSize(mbi.RegionSize, szSize, MAX_PATH);

			//显示块地址和长度
			cout.fill('0');
			cout << hex << setw(8) << (DWORD)pBlock
				<< "-"
				<< hex << setw(8) << (DWORD)pEnd
				<< (strlen(szSize) == 7 ? "(" : ",(") << szSize << ")";
			//<< "(" << szSize << ")";

			//显示块的状态
			string state = " state: ";
			switch (mbi.State)
			{
			case MEM_COMMIT:
				state += "已提交";
				break;
			case MEM_FREE:
				state += "空闲  ";
				break;
			case MEM_RESERVE:
				state += "已预留";
				break;
			}
			cout << state;

			//显示保护
			if (mbi.Protect == 0 && mbi.State != MEM_FREE) {
				mbi.Protect = PAGE_READONLY;
			}
			showProtection(mbi.Protect);

			//显示类型
			string type = ", type: ";
			switch (mbi.Type)
			{
			case MEM_IMAGE:
				type += "Image";
				break;
			case MEM_MAPPED:
				type += "Mapped";
				break;
			case MEM_PRIVATE:
				type += "Private";
				break;
			}

			pBlock = pEnd;
			cout << endl;
		}
	}
}
int main(int argc, char* argv[]) {
	//获得每个进程的信息
	cout << "各个进程的信息: " << endl;
	PROCESSENTRY32 pe;
	pe.dwSize = sizeof(pe);
	HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	BOOL bMore = ::Process32First(hProcessSnap, &pe);
	while (bMore)
	{
		HANDLE hP = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
		PROCESS_MEMORY_COUNTERS pmc;
		ZeroMemory(&pmc, sizeof(pmc));

		if (GetProcessMemoryInfo(hP, &pmc, sizeof(pmc)) == TRUE)
		{
			cout << "进程ID: ";
			wcout << pe.th32ProcessID;

			cout << "\t虚拟内存的大小为: " << (float)pmc.WorkingSetSize / 1024 << "KB";

			cout << "\t进程名称: ";
			wcout << pe.szExeFile << endl;
		}
		bMore = ::Process32Next(hProcessSnap, &pe);
	}
	cout << endl;

	//显示进程的虚拟地址空间布局和工作集信息
	int process_id;
	do {
		cout << "显示进程的虚拟地址空间布局和工作集信息" << endl
			<< "输入要查询的进程ID(退出请输入-1): ";
		cin >> process_id;
		if (process_id >= 0) {
			HANDLE hP = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);
			walkVM(hP);
		}
	} while (process_id != -1);
	return 0;
}

四、实验结果及分析

请添加图片描述

五、实验收获与体会

通过本实验,熟练掌握了GetSystemInfo, VirtualQueryEx,VirtualAlloc, GetPerformanceInfo, GlobalMemoryStatusEx等Windows下关于内存信息的系统调用函数,了解了系统内部内存的工作方式和工作情况,对Windows操作系统的内存分配方式有了更加深入的了解。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值