繁体   English   中英

内存如何在Windows中运行?

[英]How does memory work in 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;
    }

直到最近,我的理解是,这里列出的地址是读取内存唯一真正重要的东西,这就是我在内存中找到正确值的原因。 不幸的是,这似乎是tosh的负担,似乎实际上句柄控制着我正在与哪个窗口进行交互。 例如:

我正在运行2个版本的Process“Notepad.exe”。

进程的每个实例都有一个整数,第一个包含数字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和Notepad(我认为)它将无法工作。 我只是想知道为什么这是改变的句柄,而不是地址。

谢谢

直到最近,我的理解是,这里列出的地址是读取内存唯一真正重要的东西,这就是我在内存中找到正确值的原因。 不幸的是,这似乎是tosh的负担,似乎实际上句柄控制着我正在与哪个窗口进行交互。

在这一段中,对于你正在做的事情存在多种错误理解,我不确定从哪里开始。

但是这里(假设这是不完整的):

读取我无法访问的进程的内存

你不能。

如果您没有足够的权限访问目标进程,Windows安全性将阻止您获得具有必要权限的该进程的句柄。 (如果不是这种情况则不会有安全措施。)

但是,我们假设读取过程正在运行Debug或等效权限,从而提供足够的访问权限(这就是为什么,在某种程度上称为“上帝特权”允许持有者绕过安全性)。

处理控制哪个窗口

你需要一个进程句柄,而不是一个窗口句柄:它们是完全不同的东西。 使用OpenProcess从进程ID获取进程句柄,在请求的访问权限中读取内存包括PROCESS_VM_READ

他们需要利用Windows进程的(虚拟)内存布局知识来确定您需要读取的地址。 请记住,ASLR和32对64位进程将改变该内存布局。 额外分配的地址空间不太可能是连续的,因此您不能只是按顺序读取内存。

这是一个高级主题。 最后几乎总有一种更好的方法(适当的API,利用SendMessage来请求控件的内容......),而不是直接读取进程内存(记住对一个DLL的一个小改动 - 例如来自安全补丁 - 将转移事物)。

总结:找到另一种更好的方法。

编辑:了解Windows中内存的一些资源:

  1. Mark Russinovich(第1部分,共2部分)揭示了记忆管理的奥秘
  2. Mark Russinovich(第2部分,共2部分)揭示了记忆管理的奥秘

    两部分的讨论(第1部分:虚拟内存,第2部分:物理),它还将介绍一些非常有用的工具,用于查看内存及其组织方式。

  3. 阅读Windows Internals ,Mark Russinovich等。 (并非所有都是相关的,但您还需要了解Win32中的安全性)。

  4. 阅读高级Windows ,Jeffrey Richter。 我认为这已经绝版(我的第3版涵盖了Win95 / NT4),但是对于读取进程内存和解释结果需要了解的信息是唯一的重要内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM