devoured elysium
devoured elysium

Reputation: 105227

Problem using OpenProcess and ReadProcessMemory

I'm having some problems implementing an algorithm to read a foreign process' memory. Here is the main code:

            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()
                ));
        }

Although generally it seems to work correctly, the problem is that for some memory values ReadProcessMemory is returning false, and GetLastError is returning 299. From what I've googled, it seems to happen on vista because some params of OpenProcess were updated. Anyone knows what this is about? And what values should I try? Notice that as they changed, I wouldn't want to know if it's VM_READ or so, I want to know exactly what the values are.

EDIT: maybe it has something to do with not calling VirtualProtect()/VirtualProtectEx()? as seen on this SO url: WriteProcessMemory/ReadProcessMemory fail

Edit2: That was it! ^^ That is the solution, calling to VirtualProtectEx() first and after ReadProcessMemory()!

Upvotes: 1

Views: 3684

Answers (2)

Rob Kennedy
Rob Kennedy

Reputation: 163357

You store the handle to the newly opened process in a local variable (retValue), but you don't pass it to your getMemoryBasicInformation function, so I can only assume that it actually fetches information about the current process. I suspect you're really using your own process's address ranges as though they belong to the other process. Many of the address ranges will probably be the same between processes, so that error wouldn't be immediately apparent.

Upvotes: 1

Ana Betts
Ana Betts

Reputation: 74702

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.

This means you tried to read a block that was partially unmapped addresses (i.e. if the app itself did this, it'd AV)

Upvotes: 1

Related Questions