所以我一直在通过问题与外部进程内存读取(读取进程的内存我不能访问。)我已经改变了,但有一件事我只是我无法理解我的头脑。内存在Windows中如何工作?
的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);
当然这意味着该把手控制,其中存储器是阅读,而不是地址,而且事实上这个地址与我实际上想要做的事情完全不相关?任何人都可以向我解释为什么会是这种情况?
道歉,如果这个问题过于具体,但这个问题一直困扰着我的脑子很长一段时间了,虽然我每天都和很多程序员说话,但他们都没有能够(或者更多他们不愿意)帮助我。
我完全意识到这只适用于同一个exe的2个运行实例,所以如果你要阅读Firefox和记事本(我认为),它将不起作用。我只是想知道为什么它是这个改变的句柄,而不是地址。
感谢
由于您仅从基址读取4k,我怀疑您正在读取内存的可执行部分,这对于'notepad.exe'进程都是相同的。你有没有尝试过读两个不同的程序?两个过程的价值在这个位置是完全可行的。 – Steve
“完全相同的价值”是什么意思?同样的答案,当它不应该? –
@Steve - 我明白你的意思,实际上我没有使用记事本,但另一个程序,我怀疑这里会有人,记事本只是作为一个例子。我实际读取的偏移量是一个结构数组的一部分(在我注意到这个“问题”的情况下),并且距基数的偏移量为0x553008)。 (还是)感谢你的建议。 – XtrmJosh