Windows核心编程:探索虚拟内存

注:本文仅为阅读《WINDOWS.核心编程 第五版》的笔记,没啥东西

1. 内存地址分区

在这里插入图片描述

2. MEMORY_BASIC_INFORMATION

在这里插入图片描述

3. 练习代码

#include <iostream>
#include <windows.h>
#include <fstream>
#include <memory>
#include <vector>

const char* GetStateText(DWORD dwState)
{
	switch (dwState)
	{
	case MEM_COMMIT: return "MEM_COMMIT";
	case MEM_FREE: return "MEM_FREE";
	case MEM_RESERVE: return "MEM_RESERVE";
	}
	return "State_N/A";
}

const char* GetTypeText(DWORD dwType)
{
	switch (dwType)
	{
	case MEM_IMAGE: return "MEM_IMAGE";
	case MEM_MAPPED: return "MEM_MAPPED";
	case MEM_PRIVATE: return "MEM_PRIVATE";
	}
	return "Type_N/A";
}

BOOL EnablePrivilege(PCTSTR szPrivilege, BOOL fEnable) {

	// Enabling the debug privilege allows the application to see
	// information about service applications
	BOOL fOk = FALSE;    // Assume function fails
	HANDLE hToken;

	// Try to open this process's access token
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
		&hToken)) {

		// Attempt to modify the given privilege
		TOKEN_PRIVILEGES tp;
		tp.PrivilegeCount = 1;
		LookupPrivilegeValue(NULL, szPrivilege, &tp.Privileges[0].Luid);
		tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED : 0;
		AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
		fOk = (GetLastError() == ERROR_SUCCESS);

		// Don't forget to close the token handle
		CloseHandle(hToken);
	}
	return(fOk);
}

//相同属性的连续页,称为一个块
struct tagVMBlock
{
	tagVMBlock()
		:pBaseAddress(0), pAllocationBase(0), dwState(0), dwType(0), dwSize(0)
	{
	}
	PVOID pBaseAddress; //等于VirtualQuery传入参数lpAddress向下取整的页面地址
	PVOID pAllocationBase; //当State为MEM_FREE时,这个值为0,否则为区域的基地址,并且pBaseAddress在这个区域中
	DWORD dwState;
	DWORD dwType;
	DWORD dwSize;
};

//通过MEM_RESERVE调用VirtualAlloc预定的一个区域
struct tagVMRegion
{
	tagVMRegion()
		:pBaseAddress(0), pAllocationBase(0), dwState(0), dwType(0), dwSize(0)
	{
	}
	PVOID pBaseAddress; //等于VirtualQuery传入参数lpAddress向下取整的页面地址
	PVOID pAllocationBase; //当State为MEM_FREE时,这个值为0,否则为区域的基地址,并且pBaseAddress在这个区域中
	DWORD dwState;
	DWORD dwType;
	DWORD dwSize;
	std::vector<std::shared_ptr<tagVMBlock>> mBlocks;
};

//查询当前进程虚拟内存信息
void QueryVirtualMemInfo(std::vector<std::shared_ptr<tagVMRegion>>& mVirtualMemInfo)
{
	PVOID pEnumRegionAddress = NULL;
	MEMORY_BASIC_INFORMATION mbi = { 0 };
	while (::VirtualQuery(pEnumRegionAddress, &mbi, sizeof(mbi)))
	{
		auto pRegion = std::make_shared<tagVMRegion>();
		pRegion->pBaseAddress = mbi.BaseAddress;
		pRegion->pAllocationBase = mbi.AllocationBase;
		pRegion->dwState = mbi.State;
		pRegion->dwType = mbi.Type;
		mVirtualMemInfo.push_back(pRegion);

		//enum blocks
		//PVOID pEnumBlockAddress = mbi.AllocationBase;
		//if (mbi.State == MEM_FREE)
		//{
		//	pEnumBlockAddress = mbi.BaseAddress;
		//}
		PVOID pEnumBlockAddress = mbi.BaseAddress;

		MEMORY_BASIC_INFORMATION mbiBlock = { 0 };
		while (::VirtualQuery(pEnumBlockAddress, &mbiBlock, sizeof(mbiBlock)))
		{
			if (mbiBlock.AllocationBase != mbi.AllocationBase)
			{
				break;
			}

			auto pBlock = std::make_shared<tagVMBlock>();
			pBlock->pBaseAddress = mbiBlock.BaseAddress;
			pBlock->pAllocationBase = mbiBlock.AllocationBase;
			pBlock->dwState = mbiBlock.State;
			pBlock->dwType = mbiBlock.Type;
			pBlock->dwSize = mbiBlock.RegionSize;

			pRegion->mBlocks.push_back(pBlock);
			pRegion->dwSize += pBlock->dwSize;

			//next
			pEnumBlockAddress = LPVOID((LPBYTE)pEnumBlockAddress + pBlock->dwSize);
		}
		
		//enum next
		pEnumRegionAddress = LPVOID((LPBYTE)pEnumRegionAddress + pRegion->dwSize);
	}
}


int main(int argc, char** argv)
{
	std::ofstream outFile;
	outFile.open("1.txt", std::ios_base::trunc | std::ios_base::out);
	if (!outFile.is_open())
	{
		std::cerr << "open file failed" << std::endl;
		return -1;
	}

	std::vector<std::shared_ptr<tagVMRegion>> mVirtualMemInfo;
	QueryVirtualMemInfo(mVirtualMemInfo);

	outFile << "BaseAddress\tAllocBaseAddress\tState\tType\tSize\tBlockCount" << std::endl;
	for (auto it = mVirtualMemInfo.begin(); it != mVirtualMemInfo.end(); ++it)
	{
		auto pRegion = *it;
		if (!pRegion) continue;

		outFile << pRegion->pBaseAddress
			<< "\t" << pRegion->pAllocationBase
			<< "\t" << GetStateText(pRegion->dwState)
			<< "\t" << GetTypeText(pRegion->dwType)
			<< "\t" << pRegion->dwSize
			<< "\t" << pRegion->mBlocks.size() << std::endl;

		for (auto itBlock = pRegion->mBlocks.begin(); itBlock != pRegion->mBlocks.end(); ++itBlock)
		{
			auto pBlock = *itBlock;
			if (!pBlock) continue;
			outFile << pBlock->pBaseAddress
				<< "\t" << pBlock->pAllocationBase
				<< "\t" << GetStateText(pBlock->dwState)
				<< "\t" << GetTypeText(pBlock->dwType)
				<< "\t" << pBlock->dwSize << std::endl;
		}
	}

	return 0;
}



4. 运行结果

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于学习Windows核心编程,以下是一些步骤和资源供您参考: 1. 学习C/C++编程语言:Windows核心编程主要使用C/C++语言进行开发。如果您不熟悉这些语言,建议先学习它们的基础知识。 2. 了解Windows操作系统架构:学习Windows操作系统的基本架构和内部工作原理,了解进程、线程、内存管理、驱动程序等概念和机制。 3. 使用Windows SDK和API:Windows软件开发工具包(SDK)提供了一套丰富的应用程序接口(API),您可以使用这些API来开发Windows应用程序。通过学习和使用这些API,您可以掌握Windows核心编程的基本技术。 4. 阅读相关书籍和文档:有一些经典的书籍和文档专门介绍Windows核心编程,如《Windows核心编程》、《Windows内核原理与实现》等。阅读这些资源可以帮助您深入理解Windows核心编程的概念和技术。 5. 参考示例代码和项目:在GitHub等代码托管平台上可以找到许多关于Windows核心编程的示例代码和项目。通过研究这些代码和项目,您可以学习到一些实际应用和解决方案。 6. 加入开发者社区和论坛:与其他Windows核心编程开发者交流经验和问题是一个很好的学习方法。加入相关的开发者社区和论坛,与其他开发者分享您的学习和实践经验。 请注意,Windows核心编程是一个较为高级和复杂的领域,需要一定的编程基础和计算机系统知识。建议您在学习之前先掌握基本的编程概念和技术。祝您学习顺利!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值