这份代码我印象中只在win7上有用。
#include <windows.h>
#include <tlhelp32.h>
#include <string>
void EnablePrivilege(std::wstring privilegeName)
{
HANDLE hToken;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
return;
LUID luid;
if (!LookupPrivilegeValueW(nullptr, privilegeName.c_str(), &luid))
{
CloseHandle(hToken);
return;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr))
{
CloseHandle(hToken);
return;
}
CloseHandle(hToken);
}
int main()
{
DWORD dwSessionId = WTSGetActiveConsoleSessionId(); // 得到当前用户的会话ID
DWORD winlogonPid(0);
HANDLE hPToken(nullptr), hUserTokenDup(nullptr);
PROCESSENTRY32 procEntry; //用来存放快照进程信息的一个结构体
//函数为指定的进程、进程使用的堆[HEAP]、模块[MODULE]、线程[THREAD])建立一个快照[snapshot]
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE)
{
return 1;
}
procEntry.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnap, &procEntry)) //获得第一个进程的句柄.
{
return 1;
}
do
{
if (_wcsicmp(procEntry.szExeFile, _T("winlogon.exe")) == 0) //查找winlogon.exe
{
// We found a winlogon process...make sure it's running in the console session
DWORD winlogonSessId = 0;
if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId)//得到与进程ID对应的终端服务会话ID
{
winlogonPid = procEntry.th32ProcessID;
break;
}
}
} while (Process32Next(hSnap, &procEntry)); //获得下一个进程的句柄
////////////////////////////////////////////////////////////////////////
HANDLE hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonPid); //获得进程句柄
if (!::OpenProcessToken(hProcess, MAXIMUM_ALLOWED, &hPToken)) //获得令牌句柄
{
printf("%d\r\n", GetLastError());
}
BOOL bRes = DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hUserTokenDup);//创建模拟令牌
int dup = GetLastError();
SetTokenInformation(hUserTokenDup, TokenSessionId, (void*)dwSessionId, sizeof(DWORD));
//int dup = GetLastError();
EnablePrivilege(SE_DEBUG_NAME);
EnablePrivilege(SE_INCREASE_QUOTA_NAME);
EnablePrivilege(SE_IMPERSONATE_NAME);
EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME);
#if 0
if (!AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL)) //这个函数启用或禁止指定访问令牌的特权
{
int abc = GetLastError();
printf("Adjust Privilege value Error: %u\n", GetLastError());
}
#endif
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("Token does not have the provilege\n");
}
STARTUPINFOW startupInfo;
ZeroMemory(&startupInfo, sizeof(STARTUPINFOW));
//startupInfo.lpDesktop = L"Winsta0\\Default";
PROCESS_INFORMATION processInfo;
ZeroMemory(&processInfo, sizeof(PROCESS_INFORMATION));
INT n(0);
BOOL bRet = CreateProcessWithTokenW(
hUserTokenDup,
0,
_T("C:\\Windows\\System32\\notepad.exe"),
nullptr,//const_cast<LPWSTR>(commandLine.c_str()),
0,
nullptr,
nullptr,
&startupInfo,
&processInfo);
n = GetLastError();
#if 0
DWORD bResult = CreateProcessAsUser(
hUserTokenDup, // 这个参数上面已经得到
_T("C:\\Windows\\System32\\notepad.exe"), //执行文件的路径
NULL, // command line
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
0, // creation flags
0, // pointer to new environment block
NULL, // name of current directory
&startupInfo, // pointer to STARTUPINFO structure
&processInfo // receives information about new process
);
n = GetLastError();
#endif
return 0;
}
