ReadProcessMemory vs MiniDumpWriteDump

-1

I noticed that if I try to read the entirety of the process with ReadProcessMemory it takes VERY long. However, when doing a MiniDumpWriteDump, it happens in about 1 second.

Also for some reason the byte array becomes corrupt when trying to store the entire process when doing ReadProcessMemory and MiniDumpWriteDump doesn't.

Only problem is, when doing a MiniDumpWriteDump, I can't match the addresses/values in something like Cheat Engine. Like for example doing a byte array search returns a different address.

MiniDumpWriteDump(pHandle, procID, fsToDump.SafeFileHandle.DangerousGetHandle(), 0x00000002, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

ReadProcessMemory(pHandle, (UIntPtr)0, test, (UIntPtr)procs.PrivateMemorySize, IntPtr.Zero);

ReadProcessMemory Length = 597577728

Dump Length = 372053153

c#
readprocessmemory
minidumpwritedump
asked on Stack Overflow Jul 26, 2017 by Jacob Fliss • edited Jul 26, 2017 by Jacob Fliss

1 Answer

0

if I try to read the entirety of the process with ReadProcessMemory it takes VERY long.

MiniDumpWriteDump is fast because it's a highly optimized function written my Microsoft themselves.

A proper pattern scan function that is checking page protection type and state by using VirtualQueryEx() with a limited number of wildcards won't take more than 10 seconds and in most cases will take less than 2 seconds.

This is C++ code but the logic will be the same in C#

#include <iostream>
#include <windows.h>

int main()
{
    MEMORY_BASIC_INFORMATION meminfo;
    char* addr = 0;

    HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());

    MEMORY_BASIC_INFORMATION mbi;

    char buffer[0x1000];

    while (VirtualQueryEx(hProc, addr, &mbi, sizeof(mbi)))
    {
        if (mbi.State != MEM_COMMIT || mbi.Protect == PAGE_NOACCESS)
        {
            char* buffer = new char[mbi.RegionSize];

            ReadProcessMemory(hProc, addr, buffer, mbi.RegionSize, nullptr);
        }
        addr += mbi.RegionSize;
    }

    CloseHandle(hProc);
}

Notice we check for MEM_COMMIT, if the memory isn't commited then it's invalid. Similarly if the protection is PAGE_NOACCESS we discard that memory as well. This simple technique will yield only proper memory worth scanning, resulting in a fast scan. After you Read each section into the local buffer, you can run your pattern scan code against that. Lastly just resolve the offset from the beginning of the region to the absolute address in the target process.

answered on Stack Overflow Apr 18, 2020 by GuidedHacking

User contributions licensed under CC BY-SA 3.0