前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >查看虚拟内存信息

查看虚拟内存信息

作者头像
我与梦想有个约会
发布2023-10-21 14:20:11
1310
发布2023-10-21 14:20:11
举报
文章被收录于专栏:jiajia_deng

以前介绍过 VMMap 工具是可以查看一个进程中的虚拟内存信息的,其内部的实现原理就是调用 VirtualQueryEx 函数(支持查看其他进程)得到一个进程的虚拟内存信息。根据学习的视频我也自己实现了一下,但我们用到的是 VirtualQuery 来查看自身进程的内容。

代码语言:javascript
复制
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#include <atlstr.h>

CString FormatMemInfo(MEMORY_BASIC_INFORMATION &mi)
{
    CString strAllocProtect;
    if (mi.AllocationProtect & PAGE_NOACCESS)                // 0x0001
    {
        strAllocProtect = _T("N  ");
    }
    if (mi.AllocationProtect & PAGE_READONLY)                // 0x0002
    {
        strAllocProtect = _T("R  ");
    }
    else if (mi.AllocationProtect & PAGE_READWRITE)          // 0x0004
    {
        strAllocProtect = _T("RW ");
    }
    else if (mi.AllocationProtect & PAGE_WRITECOPY)          // 0x0008
    {
        strAllocProtect = _T("WC ");
    }
    else if (mi.AllocationProtect & PAGE_EXECUTE)            // 0x0010
    {
        strAllocProtect = _T("E  ");
    }
    else if (mi.AllocationProtect & PAGE_EXECUTE_READ)       // 0x0020
    {
        strAllocProtect = _T("ER ");
    }
    else if (mi.AllocationProtect & PAGE_EXECUTE_READWRITE)  // 0x0040
    {
        strAllocProtect = _T("ERW");
    }
    else if (mi.AllocationProtect & PAGE_EXECUTE_WRITECOPY)  // 0x0080
    {
        strAllocProtect = _T("EWC");
    }
    if (mi.AllocationProtect & PAGE_GUARD)                   // 0x0100
    {
        strAllocProtect += _T("+Guard");
    }
    if (mi.AllocationProtect & PAGE_NOCACHE)                 // 0x0200
    {
        strAllocProtect += _T("+NoCache");
    }
    CString strState;
    if (mi.State == MEM_COMMIT)
    {
        strState = _T("Commit ");
    }
    else if (mi.State == MEM_FREE)
    {
        strState = _T("Free   ");
    }
    else if (mi.State == MEM_RESERVE)
    {
        strState = _T("Reserve");
    }
    else
    {
        strState = _T("Damned ");
    }
    CString strProtect;
    if (mi.Protect & PAGE_NOACCESS)
    {
        strProtect = _T("N  ");
    }
    else if (mi.Protect & PAGE_READONLY)
    {
        strProtect = _T("R  ");
    }
    else if (mi.Protect & PAGE_READWRITE)
    {
        strProtect = _T("RW ");
    }
    else if (mi.Protect & PAGE_WRITECOPY)
    {
        strProtect = _T("WC ");
    }
    else if (mi.Protect & PAGE_EXECUTE)
    {
        strProtect = _T("E  ");
    }
    else if (mi.Protect & PAGE_EXECUTE_READ)
    {
        strProtect = _T("ER ");
    }
    else if (mi.Protect & PAGE_EXECUTE_READWRITE)
    {
        strProtect = _T("ERW");
    }
    else if (mi.Protect & PAGE_EXECUTE_WRITECOPY)
    {
        strProtect = _T("EWC");
    }
    else if (mi.Protect & PAGE_GUARD)
    {
        strProtect += _T("+Guard");
    }
    else if (mi.Protect & PAGE_NOCACHE)
    {
        strProtect += _T("+NoCache");
    }

    CString strType;
    if (mi.Type == MEM_IMAGE)
    {
        strType = _T("Image  ");
    }
    else if (mi.Type == MEM_MAPPED)
    {
        strType = _T("Mapped ");
    }
    else if (mi.Type == MEM_PRIVATE)
    {
        strType = _T("Private");
    }
    else
    {
        strType = _T("-      ");
    }

    CString strRet;
    strRet.Format(_T("%8X  %8X  %8X   %10uKB    %12s  %7s  %8s  %7s"), mi.BaseAddress, mi.AllocationBase
        , (DWORD)mi.AllocationBase + (DWORD)mi.RegionSize
        , (DWORD)mi.RegionSize / 1024
        , strAllocProtect, strState, strProtect, strType);

    return strRet;
}

int _tmain()
{
    SYSTEM_INFO info;
    GetSystemInfo(&info);

    // 用户进程空间的最低地址和最高地址(跳过了64K的NULL区)
    VOID* pLowerBound = (VOID*)info.lpMinimumApplicationAddress;
    VOID* pUpperBound = (VOID*)info.lpMaximumApplicationAddress;

    MEMORY_BASIC_INFORMATION mi;
    VOID* pPtr = pLowerBound;
    VOID* pOldPtr = pPtr;

    _putts(_T("BaseAddress  AllocBase   EndAddress        SIZE  AllocProtect  State  CurProtect  TYPE"));

    // 不超过最高地址就一直循环
    while (pPtr <= pUpperBound)
    {
        // 查询存放到 mi 结构体中
        if (VirtualQuery((void*)pPtr, &mi, sizeof(mi)) == 0)
        {
            break;
        }

        // 打印信息
        _putts(FormatMemInfo(mi));

        // 记录本次指针指向
        pOldPtr = pPtr;
        // 让指针向后移,BaseAddress是本次的基础地址,RegionSize是本次的内存块大小
        pPtr = (BYTE*)mi.BaseAddress + mi.RegionSize;

        // 判断移动后的是不是和移动前相等
        if (pPtr <= pOldPtr)
        {
            printf("mi.BaseAddress = %X, mi.RegionSize = %X\n", 
                mi.BaseAddress, mi.RegionSize);
            break;
        }
    }

    _tsystem(_T("pause"));
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-04-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档