-4

I try to get a handle to a running process using the OpenProcess function. However, when checking the error code I get an error code of 6 (ERROR_INVALID_HANDLE).

Here is a reduced sample:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Test
{
    class TestClass
    {
        [DllImport("kernel32.dll")]
        static extern uint GetLastError();

        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess,
               bool bInheritHandle, int dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress,
              byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesWritten);

        static void Main() 
        {
            var process = Process.GetProcessesByName("Sample")[0];
            var processHandle = OpenProcess(0x001F0FFF, false, process.Id);    
            Console.WriteLine(GetLastError());

            int bytesRead = 0;
            byte[] buffer = BitConverter.GetBytes(1095090201);

            WriteProcessMemory(
                (int)processHandle,
                0x21F3CAAC,
                buffer,
                buffer.Length, 
                ref bytesRead);

            Console.ReadKey();
        }
    }
}
}

I'm not really sure why it does not work. It just returns Error Code 6. Some suggestions?

I somehow have the feeling it is because of the program I'm accessing, but everything else is running just fine and does not return any other errors.

Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
Tobilo
  • 1
  • 3
  • 1
    `6` is `INVALID_HANDLE`, `GetLastError()` is only valid if `OpenProcess()` fails, i.e when `processHandle == 0` is that the case? `SetLastError = true` should be added to the attribute, what type of process is `Sample`? - Is this your real code? as it stands it would not compile – Alex K. Dec 08 '15 at 12:28
  • @AlexK. Well first of all, yea processHandle returns 0. Sample is a standard .exe programm. And no it isn't my real code, because i just took a part out of it and tried to keep it small (It is originally a Windows Form Application) – Tobilo Dec 08 '15 at 12:41
  • Showing fake code that doesn't check for errors correctly is not cool. Please put that right and don't do it again. Until you do it's hard for us to believe anything that is written here. The magic constants are very helpful either. Are we really to go look them up to work out what access you specified. Your golden rule here is that you should make it as easy as possible for us to help you. The idea is that you do as much of the leg work as possible, and we only do the parts that you cannot. – David Heffernan Dec 08 '15 at 13:24
  • @DirkVollmar The asker said, "it isn't my real code" – David Heffernan Dec 08 '15 at 14:00
  • @DirkVollmar OK, well, if you think that the question has all that is needed to answer definitively, and that the question cannot be improved, that's fine. I don't agree. – David Heffernan Dec 08 '15 at 14:14

1 Answers1

1

You need to improve your error checking. You need to check first whether the return code of OpenProcess is null before you request the last error. Note that the DllImport needs SetLastError to be set to true for this to correctly work and GetLastError should not be used.

[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr OpenProcess(int dwDesiredAccess,
       bool bInheritHandle, int dwProcessId);

processHandle = OpenProcess(0x001F0FFF, false, process.Id); 
if (processHandle == IntPtr.Zero)
{
    Console.WriteLine(Marshal.GetLastWin32Error());
}

Ideally, you'd create a managed exception from the native error code. This has the advantage that you can use standard .NET exception handling and that you get error code and textual description nicely wrapped up in an exception:

processHandle = OpenProcess(0x001F0FFF, false, process.Id); 
if (processHandle == IntPtr.Zero)
{
    // calls Marhal.GetLastWin32Error and GetErrorMessage under the hood
    throw new Win32Exception();
}

And, of course, don't forget to call CloseHandle when you're done.

Community
  • 1
  • 1
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • It's still printing 6 and at the second example it's returning the Handle is invalid, but not why... – Tobilo Dec 08 '15 at 12:45
  • `Unhandled Exception: System.ComponentModel.Win32Exception: The handle is invalid` – Tobilo Dec 08 '15 at 13:05
  • @DirkVollmar What were you expecting to happen when you threw that exception. Nothing else could be expected. Can you explain why `ERROR_INVALID_HANDLE` is returned? That is, after all, the question. – David Heffernan Dec 08 '15 at 15:31
  • The first comment to this answer contradicts that hypothesis. This is the problem with the fake code. We cannot see the code that the asker is running. Perhaps it has handled the errors correctly, and OpenProcess really is serving up `ERROR_INVALID_HANDLE`. Or perhaps the asker's code still gets the error handling wrong. This is what is wrong with the question. We end up trying to reason about something that we cannot see. We need to the asker to show the code that they are running, with correct error handling, and then we can move forward. – David Heffernan Dec 08 '15 at 16:35