// 突破SESSION 0隔离创建用户进程
BOOL CreateUserProcess(char *lpszFileName)
{
BOOL bRet = TRUE;
DWORD dwSessionID = 0;
HANDLE hToken = NULL;
HANDLE hDuplicatedToken = NULL;
LPVOID lpEnvironment = NULL;
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(si);
do
{
// 获得当前Session ID
dwSessionID = ::WTSGetActiveConsoleSessionId();
// 获得当前Session的用户令牌
if (FALSE == ::WTSQueryUserToken(dwSessionID, &hToken))
{
ShowMessage("WTSQueryUserToken", "ERROR");
bRet = FALSE;
break;
}
// 复制令牌
if (FALSE == ::DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityIdentification, TokenPrimary, &hDuplicatedToken))
{
ShowMessage("DuplicateTokenEx", "ERROR");
bRet = FALSE;
break;
}
// 创建用户Session环境
if (FALSE == ::CreateEnvironmentBlock(&lpEnvironment,
hDuplicatedToken, FALSE))
{
ShowMessage("CreateEnvironmentBlock", "ERROR");
bRet = FALSE;
break;
}
// 在复制的用户Session下执行应用程序,创建进程
if (FALSE == ::CreateProcessAsUser(hDuplicatedToken,
lpszFileName, NULL, NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
lpEnvironment, NULL, &si, &pi))
{
ShowMessage("CreateProcessAsUser", "ERROR");
bRet = FALSE;
break;
}
} while (FALSE);
// 关闭句柄, 释放资源
if (lpEnvironment)
{
::DestroyEnvironmentBlock(lpEnvironment);
}
if (hDuplicatedToken)
{
::CloseHandle(hDuplicatedToken);
}
if (hToken)
{
::CloseHandle(hToken);
}
return bRet;
}
void ShowMessage(TCHAR *lpszMessage, TCHAR *lpszTitle)
{
// 获取当前的Session ID
DWORD dwSessionId = ::WTSGetActiveConsoleSessionId();
// 显示消息对话框
DWORD dwResponse = 0;
::WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, dwSessionId,
lpszTitle, (1 + ::lstrlen(lpszTitle)),
lpszMessage, (1 + ::lstrlen(lpszMessage)),
0, 0, &dwResponse, FALSE);
}
#include <stdio.h>
#include <windows.h>
#include <iostream>
using namespace std;
wchar_t serviceName[20] = L"qwer1234";
wchar_t serviceDescribe[50] = L"this is a describe";
wstring getExeFullFilename()
{
static wchar_t buffer[1024];
GetModuleFileNameW(NULL, buffer, 1024);
return wstring(buffer);
}
SERVICE_STATUS serviceStatus = { 0 };
SERVICE_STATUS_HANDLE g_serviceStatusHandle = NULL;
//首先声明一个句柄,后面操作这个服务全靠这个句柄
#define SAFE_CALL(FuncCall, ErrorCode)
if (FuncCall == ErrorCode) {
cout << #FuncCall " error, code:" << GetLastError()
<< " ,line:" << __LINE__ << "
";
exit(-1);
}
void setServiceStatus(DWORD status)
{
SERVICE_STATUS serviceStatus;
serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwWin32ExitCode = NO_ERROR;
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwWaitHint = 2000;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN |
SERVICE_ACCEPT_STOP;
serviceStatus.dwCurrentState = status;
SAFE_CALL(SetServiceStatus(g_serviceStatusHandle, &serviceStatus), 0);
}
//名字自己定义,用来操作服务的状态,参数是服务的状态
void __stdcall ServiceHandler(DWORD ServiceStatusCode) {
switch (ServiceStatusCode) {
case SERVICE_CONTROL_CONTINUE:
/*
//第一种方式,我觉得可以
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwWin32ExitCode = -1; 这个看情况吧,我觉得多余了。
SetServiceStatus(g_serviceStatusHandle, &ServiceStatus);*/
setServiceStatus(SERVICE_START_PENDING); //另一种方式,我觉得挺好
//下面不赘述,自我发挥一下
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_PAUSE:
setServiceStatus(SERVICE_PAUSED); break;
case SERVICE_CONTROL_SHUTDOWN:
setServiceStatus(SERVICE_STOPPED); break;
case SERVICE_CONTROL_STOP:
setServiceStatus(SERVICE_STOPPED); break;
default:
break;
}
}
void Init() {
//初始化所有的状态
//初始话服务为的状态
serviceStatus.dwServiceType = SERVICE_WIN32;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;//设置控制方式
serviceStatus.dwWin32ExitCode = 0; //设置推出代码
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwCheckPoint = 0;
}
void __stdcall ServiceMain(DWORD argc, LPWSTR* argv) {
// 注册服务控制器,为了控制服务的状态等 SCM第一个参数是服务的名字,第二个参数是回调函数
g_serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, &ServiceHandler);
if (g_serviceStatusHandle == 0)
{
cout << "RegisterServiceCtrlHandlerW error, code:" << GetLastError()
<< " ,line:" << __LINE__ << "
";
exit(-1);
}
//先pending,再running,只是改变状态而已,其实初始话已经pending
//为了稳妥起见再pending一次
setServiceStatus(SERVICE_START_PENDING);//表示正在初始化
setServiceStatus(SERVICE_RUNNING);
}
/*==================分割线======================*/
/*
上面是服务的部分
下面是注册等等的部分
*/
void runService()
{
const SERVICE_TABLE_ENTRYW serviceTable[] = {
{ L"", ServiceMain },
{ NULL, NULL }
};
//注册服务入口函数
SAFE_CALL(StartServiceCtrlDispatcherW(&serviceTable[0]), 0);
}
void installService() {
//注册一个服务
//函数建立了一个到服务控制管理器的连接,并打开指定的数据库。
SC_HANDLE scHandle = OpenSCManagerW(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
SAFE_CALL(scHandle, NULL);
//创建一个服务对象,并将其添加到指定的服务控制管理器数据库的函数
SC_HANDLE serviceHandle = CreateServiceW(
scHandle,
serviceName,//以NULL 结尾的服务名,用于创建登记数据库中的关键字
serviceName,//以NULL 结尾的服务名,用于用户界面标识服务
SERVICE_ALL_ACCESS,//指定服务返回类型
SERVICE_WIN32_OWN_PROCESS,//指定服务类型
SERVICE_AUTO_START,//指定何时启动服务
SERVICE_ERROR_NORMAL,//指定服务启动失败的严重程度
getExeFullFilename().c_str(),//指定服务程序二进制文件的路径
NULL,//指定顺序装入的服务组名
NULL,//忽略,NULL
L"", //指定启动该服务前必须先启动的服务或服务组
NULL,//以NULL 结尾的字符串,指定服务帐号。如是NULL,则表示使用LocalSystem帐号
L""//以NULL 结尾的字符串,指定对应的口令。为NULL表示无口令。但使用LocalSystem时填NULL
);
SAFE_CALL(serviceHandle, NULL);
CloseServiceHandle(scHandle);
CloseServiceHandle(serviceHandle);
}
void startService() {
SC_HANDLE scHandle = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
SAFE_CALL(scHandle, NULL);
SC_HANDLE serviceHandle = OpenServiceW(scHandle, serviceName, SERVICE_ALL_ACCESS);
SAFE_CALL(serviceHandle, NULL);
SERVICE_STATUS serviceStatus;
SAFE_CALL(QueryServiceStatus(serviceHandle, &serviceStatus), 0);
if (serviceStatus.dwCurrentState == SERVICE_START && serviceStatus.dwCurrentState != SERVICE_START_PENDING) {
//为啥判断两个
return;
}
SAFE_CALL(StartServiceW(serviceHandle, 0, NULL), FALSE);
CloseServiceHandle(scHandle);
CloseServiceHandle(serviceHandle);
}
void uninstallService() {
SC_HANDLE scHandle = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
SAFE_CALL(scHandle, NULL);
SC_HANDLE serviceHandle = OpenServiceW(scHandle, serviceName, SERVICE_ALL_ACCESS);
SAFE_CALL(serviceHandle, NULL);
SERVICE_STATUS serviceStatus;
SAFE_CALL(QueryServiceStatus(serviceHandle, &serviceStatus), 0);
//查询状态,直到真正关闭
if (serviceStatus.dwCurrentState == SERVICE_RUNNING) {
SAFE_CALL(ControlService(serviceHandle, SERVICE_CONTROL_STOP, &serviceStatus), 0);
SAFE_CALL(serviceStatus.dwCurrentState, NO_ERROR);
do {
SAFE_CALL(QueryServiceStatus(serviceHandle, &serviceStatus), 0);
Sleep(0);
} while (serviceStatus.dwCurrentState != SERVICE_STOPPED);
}
SAFE_CALL(DeleteService(serviceHandle), FALSE);
CloseServiceHandle(scHandle);
CloseServiceHandle(serviceHandle);
}
int wmain(int argc, wchar_t* argv[])
{
if (argc == 1) {
runService();
}
else if (argc == 2) {
if (argv[1] == wstring(L"-install")) {
installService();
startService();
}
if (argv[1] == wstring(L"-uninstall")) {
uninstallService();
}
}
else {
std::cout << "usage: a.exe [-install/-uninstall]";
}
return 0;
}