c++ 让指定进程以管理员权限运行,并且绕过UAC提示
时间: 2024-01-27 13:03:29 浏览: 298
在 Windows 中,要以管理员权限运行一个进程并绕过 UAC 提示,可以使用以下方法:
1. 使用 ShellExecuteEx 函数启动进程。该函数可以在指定的进程上下文中启动应用程序。
2. 在启动进程之前,需要创建一个管理员特权的进程令牌。可以使用 OpenProcessToken 和 DuplicateTokenEx 函数来创建一个管理员特权的令牌。
3. 使用 CreateProcessAsUser 函数以管理员权限运行指定的进程。这个函数会将进程启动在指定的用户上下文中。
下面是一个简单的 C++ 代码示例:
```
#include <windows.h>
#include <sddl.h>
#include <userenv.h>
#include <shlobj.h>
#include <iostream>
void RunElevated(const wchar_t* cmdLine)
{
SHELLEXECUTEINFO sei = { sizeof(sei) };
sei.lpVerb = L"runas";
sei.lpFile = cmdLine;
sei.hwnd = NULL;
sei.nShow = SW_NORMAL;
if (!ShellExecuteEx(&sei)) {
DWORD error = GetLastError();
if (error == ERROR_CANCELLED) {
// The user refused to allow privileges elevation.
std::cerr << "User refused to allow privileges elevation.\n";
} else {
std::cerr << "Failed to elevate privileges. Error code: " << error << "\n";
}
}
}
int main()
{
// Get the current process token.
HANDLE tokenHandle;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &tokenHandle)) {
std::cerr << "Failed to open process token. Error code: " << GetLastError() << "\n";
return 1;
}
// Duplicate the token with admin privileges.
HANDLE elevatedTokenHandle;
if (!DuplicateTokenEx(tokenHandle, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, &elevatedTokenHandle)) {
std::cerr << "Failed to duplicate process token. Error code: " << GetLastError() << "\n";
CloseHandle(tokenHandle);
return 1;
}
// Set the elevation level of the new token to full.
TOKEN_ELEVATION_TYPE elevationType;
DWORD elevationSize = sizeof(TOKEN_ELEVATION_TYPE);
if (!GetTokenInformation(elevatedTokenHandle, TokenElevationType, &elevationType, sizeof(elevationType), &elevationSize)) {
std::cerr << "Failed to get token information. Error code: " << GetLastError() << "\n";
CloseHandle(tokenHandle);
CloseHandle(elevatedTokenHandle);
return 1;
}
if (elevationType != TokenElevationTypeFull) {
TOKEN_ELEVATION elevation = { 0 };
elevation.TokenIsElevated = 1;
if (!SetTokenInformation(elevatedTokenHandle, TokenElevation, &elevation, sizeof(elevation))) {
std::cerr << "Failed to set token information. Error code: " << GetLastError() << "\n";
CloseHandle(tokenHandle);
CloseHandle(elevatedTokenHandle);
return 1;
}
}
// Get the user name and domain name for the current user.
DWORD size = 0;
GetUserNameEx(NameSamCompatible, NULL, &size);
std::wstring userName(size, L'\0');
GetUserNameEx(NameSamCompatible, &userName[0], &size);
size = 0;
GetComputerNameEx(ComputerNameDnsDomain, NULL, &size);
std::wstring domainName(size, L'\0');
GetComputerNameEx(ComputerNameDnsDomain, &domainName[0], &size);
// Create the user profile for the new user token.
PROFILEINFO profileInfo = { sizeof(profileInfo) };
profileInfo.dwFlags = PI_NOUI;
profileInfo.lpUserName = &userName[0];
profileInfo.lpProfilePath = L"";
profileInfo.lpDefaultPath = L"";
profileInfo.lpServerName = &domainName[0];
profileInfo.lpPolicyPath = L"";
profileInfo.hProfile = NULL;
DWORD sessionId;
HANDLE userTokenHandle;
if (!CreateProfile(&profileInfo, &userTokenHandle)) {
std::cerr << "Failed to create user profile. Error code: " << GetLastError() << "\n";
CloseHandle(tokenHandle);
CloseHandle(elevatedTokenHandle);
return 1;
}
if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId)) {
std::cerr << "Failed to get session ID. Error code: " << GetLastError() << "\n";
CloseHandle(tokenHandle);
CloseHandle(elevatedTokenHandle);
CloseHandle(userTokenHandle);
return 1;
}
if (!ImpersonateLoggedOnUser(userTokenHandle)) {
std::cerr << "Failed to impersonate user. Error code: " << GetLastError() << "\n";
CloseHandle(tokenHandle);
CloseHandle(elevatedTokenHandle);
CloseHandle(userTokenHandle);
return 1;
}
// Get the path to the executable.
wchar_t exePath[MAX_PATH];
if (GetModuleFileName(NULL, exePath, MAX_PATH) == 0) {
std::cerr << "Failed to get executable path. Error code: " << GetLastError() << "\n";
CloseHandle(tokenHandle);
CloseHandle(elevatedTokenHandle);
CloseHandle(userTokenHandle);
return 1;
}
RunElevated(exePath);
// Restore the original token and close the elevated token.
if (!RevertToSelf()) {
std::cerr << "Failed to revert to self. Error code: " << GetLastError() << "\n";
CloseHandle(tokenHandle);
CloseHandle(elevatedTokenHandle);
CloseHandle(userTokenHandle);
return 1;
}
CloseHandle(tokenHandle);
CloseHandle(elevatedTokenHandle);
CloseHandle(userTokenHandle);
return 0;
}
```
这个代码示例使用了 ShellExecuteEx 函数来以管理员权限运行指定的进程。如果进程启动失败,将会输出错误信息。
阅读全文