系統權限服務創建桌面進程(進程也是系統權限)


系統權限服務,創建進程.

一丶簡介

為什么要創建系統權限服務.首先.強調權限一說. 我們創建的系統服務默認是系統權限的.然后系統權限(System)創建我們的進程.那么也是系統權限.我們的進程如果要注入到Explorer.exe中就很簡單了.

二丶創建服務的幾個步驟

1.編寫服務步驟

1.main函數中注冊服務的入口函數(servicemain)並開始派發
2.服務入口函數注冊服務控制函數.並且設置自己的服務狀態
3.服務控制函數回調的處理

1.1 main函數注冊服務入口函數

int main()
{
	/*

	定義服務列表結構體
	參數1.指定的服務名字.
	參數2.服務的入口Main函數地址.
	*/
	////安裝服務.
	
	    SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
		ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我們的服務名字
		ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服務的函數地址
		//LPSERVICE_MAIN_FUNCTIONW

		ServiceTable[1].lpServiceName = NULL;
		ServiceTable[1].lpServiceProc = NULL;
		StartServiceCtrlDispatcher(ServiceTable); //開始派發.
	
	return 0;
}

2.服務入口函數注冊服務控制函數.

服務入口服務控制回調函數,注冊到SCM(服務控制管理器)當中.
當我們服務控制管理器中點擊 啟動服務.關閉服務.暫停服務的時候.則會調用我們的回調函數.
代碼如下

VOID WINAPI SerMain(DWORD   dwNumServicesArgs,LPWSTR* lpServiceArgVectors)
{
	//在服務Main里面.我們需要注冊服務.
	/*
	RegisterServiceCtrlHandler 
	注冊一個函數來處理服務的請求控制.
	*/

	g_ServiceStatus.dwServiceType = SERVICE_WIN32;    //服務的類型是Win32服務
	g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ; //服務的狀態是正在巡行
	g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP ;// 服務接手的控制代碼喊處理函數中的處理. (Reg注冊的函數地址); 當前的意思就是這個服務可以停止.並且會傳入Reg注冊的ServiceHandle處理.
	g_ServiceStatus.dwWin32ExitCode = 0;  //服務用語報告啟動或停止時候發生的錯誤代碼.返回特定的錯誤代碼就設置.
	g_ServiceStatus.dwServiceSpecificExitCode = 0;//服務特定的錯誤代碼
	g_ServiceStatus.dwCheckPoint = 0;             //跟進度條一樣,服務在啟動的時候會遞增這個值
	g_ServiceStatus.dwWaitHint = 0;               //掛起啟動,停止,暫停.或繼續操作所需要的估計時間. 

	BOOL bRet = FALSE;
	g_RegRetServiceStatusHandle = RegisterServiceCtrlHandlerEx(TEXT(SERVICE_NAME), ServiceHandle,NULL);//返回服務狀態. 注冊服務控制函數
	if (g_RegRetServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
	{
		return;
	}
	//否則,調用SetServiceStatus進行更新服務的狀態信息 結構體是最新服務狀態結構信息.
	
	g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //Service Status Setting Start.
	 bRet = SetServiceStatus(g_RegRetServiceStatusHandle,&g_ServiceStatus);//設置服務的狀態.

	if (!bRet)
	{
		return ;
	}
	//編寫自己的代碼.
	g_ContrlCodeExcue = TRUE;
	
	
	
	RunRemoteControl();
	
	
	while (g_ContrlCodeExcue)
	{
		Sleep(2000);
	}
	return;
}

3.服務控制函數回調的處理


DWORD WINAPI ServiceHandle(DWORD    dwControl, DWORD    dwEventType, LPVOID   lpEventData, LPVOID   lpContext)
{
	//服務的控制狀態.管理
	switch (dwControl)
	{
		//回調函數會傳入dwControl讓我們控制服務.我們只需要控制即可.更改狀態並且設置即可.
	case SERVICE_CONTROL_PAUSE:
		//暫停
		g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
		break;
	case SERVICE_CONTROL_CONTINUE:
		g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;

		break;
	case SERVICE_CONTROL_STOP:
		g_ServiceStatus.dwWin32ExitCode = 0;
		g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
		g_ServiceStatus.dwCheckPoint = 0;
		g_ServiceStatus.dwWaitHint = 0;
		//SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
		g_ContrlCodeExcue = FALSE;
		break;
	case SERVICE_CONTROL_INTERROGATE:
		break;
	default:
		break;
	}
	SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
	return 0;
}

編寫完上面的幾步,我們的一個系統服務就能創建出來了.

4.服務控制的完整代碼


#pragma warning (disable:4996)
#include <userenv.h>
#include <Windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <string>
#include <vector>
using namespace std;

#pragma comment(lib,"Userenv.lib")
SERVICE_STATUS_HANDLE g_RegRetServiceStatusHandle;
SERVICE_STATUS        g_ServiceStatus; //服務的狀態
BOOL g_ContrlCodeExcue;   //控制我們的代碼是否執行


DWORD WINAPI ServiceHandle(DWORD    dwControl, DWORD    dwEventType, LPVOID   lpEventData, LPVOID   lpContext)
{
	//服務的控制狀態.管理
	switch (dwControl)
	{
		//回調函數會傳入dwControl讓我們控制服務.我們只需要控制即可.更改狀態並且設置即可.
	case SERVICE_CONTROL_PAUSE:
		//暫停
		g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
		break;
	case SERVICE_CONTROL_CONTINUE:
		g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;

		break;
	case SERVICE_CONTROL_STOP:
		g_ServiceStatus.dwWin32ExitCode = 0;
		g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
		g_ServiceStatus.dwCheckPoint = 0;
		g_ServiceStatus.dwWaitHint = 0;
		//SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
		g_ContrlCodeExcue = FALSE;
		break;
	case SERVICE_CONTROL_INTERROGATE:
		break;
	default:
		break;
	}
	SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
	return 0;
}





VOID WINAPI SerMain(DWORD   dwNumServicesArgs,LPWSTR* lpServiceArgVectors)
{
	//在服務Main里面.我們需要注冊服務.
	/*
	RegisterServiceCtrlHandler 
	注冊一個函數來處理服務的請求控制.
	*/

	g_ServiceStatus.dwServiceType = SERVICE_WIN32;    //服務的類型是Win32服務
	g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ; //服務的狀態是正在巡行
	g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP ;// 服務接手的控制代碼喊處理函數中的處理. (Reg注冊的函數地址); 當前的意思就是這個服務可以停止.並且會傳入Reg注冊的ServiceHandle處理.
	g_ServiceStatus.dwWin32ExitCode = 0;  //服務用語報告啟動或停止時候發生的錯誤代碼.返回特定的錯誤代碼就設置.
	g_ServiceStatus.dwServiceSpecificExitCode = 0;//服務特定的錯誤代碼
	g_ServiceStatus.dwCheckPoint = 0;             //跟進度條一樣,服務在啟動的時候會遞增這個值
	g_ServiceStatus.dwWaitHint = 0;               //掛起啟動,停止,暫停.或繼續操作所需要的估計時間. 

	BOOL bRet = FALSE;
	g_RegRetServiceStatusHandle = RegisterServiceCtrlHandlerEx(TEXT(SERVICE_NAME), ServiceHandle,NULL);//返回服務狀態.
	if (g_RegRetServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
	{
		return;
	}
	//否則,調用SetServiceStatus進行更新服務的狀態信息 結構體是最新服務狀態結構信息.
	
	g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //Service Status Setting Start.
	 bRet = SetServiceStatus(g_RegRetServiceStatusHandle,&g_ServiceStatus);

	if (!bRet)
	{
		return ;
	}
	//編寫自己的代碼.
	g_ContrlCodeExcue = TRUE;
	
	
	
	
	
	
	while (g_ContrlCodeExcue)
	{
		Sleep(2000); //寫你自己的代碼
	}
	return;
}

int main()
{
	/*

	定義服務列表結構體
	參數1.指定的服務名字.
	參數2.服務的入后Main函數地址.
	*/
	////安裝服務.

	//SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
	//ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我們的服務名字
	//ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服務的函數地址
	////LPSERVICE_MAIN_FUNCTIONW

	//ServiceTable[1].lpServiceName = NULL;
	//ServiceTable[1].lpServiceProc = NULL;
	//StartServiceCtrlDispatcher(ServiceTable); //開始派發.

	
		 SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
		ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我們的服務名字
		ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服務的函數地址
		//LPSERVICE_MAIN_FUNCTIONW

		ServiceTable[1].lpServiceName = NULL;
		ServiceTable[1].lpServiceProc = NULL;
		StartServiceCtrlDispatcher(ServiceTable); //開始派發.
	

	return 0;
}

三丶服務中創建桌面進程

3.1服務中創建桌面進程原理

在服務中雖然說創建的進程是System權限.但是在win7系統以上,我們創建的進程都會是隱藏的.也就是說你的進程雖然創建出來了.
也是Sysem權限.但是並不能操作.僅僅就只能在管理器看到這個進程而已.
ps:(winxp下沒有嘗試是否能創建進程)
所以我們有了新的方法.不調用CreateProcess函數.而調用 CreateProcessAsUser函數.
並且進行一定的設置才可以.

核心代碼如下:

void RunRemoteControl() //在服務中創建桌面進程.
{
	HANDLE ProcessHandle = NULL;
	HANDLE CurrentToken = NULL;
	HANDLE TokenDup = NULL;
	wstring wOpenProcessName;
	if (!GetAppendNmae(wOpenProcessName, PROCESS_NAME))
	{
		int d = GetLastError();
		WriteLogString(L"RunRemoteControl OpenProcessToken failed.Last Error is:%d", d);
		return ;
	}
	ProcessHandle = GetCurrentProcess();
	if (!OpenProcessToken(ProcessHandle, TOKEN_ALL_ACCESS, &CurrentToken))
	{
		int d = GetLastError();
		WriteLogString(L"RunRemoteControl OpenProcessToken failed.Last Error is:%d", d);
		return;
	}
	if (!DuplicateTokenEx(CurrentToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &TokenDup))
	{
		int dd = GetLastError();
		WriteLogString(L"RunRemoteControl DuplicateTokenEx failed.Last error is:%d", dd);
		return;
	}
	DWORD dwSessionID = WTSGetActiveConsoleSessionId();
	WriteLogString(L" WTSGetActiveConsoleSessionId:%d", dwSessionID);
	if (!SetTokenInformation(TokenDup, TokenSessionId, &dwSessionID, sizeof(DWORD)))
	{
		int ddd = GetLastError();
		WriteLogString(L"RunRemoteControl SetTokenInformation failed.Last error is:%d", ddd);
		return;
	}
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(STARTUPINFO));
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
	si.cb = sizeof(STARTUPINFO);
	si.lpDesktop = L"WinSta0\\Default";

	LPVOID pEnv = NULL;
	DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
	if (!CreateEnvironmentBlock(&pEnv, TokenDup, FALSE))
	{
		int error1 = GetLastError();
		WriteLogString(L"RunRemoteControl CreateEnvironmentBlock failed.Last error is:%d", error1);
		return;
	}
	TCHAR szPath[1024] =  TEXT_CREATE_PROCESS_NAME_SY;
	//wcsncpy_s(szPath, wOpenProcessName.c_str(), wOpenProcessName.length());
	OutputDebugString(szPath);
	if (!CreateProcessAsUser(TokenDup, szPath, NULL, NULL, NULL, FALSE, dwCreationFlags, pEnv, NULL, &si, &pi))
	{
		int error2 = GetLastError();
		WriteLogString(L"RunRemoteControl CreateProcessAsUser failed.Last error is:%d", error2);
		return;
	}

	return	;
}

其中函數 GetAppendNmae WriteLogString 函數是我自己寫的.不影響這個核心函數.可以去掉的.
最后就可以創建我們的進程.

3.2服務中創建桌面進程完整代碼

完整代碼如下:





#pragma warning (disable:4996)
#include <userenv.h>
#include <Windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <string>
#include <vector>
using namespace std;

#pragma comment(lib,"Userenv.lib")
SERVICE_STATUS_HANDLE g_RegRetServiceStatusHandle;
SERVICE_STATUS        g_ServiceStatus; //服務的狀態
BOOL g_ContrlCodeExcue;   //控制我們的代碼是否執行
#define SERVICE_NAME "SystemServices"
#define LOAG_FILE_NAME "SystemServicesLog.txt"
#define TEXT_CREATE_PROCESS_NAME_OD TEXT("D:\\HackTools\\OllyDbg\\OllyICE 吾愛扣扣專版\\OllyICE 吾愛扣扣專版\\OllyICE.exe")//SystemRun.exe
#define TEXT_CREATE_PROCESS_NAME_SY TEXT("C:\\Users\\Administrator\\Desktop\\SystemServices\\run\\x64InjectProcess.exe")
#define PROCESS_NAME TEXT("SystemRun.exe")

BOOL GetAppendNmae(wstring &wGetName, wstring AppendName); //Get Moudle Name Last - 1 Path Cat In Path
//服務控制函數

DWORD WINAPI ServiceHandle(DWORD    dwControl, DWORD    dwEventType, LPVOID   lpEventData, LPVOID   lpContext)
{
	//服務的控制狀態.管理
	switch (dwControl)
	{
		//回調函數會傳入dwControl讓我們控制服務.我們只需要控制即可.更改狀態並且設置即可.
	case SERVICE_CONTROL_PAUSE:
		//暫停
		g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
		break;
	case SERVICE_CONTROL_CONTINUE:
		g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;

		break;
	case SERVICE_CONTROL_STOP:
		g_ServiceStatus.dwWin32ExitCode = 0;
		g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
		g_ServiceStatus.dwCheckPoint = 0;
		g_ServiceStatus.dwWaitHint = 0;
		//SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
		g_ContrlCodeExcue = FALSE;
		break;
	case SERVICE_CONTROL_INTERROGATE:
		break;
	default:
		break;
	}
	SetServiceStatus(g_RegRetServiceStatusHandle, &g_ServiceStatus);
	return 0;
}

BOOL GetEachLevelDir(PWSTR GetPathName, vector<wstring> &wSavePath) //傳入一個路徑,獲取每一級的目錄.並且用數組進行存儲.
{
	TCHAR *pCurPoint = GetPathName;//使用指針遍歷

	TCHAR  *Begin = GetPathName;
	DWORD dwEnd = 0;
	DWORD dwCount = 0;
	wstring wstrTemp = TEXT("");
	while (pCurPoint)
	{

		//否則進行循環
		//wcscmp((TCHAR *)*pCurPoint,TEXT("\\")) == 0
		if (*pCurPoint == TEXT('\\'))//以反斜杠為分割.
		{

			wSavePath.push_back(wstrTemp);
			wstrTemp.clear();
			pCurPoint++; //控制指針去相加.
			dwEnd = 0;

		}

		if (*pCurPoint == 0x0)//結尾是0則跳出循環.記錄下路徑.
		{
			return TRUE;
			break;
		}
		wstring::iterator it = wstrTemp.begin() + dwEnd;
		wstrTemp.insert(it, *pCurPoint);  //插入字符
		dwEnd++;
		pCurPoint++;
		dwCount++; //獲取判斷長度進行退出.
	}
	return FALSE;
}

BOOL   GetTokenByName(HANDLE   &hToken, LPWSTR   lpName)
{
	if (!lpName)
	{
		return   FALSE;
	}
	HANDLE                   hProcessSnap = NULL;
	BOOL                       bRet = FALSE;
	PROCESSENTRY32   pe32 = { 0 };

	hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE)
		return   (FALSE);

	pe32.dwSize = sizeof(PROCESSENTRY32);

	if (Process32First(hProcessSnap, &pe32))
	{
		do
		{
			if (!wcscmp(_wcsupr(pe32.szExeFile), _wcsupr(lpName)))
			{
				HANDLE   hProcess =
					OpenProcess(PROCESS_QUERY_INFORMATION,
					FALSE, pe32.th32ProcessID);
				bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken);
				CloseHandle(hProcessSnap);
				return   (bRet);
			}
		} while (Process32Next(hProcessSnap, &pe32));
		bRet = TRUE;
	}
	else
		bRet = FALSE;

	CloseHandle(hProcessSnap);
	return   (bRet);
}

//也可以創建進程,但是創建出來的是根據你得當前EXPLORER的權限創建的。 創建出來是管理員權限。
BOOL   RunProcess(LPWSTR   lpImage)
{
	if (!lpImage)
	{
		return   FALSE;
	}
	HANDLE   hToken;
	//TEXT("EXPLORER.EXE")
	if (!GetTokenByName(hToken, TEXT("EXPLORER.EXE")))
	{
		return   FALSE;
	}
	STARTUPINFO   si;
	PROCESS_INFORMATION   pi;

	ZeroMemory(&si, sizeof(STARTUPINFO));
	si.cb = sizeof(STARTUPINFO);
	si.lpDesktop = TEXT("winsta0\\default");

	BOOL   bResult =
		CreateProcessAsUser(hToken, lpImage, NULL, NULL, NULL,
		FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
	CloseHandle(hToken);
	if (bResult)
	{
		OutputDebugString(TEXT("CreateProcessAsUser   ok!\r\n"));
	}
	else
	{
		OutputDebugString(TEXT("CreateProcessAsUser   false!\r\n"));
	}
	return   bResult;
} 

BOOL GetAppendNmae(wstring &wGetName, wstring AppendName)//獲取啟動進程的啟動的名字
{

	TCHAR FilePath[MAX_PATH] = { 0 };
	GetModuleFileName(GetModuleHandle(0), FilePath, MAX_PATH);
	vector<wstring> wSaveDirLeavePath;
	if (!GetEachLevelDir(FilePath, wSaveDirLeavePath))
	{
		return FALSE;
	}
	//cat 
	wstring wCatPath = TEXT("");
	for (int i = 0; i < wSaveDirLeavePath.size(); i++)
	{
		if (i == (wSaveDirLeavePath.size() - 1))
		{
			break;
		}
		wCatPath.append(wSaveDirLeavePath[i]);
		wCatPath.append(TEXT("\\"));
	}
	wCatPath.append(AppendName);
	wGetName = wCatPath;

	return TRUE;
}

void WriteLogString(LPWSTR lpParam, DWORD dwCode)
{
	TCHAR lpBuffer[1024]  {0};
	wsprintf(lpBuffer,lpParam, dwCode);
	OutputDebugString(lpBuffer);
	//GetCurrentDirectory(1024, lpBuffer);
	wstring WriteLogName;
	if (!GetAppendNmae(WriteLogName, TEXT(LOAG_FILE_NAME)))
	{
		return;
	}
	FILE *pFile = NULL;
	_wfopen_s(&pFile, WriteLogName.c_str(), TEXT("a+"));
	if (NULL == pFile)
	{
		return;
	}
	fwprintf_s(pFile, lpParam); //寫入到文件
	fclose(pFile);
	return;
}

void RunRemoteControl() //在服務中創建桌面進程.
{
	HANDLE ProcessHandle = NULL;
	HANDLE CurrentToken = NULL;
	HANDLE TokenDup = NULL;
	wstring wOpenProcessName;
	if (!GetAppendNmae(wOpenProcessName, PROCESS_NAME))
	{
		int d = GetLastError();
		WriteLogString(L"RunRemoteControl OpenProcessToken failed.Last Error is:%d", d);
		return ;
	}
	ProcessHandle = GetCurrentProcess();
	if (!OpenProcessToken(ProcessHandle, TOKEN_ALL_ACCESS, &CurrentToken))
	{
		int d = GetLastError();
		WriteLogString(L"RunRemoteControl OpenProcessToken failed.Last Error is:%d", d);
		return;
	}
	if (!DuplicateTokenEx(CurrentToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &TokenDup))
	{
		int dd = GetLastError();
		WriteLogString(L"RunRemoteControl DuplicateTokenEx failed.Last error is:%d", dd);
		return;
	}
	DWORD dwSessionID = WTSGetActiveConsoleSessionId();
	WriteLogString(L" WTSGetActiveConsoleSessionId:%d", dwSessionID);
	if (!SetTokenInformation(TokenDup, TokenSessionId, &dwSessionID, sizeof(DWORD)))
	{
		int ddd = GetLastError();
		WriteLogString(L"RunRemoteControl SetTokenInformation failed.Last error is:%d", ddd);
		return;
	}
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(STARTUPINFO));
	ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
	si.cb = sizeof(STARTUPINFO);
	si.lpDesktop = L"WinSta0\\Default";

	LPVOID pEnv = NULL;
	DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
	if (!CreateEnvironmentBlock(&pEnv, TokenDup, FALSE))
	{
		int error1 = GetLastError();
		WriteLogString(L"RunRemoteControl CreateEnvironmentBlock failed.Last error is:%d", error1);
		return;
	}
	TCHAR szPath[1024] =  TEXT_CREATE_PROCESS_NAME_SY;
	//wcsncpy_s(szPath, wOpenProcessName.c_str(), wOpenProcessName.length());
	OutputDebugString(szPath);
	if (!CreateProcessAsUser(TokenDup, szPath, NULL, NULL, NULL, FALSE, dwCreationFlags, pEnv, NULL, &si, &pi))
	{
		int error2 = GetLastError();
		WriteLogString(L"RunRemoteControl CreateProcessAsUser failed.Last error is:%d", error2);
		return;
	}

	return	;
}

VOID WINAPI SerMain(DWORD   dwNumServicesArgs,LPWSTR* lpServiceArgVectors)
{
	//在服務Main里面.我們需要注冊服務.
	/*
	RegisterServiceCtrlHandler 
	注冊一個函數來處理服務的請求控制.
	*/

	g_ServiceStatus.dwServiceType = SERVICE_WIN32;    //服務的類型是Win32服務
	g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ; //服務的狀態是正在巡行
	g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP ;// 服務接手的控制代碼喊處理函數中的處理. (Reg注冊的函數地址); 當前的意思就是這個服務可以停止.並且會傳入Reg注冊的ServiceHandle處理.
	g_ServiceStatus.dwWin32ExitCode = 0;  //服務用語報告啟動或停止時候發生的錯誤代碼.返回特定的錯誤代碼就設置.
	g_ServiceStatus.dwServiceSpecificExitCode = 0;//服務特定的錯誤代碼
	g_ServiceStatus.dwCheckPoint = 0;             //跟進度條一樣,服務在啟動的時候會遞增這個值
	g_ServiceStatus.dwWaitHint = 0;               //掛起啟動,停止,暫停.或繼續操作所需要的估計時間. 

	BOOL bRet = FALSE;
	g_RegRetServiceStatusHandle = RegisterServiceCtrlHandlerEx(TEXT(SERVICE_NAME), ServiceHandle,NULL);//返回服務狀態.
	if (g_RegRetServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
	{
		return;
	}
	//否則,調用SetServiceStatus進行更新服務的狀態信息 結構體是最新服務狀態結構信息.
	
	g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //Service Status Setting Start.
	 bRet = SetServiceStatus(g_RegRetServiceStatusHandle,&g_ServiceStatus);

	if (!bRet)
	{
		return ;
	}
	//編寫自己的代碼.
	g_ContrlCodeExcue = TRUE;
	
	
	
	RunRemoteControl();
	
	
	while (g_ContrlCodeExcue)
	{
		Sleep(2000);
	}
	return;
}

int main()
{
	/*

	定義服務列表結構體
	參數1.指定的服務名字.
	參數2.服務的入后Main函數地址.
	*/
	////安裝服務.

	//SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
	//ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我們的服務名字
	//ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服務的函數地址
	////LPSERVICE_MAIN_FUNCTIONW

	//ServiceTable[1].lpServiceName = NULL;
	//ServiceTable[1].lpServiceProc = NULL;
	//StartServiceCtrlDispatcher(ServiceTable); //開始派發.

	
		 SERVICE_TABLE_ENTRY ServiceTable[2] = { NULL };
		ServiceTable[0].lpServiceName = (LPWSTR)TEXT(SERVICE_NAME); //指定我們的服務名字
		ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)SerMain;//指向服務的函數地址
		//LPSERVICE_MAIN_FUNCTIONW

		ServiceTable[1].lpServiceName = NULL;
		ServiceTable[1].lpServiceProc = NULL;
		StartServiceCtrlDispatcher(ServiceTable); //開始派發.
	

	return 0;
}



4.總結

代碼沒有進行完善,比如服務中創建的進程是寫死的.這個我沒有做.因為時間有限.只為了測試代碼.
其實不難.有興趣的可以自己做一下.
最后附上完整代碼:

鏈接:https://pan.baidu.com/s/1Yn0zHfHi9ZBfiNKkCNdMpA ")
提取碼:iius


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM