// 突破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; }