ReadProcessMemory fails on some Pages (GetLastError()=299)

泄露秘密 提交于 2019-12-18 17:31:54

问题


I try to read all commited pages of a process (Win7-64). On most pages it works but it fails for a few pages. I cannot explain why. Here is my test programme (compiled x32, tested in Win7-64):

#include <windows.h>

void main()
{
    HANDLE hProc = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,FALSE,GetCurrentProcessId());

    SYSTEM_INFO si;
    ZeroMemory(&si,sizeof(SYSTEM_INFO));
    GetSystemInfo(&si);

    char* buf = new char[si.dwPageSize];

    for (unsigned i = 0; i < 0x7fff0; i++)
    {
        void* baseOffs = (void*) (i * si.dwPageSize);
        MEMORY_BASIC_INFORMATION mbi;
        ZeroMemory(&mbi,sizeof(MEMORY_BASIC_INFORMATION));

        if (VirtualQueryEx(hProc, baseOffs, &mbi, sizeof(MEMORY_BASIC_INFORMATION)) == 0)
        {
            MessageBox(NULL, TEXT("VirtualQueryEx failed"),TEXT(""),MB_OK);
        }

        if (mbi.State == MEM_COMMIT)
        {
            SIZE_T numByteWritten = 0;
            if(ReadProcessMemory(hProc, baseOffs,buf,si.dwPageSize,&numByteWritten) == FALSE)
                OutputDebugString(TEXT("bad\n")); //GetLastError()==ERROR_PARTIALLY_READ; numByteWritten == 0;
            else
                OutputDebugString(TEXT("good\n"));

        }
    }

    delete[] buf;
}

I tired to look into the MEMORY_BASIC_INFORMATION for the failing pages but I didn't find anything strange there. Also the number of failing pages varies from run to run (in average about 5). WHat prevents me from reading these pages? Do I need to adjust some privilges in the process token?


回答1:


A little bit of debugging and somethings interesting is identified: all pages that fail have protection bit PAGE_GUARD set (see MSDN doc). As I interpret the docs, it is by design that you cannot read these pages with ReadProcessMemory.

if(ReadProcessMemory(hProc, baseOffs,buf,si.dwPageSize,&numByteWritten) == FALSE) {
    assert(mbi.Protect & 0x100);
    OutputDebugString(TEXT("bad\n")); //GetLastError()==ERROR_PARTIALLY_READ; numByteWritten == 0; 
}
else {
    assert(!(mbi.Protect & 0x100));
    OutputDebugString(TEXT("good\n")); 
}



回答2:


The page size on 32-bit Windows is not the same as the page size on 64-bit Windows. Therefore, the page size is a per-process value. The page size for your process is not necessarily the same as the page size of the process you are reading from. Use the RegionSize member of the MEMORY_BASIC_INFORMATION instead. That is the actual size of the affected region.



来源:https://stackoverflow.com/questions/12122323/readprocessmemory-fails-on-some-pages-getlasterror-299

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!