Reputation: 925
I'd like to monitor elevated processes running on a machine while a non-administrative user is logged in.
Basically, I want to run the following made-up code from C#:
var elevatedWindows = Process.GetProcesses().Where(p => p.IsElevated || p.ChildWindows.Any(cw => cw.IsElevated));
So far, the only thing I've found to give me the information I want appears to be a BUG in the .NET System.Diagnostics.Process class, as described here:
http://www.codeproject.com/Articles/302856/Bugs-in-System-Diagnostics-Process-Class
If I understand this correctly, the article says that if my program is not running with elevated permissions, it will generate a WIN32 exception with NativeErrorCode
equal to 5 if you try to get an elevated process's StartTime
or HasExited
properties.
I feel like this could be an easy workaround for my issue - try to get StartTime
or HasExited
from a non-elevated program and if it produces that error, it is an elevated process.
Problem is, I can't seem to get this to work reliably, HasExited
errors unreliably when I've manually right-clicked notepad and selected "Run as Administrator", and used GetProcessesByName("notepad")
Even more troublesome is I can't isolate individual Explorer Windows. Explorer.exe is always running, and can be elevated, but even if it is running WITHOUT elevation you can still manually start the process as elevated a number of different ways, none of which effect the parent explorer.exe process.
So I guess I need to find WindowHandles from the spawned processes, or their child threads, and somehow see if the window is elevated?
Any help would be appreciated.
Upvotes: 0
Views: 1730
Reputation: 49013
Not sure to understand what you mean by "elevated window". The process is elevated, not its windows. Starting a new Explorer view spawns a new process.
That said, you could use Interop to determine whether a process is elevated or not:
OpenProcess
to get a process handleOpenProcessToken
to open the access token associated with your processGetTokenInformation
Code :
public enum ElevationType
{
Default = 1,
Full = 2,
Limited = 3
}
// Do add some exception handling...etc.
public static ElevationType GetProcessElevationTypeByTokenHandle(IntPtr hTok)
{
if (hTok.IsNotNull)
{
// Get token information struct length
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa379626(v=vs.85).aspx for constants
int ret = 0;
GetTokenInformation(hTok, TokenInformationClass.TokenElevationType, IntPtr.Zero, 0, ret);
IntPtr tokenInformation = Marshal.AllocHGlobal(ret);
// Get token information struct
// With then TokenElevationType constant, it will returns a TOKEN_ELEVATION_TYPE value
// See https://msdn.microsoft.com/en-us/library/windows/desktop/bb530718(v=vs.85).aspx
GetTokenInformation(hTok, TokenInformationClass.TokenElevationType, tokenInformation, ret, null);
// Get a valid structure
var value = Marshal.ReadInt32(tokenInformation, 0);
Marshal.FreeHGlobal(tokenInformation);
return (ElevationType)value;
}
else
{
return ElevationType.Default;
}
}
Upvotes: 1