【问题标题】:Problem using OpenProcess and ReadProcessMemory使用 OpenProcess 和 ReadProcessMemory 的问题
【发布时间】:2009-08-26 02:25:28
【问题描述】:

我在实现读取外部进程内存的算法时遇到了一些问题。以下是主要代码:

            System.Diagnostics.Process.EnterDebugMode();
            IntPtr retValue = WinApi.OpenProcess((int)WinApi.OpenProcess_Access.VMRead | (int)WinApi.OpenProcess_Access.QueryInformation, 0, (uint)_proc.Id);
            _procHandle = retValue;

            WinApi.MEMORY_BASIC_INFORMATION[] mbia = getMemoryBasicInformation().Where(p => p.State == 0x1000).ToArray();

            foreach (WinApi.MEMORY_BASIC_INFORMATION mbi in mbia) {
                byte[] buffer = Read((IntPtr)mbi.BaseAddress, mbi.RegionSize);

                foreach (IntPtr addr in ByteSearcher.FindInBuffer(buffer, toFind, (IntPtr)0, mbi.RegionSize, increment)) {
                    yield return addr;
                }
            }

Read() ... method

        if (!WinApi.ReadProcessMemory(_procHandle, address, buffer, size, out numberBytesRead)) {
            throw new MemoryReaderException(
                string.Format(
                "There was an error with ReadProcessMemory()\nGetLastError() = {0}",
                WinApi.GetLastError()
                ));
        }

虽然通常它似乎工作正常,但问题是对于某些内存值,ReadProcessMemory 返回 false,而 GetLastError 返回 299。根据我的谷歌搜索,这似乎发生在 vista 上,因为 OpenProcess 的某些参数已更新.有谁知道这是怎么回事?我应该尝试什么价值观?请注意,当它们发生变化时,我不想知道它是否是 VM_READ 左右,我想确切地知道值是什么。

编辑:也许它与不调用 VirtualProtect()/VirtualProtectEx() 有关?正如在这个 SO url 上看到的那样:WriteProcessMemory/ReadProcessMemory fail

Edit2:就是这样! ^^ 那就是解决方案,先调用 VirtualProtectEx(),再调用 ReadProcessMemory()!

【问题讨论】:

  • 这种方法会对受害者进程造成严重破坏,如果你要这样做,你必须冻结进程。

标签: c# .net c++ vb.net process


【解决方案1】:
C:\Debuggers>kd -z C:\Windows\notepad.exe
0:000> !error 0n299
Error code: (Win32) 0x12b (299) - Only part of a ReadProcessMemory 
    or WriteProcessMemory request was completed.

这意味着您试图读取一个部分未映射地址的块(即,如果应用程序本身这样做,它会 AV)

【讨论】:

  • 这很奇怪,正如您在代码中看到的那样,我只关注 MEMORY_BASIC_INFORMATION 结构提供的内存块。还是我做错了什么?
  • 进程是否暂停?还是您正在从实时进程中读取?
  • 我在一个正在运行的进程上运行它。可能是这个原因吗?
  • 当然——当您收集 MEMORY_BASIC_INFORMATION(即 PTE)时,该进程正在分配和释放内存。
【解决方案2】:

您将新打开的进程的句柄存储在一个局部变量 (retValue) 中,但您没有将它传递给您的 getMemoryBasicInformation 函数,所以我只能假设它实际上获取了有关 当前进程。我怀疑您确实在使用自己进程的地址范围,就好像它们属于另一个进程一样。进程之间的许多地址范围可能相同,因此错误不会立即显现。

【讨论】:

  • 请记住,我只是将这部分代码放在一起,但实际上它更复杂。我已经对此进行了测试,它正在从另一个进程中读取数据。
  • 我明白了。我的水晶球在店里修理。同时,我只能评论我看到的代码。
猜你喜欢
  • 2014-06-27
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
  • 1970-01-01
  • 2013-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多