我需要跟踪另一个程序的内存,不断寻找出现在那里的字节序列,当它们出现时,我需要记住它们的位置,以便我以后知道写到哪里。
我使用以下帖子来学习如何在另一个进程的内存中查找byte []: C#: Search a byte[] array in another process's memory
我的程序很简单:它启动进程(使用Process.Start),然后从链接线程的一个答案重复运行函数:
private static int GetMemoryAddressOfString(byte[] searchedBytes)
{
IntPtr hProcess = OpenProcess(ProcessAccessFlags.VMOperation | ProcessAccessFlags.VMRead | ProcessAccessFlags.VMWrite, false, Program.ArtemisProcess.Id);
if (hProcess == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
int addr = 0;
int speed = 1024 * 64;
for (int j = 0x00400000; j < 0x11000000; j += speed)
{
byte[] bigMem = new byte[speed + searchedBytes.Length];
IntPtr unmanagedPointer = Marshal.AllocHGlobal(4);
ReadProcessMemory(hProcess, (IntPtr)j, bigMem, new UIntPtr((uint)(speed + searchedBytes.Length)), unmanagedPointer);
int result = Marshal.ReadInt32(unmanagedPointer);
Marshal.DestroyStructure(unmanagedPointer, typeof(int));
for (int k = 0; k < bigMem.Length - searchedBytes.Length; k++)
{
bool found = true;
for (int l = 0; l < searchedBytes.Length; l++)
{
if (bigMem[k + l] != searchedBytes[l])
{
found = false;
break;
}
}
if (found)
{
addr = k + j;
break;
}
}
if (addr != 0)
break;
}
return addr;
}
其中ArtemisProcess是我使用.Start()
运行的Process大多数时候,它运作正常。只要我在观察过程中执行操作,将搜索到的字节序列放入内存,下一次搜索就会找到它。但是,有时,它不会。
我想知道我是否正确并使用了Cheat Engine以确保搜索到的数据存在。
然后我添加了我创建一个非托管指针的部分,以了解有多少字节被读取 - 那就是当我发现内存中搜索字节出现的位置(Cheat Engine正确识别)时返回0 !它不会让我读那里的记忆。这种“锁定”发生大约一两分钟,然后它才允许我读取内存(突然之间,下一次尝试读取该位置的内存是成功的,并且字节序列可以找到)。
现在,我在msdn上读到“如果请求的读操作进入了一个无法访问的进程区域,他的功能就会失败”,但我怎么知道进程内存的哪一部分是可访问的,哪些不是?
为什么Cheat Engine能够读取该内存,而我的程序不是?
为什么突然允许我再次读取进程内存?
我在这里不知所措......