views:

480

answers:

1

This is weird. Earlier, running Windows 7 x64, I had trouble calling the Win32 OpenProcess against 64-bit processes. Googled around a bit, and came to the sinking conclusion this just wasn't gonna happen.

Then a funny thing happened. I tried it against the process ID for explorer.exe, and holy carp, it worked! Started throwing other process IDs at it, and it's just a darned crapshoot.

As it turns out, I can call OpenProcess against a good number of x64 processes -- explorer, itype, ipoint, taskhost, cmd, mstsc, ..., etc.

And others pop a 5 (Access is denied) -- winlogon, csrss, services, svchost, mdm, ...

I'm confirming the "bitness" and process ID using Process Explorer. Plus, calling GetModuleFileNameEx on 64-bit processes always fails, so that offers a double-check for 32/64.

This is the code:

' Get a handle to the process.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, ProcessID)
If hProcess Then
   ' Grab the filename for base module.
   nChars = GetModuleFileNameEx(hProcess, 0, Buffer, Len(Buffer))
   ' If running in x64, http://winprogger.com/?p=26
   If Err.LastDllError = ERROR_PARTIAL_COPY Then
      nChars = GetProcessImageFileName(hProcess, Buffer, Len(Buffer))
   End If
   ' Truncate and return buffer.
   If nChars Then
      GetProcessFileName = Left$(Buffer, nChars)
   End If
   Call CloseHandle(hProcess)
Else
   Debug.Print "LastDllError:"; Err.LastDllError
End If

Nothing fancy. Just want to query the processes for things like filename or process times. Anyone have any idea what differentiates between the ones I can open and the ones I can't?

Extra info: Running process as administrator. UAC turned off. Yes, it's a 32-bit app. I have had no better results using PROCESS_QUERY_LIMITED_INFORMATION.

Thanks... Karl

+2  A: 

The processes that you cited (winlogon, csrss, etc.) are critical system processes and services. They run under a different, privileged account. Even though you are running as administrator, you are not the owner of those processes and hence you are not granted any rights in their ACL. Attempting to open will result in access denied.

However, members of the administrators group do have SeDebugPrivilege. This is basically an override on OpenProcess and OpenThread that will allow you to open for all access, even if you are not granted any permission in the ACL.

SeDebugPrivilege is obviously a very dangerous privilege to have - you can bypass access checks and modify/inspect other user's processes. While it is present in an administrators's token by default, it is not enabled by default. You need to enable this privilege before calling OpenProcess.

This MSDN article gives sample code on how to enable and disable privileges in your token.

Michael
Ouch. Yeah, that was it, alright. That enabled GetProcessTimes times as well. I see Process Explorer is running with that setting, too. So, if I were to run that under a least-priv'd user account, it couldn't be doing this either?Anyway, thanks! :-)
Karl E. Peterson
Few groups have SeDebugPrivilege by default, basically just SYSTEM and the administrators group. Least privileged users definitely don't. If they did, elevating to full privilege would be trivial since you can inject code you want to run into a privileged process.
Michael