注:本文仅为阅读《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;
}