2

I've been trying to create my own memory reader in C# based on a couple of articles I've seen on CodeProject. I got everything working as I would have liked when compiled for 32-bit Windows, but the issues began when I tried to convert over to a 64-bit build.

I was able to get VirtualQueryEx to work in a 64-bit C++ test project, where the MEMORY_BASIC_INFORMATION is already defined, and the BaseAddress member is a PVOID.

When I tried to move over to C#, I have to define MEMORY_BASIC_INFORMATION myself as indicated in the CodeProject example above that I am using as guidance.

The below code works for applications that have small memory profiles, but for larger applications, the MI.BaseAddress variable below seems to truncate to 2,147,356,672, and the program is stuck in an infinite loop, where currentAddress is always equal to MI.BaseAddress + MI.RegionSize (before casting to ulong).

Any guidance would be greatly appreciated. Thank you!

public struct MEMORY_BASIC_INFORMATION
{
    public ulong BaseAddress;
    public ulong AllocationBase;
    public int AllocationProtect;
    public ulong RegionSize;
    public int State;
    public ulong Protect;
    public ulong Type;
}

-

[DllImport("kernel32.dll", SetLastError=true)]
static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);

-

public void getBlocks(int pid)
{
    totalBytes = 0;
    if (addresses != null)
        addresses = null;
    addresses = new List<UIntPtr>();
    if (sizes != null)
        sizes = null;
    sizes = new List<UInt64>();
    setPID(pid);
    getHandle();

    ulong currentAddress;
    ulong maxAddress;

    SYSTEM_INFO SI;
    GetSystemInfo(out SI);
    maxAddress = (ulong)SI.maximumApplicationAddress;
    currentAddress = (ulong)SI.minimumApplicationAddress;

    MEMORY_BASIC_INFORMATION MI;

    while (currentAddress < maxAddress)
    {
        VirtualQueryEx(hProc, (IntPtr)currentAddress, out MI, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)));
        if (MI.State == MEM_COMMIT)
        {
            totalBytes += (ulong)MI.RegionSize;
        }
        currentAddress = (ulong)MI.BaseAddress + (ulong)MI.RegionSize;
    }
4

0 回答 0