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

      

  • 相关阅读:
    斐波那契数列 的两种实现方式(Java)
    单链表反转
    单链表合并
    两个有序list合并
    list去重 转载
    RemoveAll 要重写equals方法
    Java for LeetCode 138 Copy List with Random Pointer
    Java for LeetCode 137 Single Number II
    Java for LeetCode 136 Single Number
    Java for LeetCode 135 Candy
  • 原文地址:https://www.cnblogs.com/yakoazz/p/14065950.html
Copyright © 2011-2022 走看看