以下函数调用后创建当前用户的进程,前提是当前执行的进程以system权限运行。
vector<int> FindProcessByNameEx(char *exefile)
{
int nID = -1;
vector<int > vecRes;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
try
{
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
throw 1;
}
int nWlen = MultiByteToWideChar(CP_ACP, 0, exefile, strlen(exefile), NULL, 0);
WCHAR *buffer = new WCHAR[nWlen + 1];
MultiByteToWideChar(CP_ACP, 0, exefile, strlen(exefile), buffer, nWlen);
buffer[nWlen] = '\0';;
//遍历进程快照。轮流显示每个进程的信息
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
while (bMore)
{
if (wcscmp(pe32.szExeFile, buffer) == 0)
{
nID = (int)pe32.th32ProcessID;
vecRes.push_back(nID);
}
bMore = ::Process32Next(hProcessSnap, &pe32);
}
//清除snapshot对象
if (buffer == NULL)
{
delete buffer;
buffer = NULL;
}
if (hProcessSnap == NULL)
{
::CloseHandle(hProcessSnap);
hProcessSnap = NULL;
}
}
catch (...)
{
vecRes.clear();
}
return vecRes;
}
BOOL _CreateProcessAsUser(LPSTR command_line, PROCESS_INFORMATION &pi)
{
BOOL ret = FALSE;
DWORD sessionId = 0;
HANDLE hToken = NULL;
HANDLE hTokenLink = NULL;
HANDLE hTokenUser = NULL;
STARTUPINFOA si;
LUID luid;
TOKEN_PRIVILEGES tp;
DWORD dwCreationFlags = 0;
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
DWORD dwSize = sizeof(hTokenLink);
//获取explorer.exe的进程
DWORD dwProcessId = 0;
vector<int > vecProcessId = FindProcessByNameEx((char *)"explorer.exe");
for(int i=0; i< vecProcessId.size(); i++)
{
dwProcessId = vecProcessId[i];
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessId);
if (hProcess == NULL)
continue;
HANDLE hTokenTemp = NULL;
string strUser, strDomain;
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hTokenTemp))
{
::CloseHandle(hTokenTemp);
continue;
}
BOOL bRet = GetLogonFromToken(hTokenTemp, strUser, strDomain);
if (bRet)
{
if (strUser == m_InfoHandler->m_iComputerInfo.name)
{
break;
}
}
::CloseHandle(hTokenTemp);
::CloseHandle(hProcess);
}
ProcessIdToSessionId(dwProcessId, &sessionId);
try
{
// 获取进程的令牌句柄
ret = WTSQueryUserToken(sessionId, &hToken);
if (!ret)
{
throw 1;
}
ret = GetTokenInformation(hToken, TokenLinkedToken, &hTokenLink, dwSize, &dwSize);
if (!ret)
{
throw 2;
}
ret = DuplicateTokenEx(hTokenLink, TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &hTokenUser);
if (!ret)
{
throw 3;
}
//查找DEBUG权限的UID
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
throw 4;
}
//设置令牌信息
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
//应用令牌权限
if (!AdjustTokenPrivileges(hTokenUser, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL, NULL))
{
throw 5;
}
//创建进程环境块,保证环境块是在用户桌面的环境下
LPVOID pEnv = NULL;
if (CreateEnvironmentBlock(&pEnv, hTokenUser, TRUE))
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT | NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW;
}
else
{
pEnv = NULL;
}
ret = CreateProcessAsUserA(hTokenUser, nullptr, command_line, nullptr, nullptr, TRUE, dwCreationFlags, pEnv, nullptr, &si, &pi);
if (!ret)
{
throw 7;
}
}
catch (...)
{
ret = false;
}
if (hToken == NULL)
{
::CloseHandle(hToken);
}
if (hTokenLink == NULL)
{
::CloseHandle(hTokenLink);
}
if (hTokenUser == NULL)
{
::CloseHandle(hTokenUser);
}
return ret;
}
该代码实现了一个查找指定进程并创建新进程的功能。首先,通过`FindProcessByNameEx`函数找到名为'explorer.exe'的进程,获取其令牌,然后模拟该用户权限使用`CreateProcessAsUser`创建新进程。过程中涉及到令牌复制、权限调整等操作,确保新进程在用户权限下执行。

1万+

被折叠的 条评论
为什么被折叠?



