0CCh Blog

系统进程创建管理员进程的方法

代码如下:


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;
}
}