Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save b-epelbaum/b5e4822e24c5728aef7044def8041663 to your computer and use it in GitHub Desktop.

Select an option

Save b-epelbaum/b5e4822e24c5728aef7044def8041663 to your computer and use it in GitHub Desktop.
Start an elevated process impersonified by currently logged user
BOOL Helpers::create_elevated_process_as_logged_user(const wchar_t* lpApplicationName, wchar_t* lpCommandLine)
{
BOOL ret_val = FALSE;
if (const DWORD session_id = WTSGetActiveConsoleSessionId(); session_id != 0xFFFFFFFF)
{
HANDLE h_token = nullptr;
if (WTSQueryUserToken(session_id, &h_token))
{
HANDLE h_token_dup = nullptr;
if (DuplicateTokenEx(h_token, TOKEN_ALL_ACCESS, nullptr, SecurityImpersonation, TokenPrimary, &h_token_dup))
{
//The token is not elevated, we will build an elevated token for the user.
TOKEN_LINKED_TOKEN linked_token = {};
DWORD dw_size = sizeof(linked_token);
// Get the linked token, which is the elevated version of the current token
if (GetTokenInformation(h_token_dup, TokenLinkedToken, &linked_token, dw_size, &dw_size))
{
HANDLE h_primary_token = nullptr;
if (DuplicateTokenEx(linked_token.LinkedToken, MAXIMUM_ALLOWED, nullptr, SecurityImpersonation, TokenPrimary, &h_primary_token))
{
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
PROCESS_INFORMATION pi{};
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
LPVOID p_env = nullptr;
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = const_cast<LPWSTR>(L"WinSta0\\Default");
si.wShowWindow = SW_SHOW;
si.dwFlags = STARTF_USESHOWWINDOW;
if (CreateEnvironmentBlock(&p_env, h_primary_token, FALSE))
{
ret_val = CreateProcessAsUser(h_primary_token, lpApplicationName, lpCommandLine, nullptr, nullptr, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
p_env, nullptr, &si, &pi);
if (ret_val)
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
if (p_env)
{
DestroyEnvironmentBlock(p_env);
}
}
}
if (h_primary_token)
{
CloseHandle(h_primary_token);
}
}
}
if (h_token_dup)
{
CloseHandle(h_token_dup);
}
}
if (h_token)
{
CloseHandle(h_token);
}
}
return ret_val;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment