- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在 Windows 7 和 visual studio 2015 上创建一个交互式服务,它能够初始化应用程序 UI,但 WTSQueryUserToken 方法正在重新调整为 false。
IntPtr hToken = IntPtr.Zero;
if (WTSQueryUserToken(tSessionInfo.SessionID, out hToken)) //FALSE returned
我真的没有太多 C# 经验,所以我在网上搜索得到答案,我发现“要成功调用此函数 (WTSQueryUserToken),调用应用程序必须在 LocalSystem 帐户的上下文中运行并拥有 SE_TCB_NAME 特权”,但我不知道如何为代码授予应用程序 SE_TCB_NAME 特权。有谁知道我该如何编码?
谢谢。
最佳答案
您必须进行模拟才能在用户帐户下启动应用程序。
这是一个示例,还展示了如何获得 SE_TCB_NAME 权限。
在此示例中,我们首先获取当前进程的安全 token ,然后提升权限以包含 SE_TCB_NAME 权限。
完成后,我们将获取浏览器进程的 SessionId,并复制与其关联的安全 token ,然后将其传递给 CreateProcessAsUser。
public class Impersonation
{
#region DLL Imports
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
internal const int TOKEN_ASSIGN_PRIMARY = 0x0001;
internal const int TOKEN_DUPLICATE = 0x0002;
internal const int TOKEN_IMPERSONATE = 0X00000004;
internal const int TOKEN_ADJUST_DEFAULT = 0x0080;
internal const int TOKEN_ADJUST_SESSIONID = 0x0100;
internal const int MAXIMUM_ALLOWED = 0x2000000;
internal const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
internal const int NORMAL_PRIORITY_CLASS = 0x20;
internal const int CREATE_NEW_CONSOLE = 0x00000010;
internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
internal const string SE_TCB_NAME = "SeTcbPrivilege";
internal const string SE_RESTORE_NAME = "SeRestorePrivilege";
private static WindowsImpersonationContext impersonatedUser;
public static IntPtr hToken = IntPtr.Zero;
public static IntPtr dupeTokenHandle = IntPtr.Zero;
const string SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege";
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}
struct STARTUPINFO
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
public enum ShowCommands : int
{
SW_HIDE = 0,
SW_SHOWNORMAL = 1,
SW_NORMAL = 1,
SW_SHOWMINIMIZED = 2,
SW_SHOWMAXIMIZED = 3,
SW_MAXIMIZE = 3,
SW_SHOWNOACTIVATE = 4,
SW_SHOW = 5,
SW_MINIMIZE = 6,
SW_SHOWMINNOACTIVE = 7,
SW_SHOWNA = 8,
SW_RESTORE = 9,
SW_SHOWDEFAULT = 10,
SW_FORCEMINIMIZE = 11,
SW_MAX = 11
}
[DllImport("shell32.dll")]
static extern IntPtr ShellExecute(
IntPtr hwnd,
string lpOperation,
string lpFile,
string lpParameters,
string lpDirectory,
ShowCommands nShowCmd);
[DllImport("advapi32.dll", SetLastError = true)]
static extern int ImpersonateLoggedOnUser(IntPtr hToken);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("kernel32", SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
static extern bool DuplicateTokenEx(IntPtr hExistingToken, Int32 dwDesiredAccess,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
Int32 ImpersonationLevel, Int32 dwTokenType,
ref IntPtr phNewToken);
[DllImport("userenv.dll", SetLastError = true)]
static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment, IntPtr hToken, bool bInherit);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool CreateProcessAsUser(
IntPtr hToken,
string lpApplicationName,
string lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
#endregion
private static readonly ILog log = LogManager.GetLogger(typeof(Impersonation));
private static void WriteToLog(string message)
{
log.Debug(message);
}
/// <summary>
/// Duplicates the token information derived
/// from the logged in user's credentials. This
/// is required to run the application on the
/// logged in users desktop.
/// </summary>
/// <returns>Returns true if the application was successfully started in the user's desktop.</returns>
public static bool ExecuteAppAsLoggedOnUser(string AppName, string CmdLineArgs)
{
WriteToLog("In ExecuteAppAsLoggedOnUser for all users.");
IntPtr LoggedInUserToken = IntPtr.Zero;
IntPtr DuplicateToken = IntPtr.Zero;
IntPtr ShellProcessToken = IntPtr.Zero;
if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TOKEN_ADJUST_PRIVILEGES, ref LoggedInUserToken))
{
WriteToLog("OpenProcessToken failed: " + Marshal.GetLastWin32Error());
return false;
}
else
{
//Below part for increasing the UAC previleges to the token.
TokPriv1Luid tp = new TokPriv1Luid();
tp.Count = 1;
tp.Luid = 0;
if (!LookupPrivilegeValue(null, SE_INCREASE_QUOTA_NAME, ref tp.Luid))
{
WriteToLog("LookupPrivilegeValue failed: " + Marshal.GetLastWin32Error());
return false;
}
tp.Attr = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(LoggedInUserToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero))
{
WriteToLog("OpenProcessToken failed: " + Marshal.GetLastWin32Error());
return false;
}
CloseHandle(LoggedInUserToken);
}
List<Process> explorerProcessList = new List<Process>();
string trayProcessName = AppName.Substring(AppName.LastIndexOf(@"\") + 1, AppName.Length - AppName.LastIndexOf(@"\") - 5);
foreach (Process explorerProcess in Process.GetProcessesByName("explorer"))
{
bool IsProcessRunningForUser = false;
foreach (Process PHTrayProcess in Process.GetProcessesByName(trayProcessName))
{
if (explorerProcess.SessionId == PHTrayProcess.SessionId)
{
if (log.IsDebugEnabled) log.Debug(trayProcessName + " is already running for user SessionId " + explorerProcess.SessionId);
IsProcessRunningForUser = true;
break;
}
}
if (((Environment.OSVersion.Version.Major > 5 && explorerProcess.SessionId > 0)
|| Environment.OSVersion.Version.Major == 5)
&& !IsProcessRunningForUser)
{
if (log.IsDebugEnabled) log.Debug(trayProcessName + " is not running for user SessionId " + explorerProcess.SessionId);
explorerProcessList.Add(explorerProcess);
}
}
if (null != explorerProcessList && explorerProcessList.Count > 0)
{
foreach (Process explorerProcess in explorerProcessList)
{
Process ShellProcess = explorerProcess;
ShellProcess.StartInfo.LoadUserProfile = true;
try
{
int tokenRights = MAXIMUM_ALLOWED; //TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID;
if (!OpenProcessToken(ShellProcess.Handle, tokenRights, ref ShellProcessToken))
{
WriteToLog("Unable to OpenProcessToken " + Marshal.GetLastWin32Error());
return false;
}
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
sa.nLength = Marshal.SizeOf(sa);
if (!DuplicateTokenEx(ShellProcessToken, tokenRights, ref sa, 2, 1, ref DuplicateToken))
{
WriteToLog("Unable to duplicate token " + Marshal.GetLastWin32Error());
return false;
}
WriteToLog("Duplicated the token " + WindowsIdentity.GetCurrent().Name);
SECURITY_ATTRIBUTES processAttributes = new SECURITY_ATTRIBUTES();
SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES();
PROCESS_INFORMATION pi;
STARTUPINFO si = new STARTUPINFO();
si.cb = (uint)Marshal.SizeOf(si);
IntPtr UserEnvironment = IntPtr.Zero;
uint dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
if (!CreateEnvironmentBlock(out UserEnvironment, ShellProcessToken, true))
{
WriteToLog("Unable to create user's enviroment block " + Marshal.GetLastWin32Error());
}
else
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
}
//string userName = getUserName(UserEnvironment);
//WriteToLog("UserName:::" + userName);
if (!CreateProcessAsUser(DuplicateToken, AppName, (CmdLineArgs == null) ? string.Empty : CmdLineArgs, ref processAttributes, ref threadAttributes, true, dwCreationFlags, UserEnvironment, AppName.Substring(0, AppName.LastIndexOf('\\')), ref si, out pi))
{
WriteToLog("Unable to create process " + Marshal.GetLastWin32Error());
if (Marshal.GetLastWin32Error() == 740)
{
WriteToLog("Please check the installation as some elevated permissions is required to execute the binaries");
}
return false;
}
Process trayApp = Process.GetProcessById(Convert.ToInt32(pi.dwProcessId));
trayApp.StartInfo.LoadUserProfile = true;
}
finally
{
if (ShellProcessToken != null) CloseHandle(ShellProcessToken);
if (DuplicateToken != null) CloseHandle(DuplicateToken);
}
}
}
else
{
WriteToLog("No user has been identified to have logged into the system.");
return false;
}
WriteToLog("Finished ExecuteAppAsLoggedOnUser for all users.");
return true;
}
/// <summary>
/// Impersonate the user credentials. This would be required by
/// the service applications to impersonate the logged in user
/// credentials to launch certain applications or applying the
/// power scheme.
/// </summary>
/// <returns>Returns true if the impersonation is successful.</returns>
public static bool ImpersonateUser()
{
// For simplicity I'm using the PID of System here
//if (log.IsDebugEnabled) log.Debug("GetaProcess for Explorer");
Process Pname = GetaProcess("explorer");
//This can be null if no user has not logged into the system.
if (Pname == null) return false;
int pid = Pname.Id;
Process proc = Process.GetProcessById(pid);
if (OpenProcessToken(proc.Handle, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE, ref hToken)) // != 0)
{
WindowsIdentity newId = new WindowsIdentity(hToken);
//log.Debug(newId.Owner);
try
{
const int SecurityImpersonation = 2;
dupeTokenHandle = DupeToken(hToken,
SecurityImpersonation);
if (IntPtr.Zero == dupeTokenHandle)
{
string s = String.Format("Dup failed {0}, privilege not held",
Marshal.GetLastWin32Error());
throw new Exception(s);
}
impersonatedUser = newId.Impersonate();
return true;
}
finally
{
CloseHandle(hToken);
}
}
else
{
string s = String.Format("OpenProcess Failed {0}, privilege not held", Marshal.GetLastWin32Error());
throw new Exception(s);
}
}
/// <summary>
/// Duplicate the token for user impersonation.
/// </summary>
/// <param name="token">Token to duplicate for impersonation</param>
/// <param name="Level">Impersonation security level, currently hardcored to 2</param>
/// <returns>Returns duplicated token</returns>
public static IntPtr DupeToken(IntPtr token, int Level)
{
IntPtr dupeTokenHandle = IntPtr.Zero;
bool retVal = DuplicateToken(token, Level, ref dupeTokenHandle);
return dupeTokenHandle;
}
/// <summary>
/// Get the process running locally on the machine.
/// If the specified process does not exists, it
/// returns back the current process.
/// </summary>
/// <param name="processname">Process name to get</param>
/// <returns>Returns back the process</returns>
public static Process GetaProcess(string processname)
{
Process[] aProc = Process.GetProcessesByName(processname);
if (aProc.Length > 0) return aProc[0];
else
{
//if (log.IsDebugEnabled) log.Debug("Explorer is not running");
Process currentProcess = Process.GetCurrentProcess();
return currentProcess;
}
}
/// <summary>
/// Roleback the impersonation if applied previously.
/// </summary>
public static void UndoImpersonate()
{
impersonatedUser.Undo();
if (hToken != IntPtr.Zero) CloseHandle(hToken);
if (dupeTokenHandle != IntPtr.Zero) CloseHandle(dupeTokenHandle);
return;
}
}
然后就可以了
Impersonation.ExecuteAppAsLoggedOnUser("applicationName", null);
关于c# - WTSQueryUserToken 返回 FALSE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42717691/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!