本程序主要实现功能是通过服务开启一个界面程序和执行一些cmd命令
第一步:创建一个ATL project,选择Service(exe),创建好后我个人添加的类的声明和定义都在一个cpp里,所以下面直接上cpp代码
// ATLdemo.cpp : Implementation of WinMain
#include "stdafx.h"
#include "resource.h"
#include "ATLdemo_i.h"
#include
#include
#pragma comment(lib, "userenv.lib")
#include//win32 api
#pragma comment(lib, "WtsApi32.lib")
#include
#include //shellsexcute
#pragma comment(lib, "shell32.lib")
#include "atlbase.h"
#include "fstream"
#include "iostream"
using namespace ATL;
class CATLdemoModule : public ATL::CAtlServiceModuleT< CATLdemoModule, IDS_SERVICENAME >
{
public :
DECLARE_LIBID(LIBID_ATLdemoLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_ATLDEMO, "{BA3C0E26-048E-464F-86FB-133DF8638B79}")
HRESULT InitializeSecurity() throw()
{
// TODO : Call CoInitializeSecurity and provide the appropriate security settings for your service
// Suggested - PKT Level Authentication,
// Impersonation Level of RPC_C_IMP_LEVEL_IDENTIFY
// and an appropiate Non NULL Security Descriptor.
return S_OK;
}
void OnPause() throw(); //暂停
void OnStop() throw();//停止
void Handler(DWORD dwOpcode) throw();//处理不同的服务控制消息
void OnContinue() throw();//继续运行
HRESULT PreMessageLoop(int nShowCmd) throw();//消息响应
bool QuerySerStatu();//查询服务状态
void CreateCmd();
inline HRESULT RegisterAppId(_In_ bool bService = false) throw()//为了运行重写的 install
{
if (!Uninstall())
return E_FAIL;
CATLdemoModule::UpdateRegistryAppId(TRUE);
CRegKey keyAppID;
keyAppID.Open(HKEY_CLASSES_ROOT, _T("AppID"), KEY_WRITE);
CRegKey key;
key.Create(keyAppID, CATLdemoModule::GetAppIdT());
key.DeleteValue(_T("LocalService"));
key.SetStringValue(_T("LocalService"), m_szServiceName);
// Create service
if (!Install())
return E_FAIL;
return S_OK;
}
bool LaunchSession1Process( LPTSTR lpCommand );
void RunMessageLoop() throw();
HRESULT Run(int nShowCmd = SW_HIDE) throw();//重写run
BOOL Install() throw();//为了重写createservice
bool ParseCommandLine(
_In_z_ LPCTSTR lpCmdLine,
_Out_ HRESULT* pnRetCode) throw();
private:
WCHAR lpszClientPath[MAX_PATH];//当前服务路径
_TCHAR dependServices[256];//依赖项
DWORD size;
DWORD dwStartType;
//int Get_Time();
int Share_Memory();
bool Count_Time();
typedef struct _Date
{
int i_year;
int i_month;
int i_day;
}Date;
Date Initia_time;
Date Pay_time;
static int YearCalcArray[20] ;
static int MonthCalcArray[12] ;
};
int YearCalcArray[4] = {365, 365, 365, 366};
int MonthCalcArray[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30,31,30,31};
CATLdemoModule _AtlModule;
//
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpCmdLine*/, int nShowCmd)
{
_AtlModule.WinMain(nShowCmd);
}
void CATLdemoModule::RunMessageLoop()throw()
{
//to do something
MSG msg;
if(LaunchSession1Process(L"ll"))
LogEvent(L"交互成功");
//Share_Memory();
CreateCmd();
if(!QuerySerStatu())
LogEvent(L"查询状态失败");
while (GetMessage(&msg, 0, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
bool CATLdemoModule::LaunchSession1Process( LPTSTR lpCommand)
{
BOOL bSuccess = FALSE;
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si);
DWORD dwSessionID = WTSGetActiveConsoleSessionId();
HANDLE hToken = NULL;
if (WTSQueryUserToken(dwSessionID, &hToken) == FALSE)
{
LogEvent(L"读取当前登录用户的令牌信息失败");
}
HANDLE hDuplicatedToken = NULL;
if (DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hDuplicatedToken) == FALSE)
{
LogEvent(L"复制当前登录用户的令牌信息失败");
}
LPVOID lpEnvironment = NULL;
if (CreateEnvironmentBlock(&lpEnvironment, hDuplicatedToken, FALSE) == FALSE)
{
LogEvent(L"创造环境失败");
}
if (GetModuleFileName(NULL, lpszClientPath, MAX_PATH) == 0)
{
LogEvent(L"获取当前进程已加载模块的文件的完整路径失败");
}
PathRemoveFileSpec(lpszClientPath);//删除最后文件名
WCHAR *path=(L"C:\\windows\\system32\\cmd.exe");
//执行cmd命令
if (CreateProcessAsUser(hDuplicatedToken,path, NULL, NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
lpEnvironment, NULL, &si, &pi) == FALSE)
{
DWORD a=GetLastError();
TCHAR str[100];
wsprintf(str,L"%u",a);
LogEvent((LPCTSTR)str);
LogEvent(L"创建新进程失败");
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
bSuccess = TRUE;
return bSuccess;
}
bool CATLdemoModule::ParseCommandLine(
_In_z_ LPCTSTR lpCmdLine,
_Out_ HRESULT* pnRetCode) throw()
{
if (!CAtlExeModuleT::ParseCommandLine(lpCmdLine, pnRetCode))
return false;
TCHAR szTokens[] = _T("-/");
*pnRetCode = S_OK;
CATLdemoModule* pT = static_cast(this);
LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
while (lpszToken != NULL)
{
if (WordCmpI(lpszToken, _T("Service"))==0)
{
*pnRetCode = this->RegisterAppId(true);
if (SUCCEEDED(*pnRetCode))
{
*pnRetCode = this->RegisterServer(TRUE);
}
return false;
}
lpszToken = FindOneOf(lpszToken, szTokens);
}
return true;
}
HRESULT CATLdemoModule::Run(int nShowCmd) throw()
{
HRESULT hr = S_OK;
CATLdemoModule *pT = this;
hr = pT->PreMessageLoop(nShowCmd);
// Call RunMessageLoop only if PreMessageLoop returns S_OK.
if (GetModuleFileName(NULL, lpszClientPath, MAX_PATH) == 0)
{
LogEvent(L"获取当前进程已加载模块的文件的完整路径失败");
}
PathRemoveFileSpec(lpszClientPath);//删除最后文件名
wcscat_s(lpszClientPath, sizeof(lpszClientPath)/sizeof(WCHAR), L"time_rec.txt");
//SYSTEMTIME sys;//获取系统时间
fstream file;
file.open();
//while(1){
//GetLocalTime( &sys );
//int Time_Year=sys.wYear;
//int Time_second=sys.wSecond;
//int Time_Minute=sys.wMinute;
//wchar_t ch[20];
_stprintf_s(ch,"%d",Time_Minute);
//_itow_s(Time_second, ch, 20, 10);
//LPWSTR tittle=L"hello";
//DWORD resp;
//WTSSendMessage(
// WTS_CURRENT_SERVER_HANDLE,
// WTSGetActiveConsoleSessionId(),
// tittle,5,
// ch,20,
// 0, 0, &resp,false);
//Sleep(5000);
//}
if (hr == S_OK)
{
pT->RunMessageLoop();
}
// Call PostMessageLoop if PreMessageLoop returns success.
if (SUCCEEDED(hr))
{
hr = pT->PostMessageLoop();
}
ATLASSERT(SUCCEEDED(hr));
return hr;
}
HRESULT CATLdemoModule::PreMessageLoop( int nShowCmd ) throw()
{
//让服务允许暂停和继续操作
m_status.dwControlsAccepted = m_status.dwControlsAccepted|SERVICE_ACCEPT_PAUSE_CONTINUE;
HRESULT hr = __super::PreMessageLoop(nShowCmd);
if (hr == S_FALSE)
{
hr = S_OK;
}
//将服务状态设置为启动
SetServiceStatus(SERVICE_RUNNING);
//写入系统日志
LogEvent(L"ATLDemo Service Start Successfully~!");
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
bool ret;
ret=OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
if(!ret)
LogEvent(L"获取令牌句柄失败!!");
LUID Luid;
ret= LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME ,&Luid);
if(!ret)
LogEvent(L"获取Luid失败");
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkp.Privileges[0].Luid=Luid;
//AdjustTokenPrivileges(hToken, FALSE, &tkp,sizeof(TOKEN_PRIVILEGES),NULL, NULL);
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES)NULL, 0);
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
LogEvent(L"修改特权失败");
}
if(GetLastError()== ERROR_SUCCESS) //修改权限成功
{
LogEvent(L"修改特权成功");
//ShellExecute(NULL, L"Open", L"C:\\Users\\Administrator\\Desktop\\NCG00.txt", NULL, NULL, SW_SHOWNORMAL);
}
return hr;
}
void CATLdemoModule::Handler( DWORD dwOpcode ) throw()
{
switch(dwOpcode)
{
case SERVICE_CONTROL_PAUSE://暂停
{
OnPause();
break;
}
case SERVICE_CONTROL_CONTINUE://继续
{
OnContinue();
break;
}
default:
break;
}
__super::Handler(dwOpcode);
}
void CATLdemoModule::OnPause() throw()
{
//设置服务状态为暂停
SetServiceStatus(SERVICE_PAUSED);
__super::OnPause();
}
void CATLdemoModule::OnStop() throw()
{
//设置服务状态为停止
SetServiceStatus(SERVICE_STOPPED);
__super::OnStop();
}
void CATLdemoModule::OnContinue() throw()
{
//设置服务状态为启动
SetServiceStatus(SERVICE_RUNNING);
__super::OnContinue();
}
BOOL CATLdemoModule::Install() throw()
{
if (IsInstalled())
return TRUE;
// Get the executable file path
TCHAR szFilePath[MAX_PATH + _ATL_QUOTES_SPACE];
DWORD dwFLen = ::GetModuleFileName(NULL, szFilePath + 1, MAX_PATH);
if( dwFLen == 0 || dwFLen == MAX_PATH )
return FALSE;
// Quote the FilePath before calling CreateService
szFilePath[0] = _T('\"');
szFilePath[dwFLen + 1] = _T('\"');
szFilePath[dwFLen + 2] = 0;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL){
LogEvent(L"打开SCM失败");
}
//创建服务
LogEvent(L"进入Install");
SC_HANDLE hService = ::CreateService(
hSCM, L"supsys",L"Support System",
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, _T("RPCSS\0"), NULL, NULL);
if (hService == NULL)
{
DWORD error=GetLastError();
//LogEvent((LPCTSTR)error);
::CloseServiceHandle(hSCM);
LogEvent(L"CreateService failure");
return FALSE;
}
LogEvent(L"CreateService successful");
///
hSCM = ::OpenSCManager(NULL,NULL,SERVICE_CHANGE_CONFIG);
hService=::OpenService(hSCM,L"supsys",SERVICE_CHANGE_CONFIG);
if(hService==NULL)
LogEvent(L"123");
SERVICE_DESCRIPTION sDescription;
TCHAR szDescription[1024];
ZeroMemory(szDescription,1024);
ZeroMemory(&sDescription,sizeof(SERVICE_DESCRIPTION));
//服务描述
lstrcpy(szDescription,L"windows服务支持!");
sDescription.lpDescription = szDescription;
//修改服务描述信息
ChangeServiceConfig2(hService,SERVICE_CONFIG_DESCRIPTION,&sDescription);
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return TRUE;
}
bool CATLdemoModule::Count_Time()
{
SYSTEMTIME sys;//获取系统时间
GetLocalTime( &sys );
Date Current_Time;
Current_Time.i_year=sys.wYear;
Current_Time.i_month=sys.wMonth;
Current_Time.i_day=sys.wDay;
while(1){
int i=Pay_time.i_day-Current_Time.i_day;
if(i>=0&&i<3)
{//show the warning;
}
else if(i<0)
{//kill the process;
}
}
}
//共享内存获得变量
int CATLdemoModule::Share_Memory()
{
int nRetCode = 0;
while(1){
HANDLE hMapping = OpenFileMapping(FILE_MAP_ALL_ACCESS,NULL,L"Global\\ShareMemory");
if (hMapping)
{
LogEvent(L"Success Share_Memory");
LPVOID lpBase = MapViewOfFile(hMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
char szBuffer[5] = {0};
strcpy(szBuffer,(char*)lpBase);
if(!strcmp(szBuffer,"true")){
LogEvent(L"true");
}
UnmapViewOfFile(lpBase);
CloseHandle(hMapping);
nRetCode=1;
OnStop();
break;
}
else
{
LogEvent(L"OpenMapping Error");
}
}
return nRetCode;
}
bool CATLdemoModule::QuerySerStatu(){
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);//打开SCmanager
if (!schSCManager)//打开失败
{
LogEvent(L"OpenSCManager failed w/err 0x%08lx\n", GetLastError());
return false;
}
LPCTSTR MySer_Name=L"ZhuDongFangYu";
SC_HANDLE schService = OpenService(schSCManager, MySer_Name, //打开服务
SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
if (NULL != schService)//服务存在
{
LogEvent(L"主动防御 was installed.\n");
DWORD cbBytesNeeded;
//
// Query the status of the service
//
SERVICE_STATUS_PROCESS ssp;
if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
sizeof(ssp), &cbBytesNeeded))
{
LogEvent(L"Service status: ");
if(ssp.dwCurrentState==SERVICE_RUNNING)//正在运行返回true
{
::CloseServiceHandle(schSCManager);
::CloseServiceHandle(schService);
return true;
}
else
{
::CloseServiceHandle(schSCManager);
::CloseServiceHandle(schService);
return false;
}
//switch (ssp.dwCurrentState)
//{
//case SERVICE_STOPPED: _putws(L"Stopped"); break;
//case SERVICE_RUNNING: _putws(L"Running"); break;
//case SERVICE_PAUSED: _putws(L"Paused"); break;
//case SERVICE_START_PENDING:
//case SERVICE_STOP_PENDING:
//case SERVICE_CONTINUE_PENDING:
//case SERVICE_PAUSE_PENDING: _putws(L"Pending"); break;
//}
}
else
{
LogEvent(L"QueryServiceStatusEx failed w/err 0x%08lx\n", GetLastError());
}
::CloseServiceHandle(schSCManager);
::CloseServiceHandle(schService);
}
else//服务不存在返回flase
{
LogEvent(L"主动防御 was unstalled.\n");
::CloseServiceHandle(schSCManager);
::CloseServiceHandle(schService);
return false;
}
}
void CATLdemoModule::CreateCmd(){
}
以上可以说实现了一个最基本的服务程序,服务程序不能直接debug,要先生成(注意生成时如果这个服务正在运行或已经注册将会失败)
让服务注册运行的cmd命令为
d:
cd D:\work project\me\daima\ATLdemo\Debug
atldemo.exe /service
net start supsys
删除服务的命令为
atldemo /unregserver
或
sc delete atldemo