服务程序创建用户进程

头文件

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <tchar.h>
#include <Tlhelp32.h>
#include <UserEnv.h>
#include <io.h>

日志
 

void writefile(TCHAR* szBuf)
{
	static FILE* fp = NULL;


	if (NULL == fp)
	{
		fp = fopen(".\\tmp.log", "w+b");
	}


	if (NULL == fp)
	{
		system("echo open voi.log fialed >> .\\tmp2.log");
		return;
	}


	fseek(fp, 0, FILE_END);
	fwrite(szBuf, 1, _tcslen(szBuf) * sizeof(TCHAR), fp);
	fflush(fp);
	//fclose(fp);
	//_tprintf(_T("write %s "), szBuf);
}

#define CURRENT_LOG_LEVEL         1

#define LOG_DEBUG         1
#define LOG_ERROR         2


void Log(int logLevel, TCHAR* format, ...)
{
	TCHAR   tszLogInfo[1024], szBuf[512];
	va_list arglist;


	szBuf[0] = 0;


	// 获取参数列表
	va_start(arglist, format);
	// 格式化缓冲区
	_vstprintf_s(szBuf, sizeof(szBuf), format, arglist);


	//if (CURRENT_LOG_LEVEL > logLevel)
	//{
	// return;
	//}


	if (LOG_DEBUG == logLevel)
	{
		_stprintf_s(tszLogInfo, sizeof(tszLogInfo), _T("debug : %s"), szBuf);
	}
	else
	{
		_stprintf_s(tszLogInfo, sizeof(tszLogInfo), _T("error : %s"), szBuf);
	}


	if (CURRENT_LOG_LEVEL <= logLevel)
	{
		_tprintf(tszLogInfo);
	}


	writefile(tszLogInfo);

}

获取桌面进程

BOOL GetExplorerProcessToken(DWORD* dwProcessId)
{
	HANDLE hThisProcess = NULL;
	PROCESSENTRY32 pe;
	BOOL  bMore;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);


	if (hSnapshot == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
	pe.dwSize = sizeof(PROCESSENTRY32);

	bMore = Process32First(hSnapshot, &pe);
	while (bMore)
	{
		if (0 == _tcsicmp(pe.szExeFile, _T("explorer.exe")))
		{
			hThisProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pe.th32ProcessID);
			*dwProcessId = pe.th32ProcessID;
			return true;
		}
		bMore = Process32Next(hSnapshot, &pe);
	}
	return false;
}


根据桌面进程创建新的用户进程

//ptszParameter的第一个字符要为空格,不然会报错,参数错误87

//注意ptszParameter的第一个字符要为空格

//ptszParameter的第一个字符要为空格

//重要的事情说三遍

BOOL RunProcess(const TCHAR* ptszProcessPath, const TCHAR* ptszParameter, LONG* plExitCode, BOOL bBlock)
{
	DWORD dwSessionId;
	DWORD dwProcessId;
	HANDLE hTokenThis = NULL;
	HANDLE hThisProcess = NULL;
	HANDLE hTokenDup = NULL;
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	DWORD dwCreationFlag = CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS;//NORMAL_PRIORITY_CLASS| CREATE_NEW_CONSOLE;
	LPVOID pEnv = NULL;
	TCHAR tszDeskTop[20];


	Log(LOG_DEBUG, _T("RunProcessAsUser %s %s \r\n"), ptszProcessPath, ptszParameter);


	if (!ptszProcessPath)
	{
		Log(LOG_ERROR, _T("RunProcess pwProcessPath is NULL\n"));
		return FALSE;
	}


	if (ptszProcessPath[0] == '\0')
	{
		return FALSE;
	}
	//if (!CheckFileIsExist(pwProcessPath))
	//{
	// return EXE_NOT_EXIT;
	//}
	//HANDLE hThisProcess = GetCurrentProcess();
	if (!GetExplorerProcessToken(&dwProcessId))//获取桌面进程的id。
	{
		Log(LOG_ERROR, _T("Get explorer.exe processId faild... \r\n"));
		return FALSE;
	}

	hThisProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessId);
	//获取桌面进程的回话id,不然在远程桌面的情况下,消息框显示不出来。
	ProcessIdToSessionId(dwProcessId, &dwSessionId);


	if (!hThisProcess)
	{
		Log(LOG_ERROR, _T("RunProcess GetProcessToken is NULL\n"));
		return FALSE;
	}

	OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);


	// 复制一个进程令牌,目的是为了修改session id属性,以便在其它session中创建进程
	if (!DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hTokenDup))
	{
		Log(LOG_ERROR, _T("RunProcess DuplicateTokenEx faild,error code is: %d\n"), GetLastError());
		return FALSE;
	}


	SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD)); // 把session id设置到备份的令牌中

	ZeroMemory(&si, sizeof(STARTUPINFO));
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    _tcscpy_s(tszDeskTop, sizeof(tszDeskTop) / sizeof(tszDeskTop[0]), _T("WinSta0\\Default"));

	si.cb = sizeof(STARTUPINFO);
	si.lpDesktop = tszDeskTop;
	si.wShowWindow = SW_SHOW;


	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

	CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE); // 创建环境块
	if (!CreateProcessAsUser(hTokenDup, ptszProcessPath, ptszParameter, NULL, NULL, FALSE, dwCreationFlag, pEnv, NULL, &si, &pi))
	{
		Log(LOG_ERROR, _T("CreateProcessAsUser faild, error code: %d\n"), GetLastError());
		return FALSE;
	}


	//bBlok表示是否 阻塞,也可以传入timeout=dwMilliseconds
	//if (dwMilliseconds > 0)
	//{
	// if (WaitForSingleObject(pi.hProcess, dwMilliseconds))
	// {
	// TerminateProcess(pi.hProcess, 0);
	// }
	//}


	if (bBlock)
	{
		WaitForSingleObject(pi.hProcess, INFINITE);
	}


	GetExitCodeProcess(pi.hProcess, (DWORD*)plExitCode);


	Log(LOG_DEBUG, _T("run %s %s return 0x%x\r\n"), ptszProcessPath, ptszParameter, *plExitCode);


	if (hTokenDup)
	{
		CloseHandle(hTokenDup);
	}
	if (hTokenThis)
	{
		CloseHandle(hTokenThis);
	}
	if (pi.hThread != INVALID_HANDLE_VALUE)
	{
		CloseHandle(pi.hThread);
	}
	if (pi.hProcess != INVALID_HANDLE_VALUE)
	{
		CloseHandle(pi.hProcess);
	}


	return TRUE;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值