因此,我一直在与外部进程内存读取问题(读取我无权访问的进程的内存)作斗争。我对几件事的理解发生了变化,但有一件事我根本无法理解大约。
win32api 函数 ReadProcessMemory() 接受几个参数,如下所示:
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
我正在传递这样的论点:
public byte[] ReadBytes(IntPtr Handle, Int64 Address, uint BytesToRead)
{
IntPtr ptrBytesRead;
byte[] buffer = new byte[BytesToRead];
ReadProcessMemory(Handle, new IntPtr(Address), buffer, BytesToRead, out ptrBytesRead);
return buffer;
}
直到最近,我才明白这里列出的地址是唯一对读取内存非常重要的东西,这就是我在内存中找到正确值的原因。不幸的是,这似乎是一个负担,而且似乎实际上句柄控制着我正在与之交互的窗口。例如:
我正在运行进程“Notepad.exe”的 2 个版本。
进程的每个实例中都有一个整数,第一个包含数字 12345,第二个包含 54321。
我正在寻找读取该整数,并且假设(虽然我还没有确认这一点,所以它可能是不真实的)该程序内存空间内的内存地址是 0x1000。
例如,如果我运行:
ReadProcessMemory(NP.Handle, NP.MainModule.BaseAddress + 0x1000, buffer, 32, bread);
这将在添加到该偏移量的基地址处使用该句柄读取进程。但是,此代码将读取完全相同的值:
ReadProcessMemory(NP.Handle, NP2.MainModule.BaseAddress + 0x1000, buffer, 32, bread);
请注意,NP2 应该是第二个记事本窗口,而 NP 是第一个。在上述之上,这将读取一个不同的值(尽管我们正在读取的地址与第一个示例相同):
ReadProcessMemory(NP2.Handle, NP.MainModule.BaseAddress + 0x1000, buffer, 32, bread);
当然,这意味着句柄控制的是读取内存的位置,而不是地址,实际上地址与我实际尝试做的事情完全无关?谁能向我解释为什么会这样?
抱歉,如果这个问题过于具体,但这个问题已经让我绞尽脑汁很长时间了,虽然我每天都与众多程序员交谈,但他们都没有能力(或者也许更多的是他们没有) t 愿意)帮助我。
我完全知道这仅适用于同一 exe 的 2 个正在运行的实例,因此如果您要阅读 Firefox 和记事本(我认为),它将无法正常工作。我只是想知道为什么是句柄进行了这种更改,而不是地址。
谢谢