C# 使用OpenProcess和ReadProcessMemory时出现问题

C# 使用OpenProcess和ReadProcessMemory时出现问题,c#,.net,c++,vb.net,process,C#,.net,C++,Vb.net,Process,我在实现读取外部进程内存的算法时遇到了一些问题。以下是主要代码: System.Diagnostics.Process.EnterDebugMode(); IntPtr retValue = WinApi.OpenProcess((int)WinApi.OpenProcess_Access.VMRead | (int)WinApi.OpenProcess_Access.QueryInformation, 0, (uint)_proc.Id);

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

            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所示:

Edit2:就是这样这就是解决方案,首先在ReadProcessMemory()之后调用VirtualProtectEx()


这意味着您试图读取部分未映射地址的块(即,如果应用程序本身执行此操作,它将自动执行)

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

这很奇怪,正如您在代码中看到的,我只关注内存基本信息结构给出的内存块。还是我做错了什么?进程是否暂停?或者你在从一个实时进程中读取数据?我在一个正在运行的进程上运行它。这可能是原因吗?当然-当您收集内存基本信息(即PTE)时,过程是分配和释放内存。请记住,我只是将代码的这部分放在一起,但实际上它更复杂。我已经测试过了,它正在从另一个进程读取数据。我的水晶球在商店里修理。同时,我只能对我展示的代码进行评论。这种方法将对受害者进程造成严重破坏,如果你要这样做,你必须冻结进程。
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.