zoukankan      html  css  js  c++  java
  • 调试

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

      

  • 相关阅读:
    使用批处理脚本在win10系统启动Redis 5.0.10
    异常分析 JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    Spring Boot基于redis分布式锁模拟直播秒杀场景
    管理的经验二
    第三方api接口
    接口测试总结
    测试框架的基本能力
    接口测试的价值
    面试的经验
    管理的经验
  • 原文地址:https://www.cnblogs.com/yakoazz/p/14065950.html
Copyright © 2011-2022 走看看