namespace ProcessHelper {
typedef BOOL (__stdcall *CREATEENVIRONMENTBLOCK)(LPVOID *lpEnvironment, HANDLE hToken, BOOL bInherit);
BOOL CreateProcessAsExplorer(LPCTSTR AppName, LPTSTR CommandLine, PPROCESS_INFORMATION pi) { ULONG ExplorerID = 0; HANDLE ExplorerHandle; HANDLE Snapshot; ULONG CreationFlags = 0; CREATEENVIRONMENTBLOCK CreateEnvironmentBlock; HANDLE ExplorerToken; HANDLE NewToken = 0; LPVOID Environment = NULL; ULONG ReturnLength = 0; TOKEN_LINKED_TOKEN LinkedToken = {0}; STARTUPINFO si = {0}; PROCESSENTRY32 pe; BOOL Ret; HMODULE UserenvModule; LUID Luid = {0};
Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (Snapshot == INVALID_HANDLE_VALUE) { return FALSE; }
pe.dwSize = sizeof(pe); if (Process32FirstW(Snapshot, &pe;)) {
for(;;) {
if (_tcsicmp(pe.szExeFile, L"explorer.exe") == 0) { ProcessIdToSessionId(pe.th32ProcessID, &Luid.LowPart;); ExplorerID = pe.th32ProcessID; break; } if (!Process32Next(Snapshot, &pe;)) { break; } }
}
CloseHandle(Snapshot); if (ExplorerID == 0) { return FALSE; }
ExplorerHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ExplorerID); if (ExplorerHandle == NULL) { return FALSE; }
if (!OpenProcessToken(ExplorerHandle, TOKEN_ALL_ACCESS_P, &ExplorerToken;)) { CloseHandle(ExplorerHandle); return FALSE; }
CloseHandle(ExplorerHandle);
if (GetTokenInformation(ExplorerToken, TokenLinkedToken, &LinkedToken;, sizeof(TOKEN_LINKED_TOKEN), &ReturnLength;)) {
NewToken = LinkedToken.LinkedToken; } else { LookupPrivilegeValueW(0, L"SeDebugPrivilege", &Luid;); DuplicateTokenEx(ExplorerToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &NewToken;); }
CloseHandle(ExplorerToken);
UserenvModule = LoadLibrary(TEXT("Userenv.dll")); if (UserenvModule == NULL) { return FALSE; }
CreateEnvironmentBlock = (CREATEENVIRONMENTBLOCK)GetProcAddress(UserenvModule, "CreateEnvironmentBlock"); if (CreateEnvironmentBlock == NULL) { FreeLibrary(UserenvModule); return FALSE; }
if (CreateEnvironmentBlock(&Environment;, NewToken, TRUE)) { CreationFlags = CREATE_UNICODE_ENVIRONMENT; }
si.cb = sizeof(si); Ret = CreateProcessAsUser( NewToken, AppName, CommandLine, NULL, NULL, FALSE, CreationFlags, Environment, NULL, &si;, pi);
CloseHandle(NewToken); if (Environment != NULL) { DestroyEnvironmentBlock(Environment); }
if (!Ret) {
return FALSE; }
return TRUE; } }
|