window 核心编程 14.4 查看虚拟地址 比较全的用户自定义函数

#include <windows.h>
#include <stdio.h>
#include<iostream>
#include <string.h>
#include "strsafe.h"
#include <WinInet.h>
#include<tchar.h>
#include<StrSafe.h>
using namespace std;

typedef struct {
    //region information
    PVOID pvRgnBaseAddress;
    DWORD dwRgnProtection;
    SIZE_T RgnSize;
    DWORD dwRgnStorage;
    DWORD dwRgnBlocks;
    DWORD dwRgnGuardBlks;//if > 0 ,region contains thread stack
    BOOL bRgnIsAStack;//True if region contains thread stack

    //BLOCK Information
    PVOID pvBlkBaseAddress;
    DWORD dwBlkProtection;
    SIZE_T BlkSize;
    DWORD dwBlkStorage;
}VMQUERY, *PVMQUERY;
typedef struct {
    SIZE_T RgnSize;
    DWORD dwRgnStorage;
    DWORD dwRgnBlock;
    DWORD dwRgnGuardBlks;
    BOOL bRgnIsAStack;
}VMQUERY_HELP;
static DWORD gs_dwAllocGran = 0;
static BOOL VMQueryHelp(HANDLE hProcess, LPCVOID pvAddress, VMQUERY_HELP *pVMQHelp)
{
    ZeroMemory(pVMQHelp, sizeof(*pVMQHelp));
    //get address of region containing passed memory address
    MEMORY_BASIC_INFORMATION mbi;
    BOOL bOk = (VirtualQueryEx(hProcess, pvAddress, &mbi, sizeof(mbi)) == sizeof(mbi));
    if (!bOk)
    {
        return (bOk);
    }
    //walk starting at the region's base address(which never changes)
    PVOID pvRgnBaseAddress = mbi.AllocationBase;
    //walk starting at the frist block in the region(change in the loop)
    PVOID pvAddressBlk = pvRgnBaseAddress;
    pVMQHelp->dwRgnStorage = mbi.Type;
    for (;;)
    {
        //get info about current block
        bok = (VirtualQueryEx(hProcess, pvAddressBlk, &mbi, sizeof(mbi)) == sizeof(mbi));
        if (!bOk)
        {
            break;//couldn't get the information; end loop
        }
        //is this block in the same region?
        if (mbi.AllocationBase != pvRgnBaseAddress)
            break;//found a block in the next region ;end loop
        //we have a block contained in the region
        pVMQHelp->dwRgnBlock++;//add another block to the region
        pVMQHelp->RgnSize += mbi.RegionSize;//add block's size to region size

        //if block has PAGE_GUARD attribute, add 1 to the counter
        if ((mbi.Protect & PAGE_GUARD) == PAGE_GUARD)
            pVMQHelp->dwRgnGuardBlks++;
        
        //take a best guess as to the type of physical storage committed to the block
        //this is aguess because some blocks can covert form MEM_IMAGE to MEM_PRIVATE
        //or from MEM_MAPPED to MEM_PRIVATE; MEM_PRIVATE can always be override by MEM_IMAGE or MEM_MAPPED
        if (pVMQHelp->dwRgnStorage == MEM_PRIVATE)
            pVMQHelp->dwRgnStorage = mbi.Type;
         
        //get the address of next block
        pvAddressBlk = (PVOID)((PBYTE)pvAddressBlk + mbi.RegionSize);
    }

    //after examining the region, check to see whether it is a thread stack
    //windows vista: assume stack if region has at least 1 PAGE_GEARD block
    pVMQHelp->bRgnIsAStack = (pVMQHelp->dwRgnGuardBlks > 0);
    return (TRUE);

}

BOOL VMQuery(HANDLE hProcess, LPCVOID pvAddress, PVMQUERY pVMQ)
{
    if (gs_dwAllocGran == 0)
    {
        //set allocation granularity if this is the frist call 
        SYSTEM_INFO sinf;
        GetSystemInfo(&sinf);
        gs_dwAllocGran = sinf.dwAllocationGranularity;
    }
    ZeroMemory(pVMQ, sizeof(*pVMQ));
    //get the MEMORY_BASIC_INFORMATION for the passed address
    MEMORY_BASIC_INFORMATION mbi;
    BOOL bOk = (VirtualQueryEx(hProcess, pvAddress, &mbi, sizeof(mbi)) == sizeof(mbi));
    if (!bOk)
    {
        return (bOk);
    }
    switch (mbi.State)
    {
    case MEM_FREE:
        pVMQ->pvBlkBaseAddress = NULL;
        pVMQ->BlkSize = 0;
        pVMQ->dwBlkProtection = 0;
        pVMQ->dwBlkStorage = MEM_FREE;
        break;
    case MEM_RESERVE:
        pVMQ->pvBlkBaseAddress = mbi.BaseAddress;
        pVMQ->BlkSize = mbi.RegionSize;
        //for a uncommitted block , mbi.protect is invalid. so we will
        //show that the reserved block inherits the protection attribute
        //of the region in which it is contained
        pVMQ->dwBlkProtection = mbi.AllocationProtect;
        pVMQ->dwBlkStorage = MEM_RESERVE;
        break;
    case MEM_COMMIT:
        pVMQ->pvBlkBaseAddress = mbi.BaseAddress;
        pVMQ->BlkSize = mbi.RegionSize;
        pVMQ->dwBlkProtection = mbi.Protect;
        pVMQ->dwBlkStorage = mbi.Type;
        break;
    default:
        DebugBreak();
        break;
    }
    //now fill in the reion data members
    VMQUERY_HELP VMQHelp;
    switch (mbi.State)
    {
    case MEM_FREE:
        pVMQ->pvRgnBaseAddress= mbi.BaseAddress;
        pVMQ->dwRgnProtection = mbi.AllocationProtect;
        pVMQ->BlkSize = mbi.RegionSize; 
        pVMQ->dwBlkStorage = MEM_FREE;
        pVMQ->dwRgnBlocks = 0;
        pVMQ->dwRgnGuardBlks = 0;
        pVMQ->bRgnIsAStack = FALSE;
        break;
    case MEM_RESERVE://reserced block without committed storage in it
        pVMQ->pvRgnBaseAddress = mbi.AllocationBase;
        pVMQ->dwRgnProtection = mbi.AllocationProtect;
        //iterate through all blocks to get complete region information
        VMQueryHelp(hProcess, pvAddress, &VMQHelp);

        pVMQ->RgnSize = VMQHelp.RgnSize;
        pVMQ->dwRgnBlocks= VMQHelp.dwRgnStorage;
        pVMQ->dwRgnStorage = VMQHelp.dwRgnStorage;
        pVMQ->dwRgnGuardBlks = VMQHelp.dwRgnGuardBlks;
        pVMQ->bRgnIsAStack = VMQHelp.bRgnIsAStack;
        break;
    case MEM_COMMIT:
        pVMQ->pvRgnBaseAddress = mbi.AllocationBase;
        pVMQ->dwRgnProtection = mbi.AllocationProtect;
        //iterate through all blocks to get complete region information
        VMQueryHelp(hProcess, pvAddress, &VMQHelp);

        pVMQ->RgnSize = VMQHelp.RgnSize;
        pVMQ->dwRgnBlocks = VMQHelp.dwRgnStorage;
        pVMQ->dwRgnStorage = VMQHelp.dwRgnStorage;
        pVMQ->dwRgnGuardBlks = VMQHelp.dwRgnGuardBlks;
        pVMQ->bRgnIsAStack = VMQHelp.bRgnIsAStack;
        break;
    default:
        DebugBreak();
        break;
    }
    return (bOk);
}

猜你喜欢

转载自blog.csdn.net/cc6979191/article/details/85334522