我需要跟踪另一个程序的内存,不断寻找出现在其中的字节序列,当它们出现时,我需要记住它们的位置,以便我以后知道在哪里写入。
我使用以下帖子来学习如何在另一个进程的内存中查找 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() 运行的进程
大多数时候,它工作正常。一旦我在监视进程中执行将搜索到的字节序列放入内存的操作,下一次搜索就会找到它。但是,有时,它不会。
我想知道我是否正确并使用作弊引擎来确保搜索到的数据在那里。
然后我添加了创建非托管指针的部分,以了解读取了多少字节 - 那就是当我发现内存中搜索字节出现的位置(作弊引擎正确识别)返回 0 时!它不会让我在那里读取内存。这种“锁定”发生了大约一两分钟,然后才允许我读取内存(只是突然之间,下一次尝试在该位置读取内存是成功的,并且找到了字节序列)。
现在,我在 msdn 上读到“如果请求的读取操作进入无法访问的进程区域,他的函数将失败”但是我如何知道进程内存的哪个部分是可访问的,哪些不是?
为什么作弊引擎能够读取该内存,而我的程序却不能?
为什么它突然允许我再次读取进程内存?
我在这里不知所措...