CodeProjectで見たいくつかの記事に基づいて、C# で独自のメモリ リーダーを作成しようとしています。32 ビット Windows 用にコンパイルした場合はすべてが正常に動作しましたが、64 ビット ビルドに変換しようとしたときに問題が発生しました。
がVirtualQueryEx
すでにMEMORY_BASIC_INFORMATION
定義されており、BaseAddress
メンバーがPVOID
.
C# に移行しようとしたときMEMORY_BASIC_INFORMATION
、ガイドとして使用している上記の CodeProject の例に示されているように、自分自身を定義する必要があります。
以下のコードはメモリ プロファイルが小さいアプリケーションでは機能しますが、大規模なアプリケーションでは、以下の変数がMI.BaseAddress
2,147,356,672 に切り捨てられたように見え、プログラムは無限ループに陥ります。currentAddress
MI.BaseAddress + MI.RegionSize
ulong
ガイダンスをいただければ幸いです。ありがとうございました!
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;
}