Process.GetProcesses() 哪里 process.IsElevated?
Process.GetProcesses() WHERE process.IsElevated?
我想在非管理用户登录时在机器上监控提升的进程 运行ning。
基本上,我想 运行 以下来自 C# 的编造代码:
var elevatedWindows = Process.GetProcesses().Where(p => p.IsElevated || p.ChildWindows.Any(cw => cw.IsElevated));
到目前为止,我发现唯一能提供我想要的信息的似乎是 .NET System.Diagnostics.Process class 中的一个 BUG,如下所述:
http://www.codeproject.com/Articles/302856/Bugs-in-System-Diagnostics-Process-Class
如果我理解正确,文章说如果我的程序没有 运行 提升的权限,如果您尝试获得提升的权限,它将生成 NativeErrorCode
等于 5 的 WIN32 异常进程的 StartTime
或 HasExited
属性。
我觉得这可能是解决我的问题的简单方法 - 尝试从非提升的程序中获取 StartTime
或 HasExited
,如果它产生该错误,则它是一个提升的过程。
问题是,我似乎无法让它可靠地工作,当我手动右键单击记事本并选择 "Run as Administrator" 并使用 [=19= 时,HasExited
错误不可靠]
更麻烦的是我无法隔离单个资源管理器Windows。 Explorer.exe 始终是 运行ning,并且 可以 提升,但即使它是 运行ning 没有提升,您仍然可以手动启动该过程,因为提升了许多不同的方式,none 其中影响父 explorer.exe 进程。
所以我想我需要从生成的进程或其子线程中找到 WindowHandles,并以某种方式查看 window 是否已提升?
如有任何帮助,我们将不胜感激。
不确定 "elevated window" 是什么意思。该过程已提升,而不是其 windows。启动一个新的资源管理器视图会生成一个新进程。
也就是说,您可以使用 Interop 来确定进程是否已提升:
- 调用
OpenProcess
获取进程句柄
- 调用
OpenProcessToken
打开与您的进程关联的访问令牌
- 然后在
GetTokenInformation
中使用类似下面的内容
代码:
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;
}
}
我想在非管理用户登录时在机器上监控提升的进程 运行ning。
基本上,我想 运行 以下来自 C# 的编造代码:
var elevatedWindows = Process.GetProcesses().Where(p => p.IsElevated || p.ChildWindows.Any(cw => cw.IsElevated));
到目前为止,我发现唯一能提供我想要的信息的似乎是 .NET System.Diagnostics.Process class 中的一个 BUG,如下所述:
http://www.codeproject.com/Articles/302856/Bugs-in-System-Diagnostics-Process-Class
如果我理解正确,文章说如果我的程序没有 运行 提升的权限,如果您尝试获得提升的权限,它将生成 NativeErrorCode
等于 5 的 WIN32 异常进程的 StartTime
或 HasExited
属性。
我觉得这可能是解决我的问题的简单方法 - 尝试从非提升的程序中获取 StartTime
或 HasExited
,如果它产生该错误,则它是一个提升的过程。
问题是,我似乎无法让它可靠地工作,当我手动右键单击记事本并选择 "Run as Administrator" 并使用 [=19= 时,HasExited
错误不可靠]
更麻烦的是我无法隔离单个资源管理器Windows。 Explorer.exe 始终是 运行ning,并且 可以 提升,但即使它是 运行ning 没有提升,您仍然可以手动启动该过程,因为提升了许多不同的方式,none 其中影响父 explorer.exe 进程。
所以我想我需要从生成的进程或其子线程中找到 WindowHandles,并以某种方式查看 window 是否已提升?
如有任何帮助,我们将不胜感激。
不确定 "elevated window" 是什么意思。该过程已提升,而不是其 windows。启动一个新的资源管理器视图会生成一个新进程。
也就是说,您可以使用 Interop 来确定进程是否已提升:
- 调用
OpenProcess
获取进程句柄 - 调用
OpenProcessToken
打开与您的进程关联的访问令牌 - 然后在
GetTokenInformation
中使用类似下面的内容
代码:
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;
}
}