tags:

views:

427

answers:

2

I am trying to open a process handle in C# using the OpenProcess function as follows:

IntPtr hProcess = OpenProcess(0x410, false, pid);

where pid is the process ID of the process I would like to open.

When called on a PID whose user is "NT AUTHORITY\SYSTEM" (on Vista x64), the above call fails, with an "Access Denied" error.

How do I get a handle of such a process?

What makes me think this is at all possible is that the .NET System.Diagnostics.Process class seems to be able to operate on such processes. For example, Process.ProcessName works fine on such processes. Under the hood, it calls Process.MainModule.ModuleName, which ultimately calls OpenProcess in exactly the same way I do. However, System.Diagnostics doesn't get the "Access Denied" error whereas I do.

Curiously, anything that attempts to get the handle of the process into my application also throws the exception. For example, Process.Handle and Process.MainModule both throw an "Access Denied" error, despite the fact that Process.MainModule clearly succeeds when called indirectly through Process.ProcessName.

Does System.Diagnostics operate under some sort of raised privileges? How can I raise the privileges of my application to be able to do the same?

A: 

How do I get a handle of such a process? How can I raise the privileges of my application to be able to do the same?

Apparently the application needs to give itself the SeDebugPrivilege: How To Use the SeDebugPrivilege to Acquire Any Process Handle

However it's not a great idea for a general-purpose app to rely on this because SeDebugPrivilege is equivalent to administrator privileges (security-wise).

I'm still not sure how exactly System.Diagnostics exposes Process.ProcessName without requiring the SeDebugPrivilege, but then I know next to nothing about the code security features of .NET.

romkyns
+1  A: 

Process name and a few other things don't require privileges to get.

Anyway, the reason you need SeDebugPrivilege is that with most arguments to OpenProcess you can compromise the machine's security if opening a SYSTEM process.

See WriteProcessMemory for the obvious reason.

Furthermore, .NET processes are not special to the kernel. If you can declare OpenProcess you have all the privileges of System.Diagnostics.Process.

Joshua
Take a look on http://msdn.microsoft.com/en-us/library/ms684880(VS.85).aspx for PROCESS_QUERY_LIMITED_INFORMATION. Your current code asks for PROCESS_VM_READ which you're *definitely* not going to get under Vista+ for stuff you don't own
Paul Betts
Thanks for this. You say process name does not require privileges to get. However the only way I found of getting the name is OpenProcess, which fails on SYSTEM-owned pids due to privilege issues. Could you please show how to get the name with WinAPI calls without special privileges? I'll accept that as the answer.
romkyns