0

因此,我一直在与外部进程内存读取问题(读取我无权访问的进程的内存)作斗争。我对几件事的理解发生了变化,但有一件事我根本无法理解大约。

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 和记事本(我认为),它将无法正常工作。我只是想知道为什么是句柄进行了这种更改,而不是地址。

谢谢

4

1 回答 1

2

直到最近,我才明白这里列出的地址是唯一对读取内存非常重要的东西,这就是我在内存中找到正确值的原因。不幸的是,这似乎是一个负担,而且似乎实际上句柄控制着我正在与之交互的窗口。

在本段中,对您正在做的事情有多种误解,我不确定从哪里开始。

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

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

你不能。

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

但是,我们将假设读取过程以 Debug 或提供足够访问权限的等效权限运行(这就是为什么,部分地,这种权限被称为“上帝权限”,允许持有者绕过安全性)。

句柄控制哪个窗口

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

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

这是一个高级话题。最后,几乎总是有比直接读取进程内存更好的方法(适当的 API,利用SendMessage来请求控件的内容,...)周围的东西)。

摘要:找到另一种更好的方法。

编辑:了解 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),但它是对读取进程内存和解释结果所需了解的信息的唯一认真介绍。

于 2013-06-05T10:28:06.000 回答