381 lines
11 KiB
C++
381 lines
11 KiB
C++
|
#include "Packet.h"
|
|||
|
|
|||
|
#include <iostream>
|
|||
|
#include <stdio.h>
|
|||
|
#include <fstream>
|
|||
|
#include <Windows.h>
|
|||
|
#include <string>
|
|||
|
#include <tlhelp32.h>
|
|||
|
#include <sstream>
|
|||
|
#include <tchar.h>
|
|||
|
#include "easylog/easylogging++.h"
|
|||
|
|
|||
|
INITIALIZE_EASYLOGGINGPP
|
|||
|
|
|||
|
|
|||
|
// Windows服务的服务名
|
|||
|
TCHAR SERVICE_NAME[] = _T("MyPcap");
|
|||
|
SERVICE_STATUS_HANDLE g_ServiceStatusHandle;
|
|||
|
SERVICE_STATUS g_ServiceStatus;
|
|||
|
DWORD g_ThreadID;
|
|||
|
std::wofstream g_ofs;
|
|||
|
|
|||
|
// 服务主函数
|
|||
|
VOID WINAPI ServiceMain(DWORD argc, LPWSTR* argv);
|
|||
|
|
|||
|
// 服务控制处理函数
|
|||
|
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode);
|
|||
|
|
|||
|
|
|||
|
void EasyLogConf()
|
|||
|
{
|
|||
|
//加载默认配置 init log
|
|||
|
el::Configurations conf;
|
|||
|
//设置为默认
|
|||
|
conf.setToDefault();
|
|||
|
//设置日志输出格式
|
|||
|
conf.setGlobally(el::ConfigurationType::Format, "%datetime %level [%fbase|%line] %msg");
|
|||
|
//设置日志文件目录以及文件名
|
|||
|
conf.setGlobally(el::ConfigurationType::Filename, "logs\\%datetime{%Y%M%d}.log");
|
|||
|
//启用日志
|
|||
|
conf.setGlobally(el::ConfigurationType::Enabled, "true");
|
|||
|
//是否写入文件
|
|||
|
conf.setGlobally(el::ConfigurationType::ToFile, "true");
|
|||
|
//是否输出控制台
|
|||
|
conf.setGlobally(el::ConfigurationType::ToStandardOutput, "false");
|
|||
|
|
|||
|
//设置配置文件
|
|||
|
el::Loggers::reconfigureAllLoggers(conf); //加载配置文件
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
std::wstring GetStrNow()
|
|||
|
{
|
|||
|
wchar_t buffer[128];
|
|||
|
SYSTEMTIME snow;
|
|||
|
GetLocalTime(&snow);
|
|||
|
swprintf_s(buffer, sizeof(buffer), L"%04d-%02d-%02d %02d:%02d:%02d", snow.wYear, snow.wMonth, snow.wDay, snow.wHour, snow.wMinute, snow.wSecond);
|
|||
|
return std::wstring(buffer);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void LogEvent(LPTSTR chmsg) {
|
|||
|
HANDLE hEventSource;
|
|||
|
LPTSTR lpszStrings[1];
|
|||
|
|
|||
|
lpszStrings[0] = chmsg;
|
|||
|
|
|||
|
hEventSource = RegisterEventSource(NULL, SERVICE_NAME);
|
|||
|
if (hEventSource != NULL)
|
|||
|
{
|
|||
|
ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*)&lpszStrings[0], NULL);
|
|||
|
DeregisterEventSource(hEventSource);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int execCmdUseGetline(const char* cmd, std::wofstream& ofs)
|
|||
|
{
|
|||
|
FILE* pipe = _popen(cmd, "r");
|
|||
|
if (!pipe)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|||
|
wchar_t buf[512] = { 0 };
|
|||
|
ofs << GetStrNow() << "\n";
|
|||
|
ofs.flush();
|
|||
|
while (fgetws(buf, 512, pipe) != NULL)
|
|||
|
{
|
|||
|
if (snapshot == INVALID_HANDLE_VALUE) {
|
|||
|
ofs << buf;
|
|||
|
ofs.flush();
|
|||
|
}
|
|||
|
else {
|
|||
|
std::wstring str(buf);
|
|||
|
int frel = str.find(L"TCP");
|
|||
|
int fre2 = str.find(L"UDP");
|
|||
|
if (frel != -1)
|
|||
|
{
|
|||
|
std::wistringstream iss(str);
|
|||
|
std::wstring protocol, localAddress, remoteAddress, state, processName;
|
|||
|
int processId;
|
|||
|
iss >> protocol >> localAddress >> remoteAddress >> state >> processId;
|
|||
|
|
|||
|
PROCESSENTRY32 processEntry;
|
|||
|
processEntry.dwSize = sizeof(PROCESSENTRY32);
|
|||
|
// 遍历进程列表
|
|||
|
if (Process32First(snapshot, &processEntry)) {
|
|||
|
do {
|
|||
|
// 如果找到目标进程,则返回其名称
|
|||
|
if (processEntry.th32ProcessID == processId) {
|
|||
|
processName = processEntry.szExeFile;
|
|||
|
break;
|
|||
|
}
|
|||
|
} while (Process32Next(snapshot, &processEntry));
|
|||
|
}
|
|||
|
ofs << protocol << "," << localAddress << "," << remoteAddress << "," << state << "," << processId << "," << processName << "\n";
|
|||
|
ofs.flush();
|
|||
|
}
|
|||
|
if (fre2 != -1) {
|
|||
|
std::wistringstream iss(str);
|
|||
|
std::wstring protocol, localAddress, remoteAddress, processName;
|
|||
|
int processId;
|
|||
|
// 读取并输出每个单词
|
|||
|
iss >> protocol >> localAddress >> remoteAddress >> processId >> processName;
|
|||
|
PROCESSENTRY32 processEntry;
|
|||
|
processEntry.dwSize = sizeof(PROCESSENTRY32);
|
|||
|
// 遍历进程列表
|
|||
|
if (Process32First(snapshot, &processEntry)) {
|
|||
|
do {
|
|||
|
// 如果找到目标进程,则返回其名称
|
|||
|
if (processEntry.th32ProcessID == processId) {
|
|||
|
processName = processEntry.szExeFile;
|
|||
|
break;
|
|||
|
}
|
|||
|
} while (Process32Next(snapshot, &processEntry));
|
|||
|
}
|
|||
|
ofs << protocol << "," << localAddress << "," << remoteAddress << "," << "none" << "," << processId << "," << processName << "\n";
|
|||
|
ofs.flush();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
ofs << "\n";
|
|||
|
ofs.flush();
|
|||
|
_pclose(pipe);
|
|||
|
if (snapshot != INVALID_HANDLE_VALUE)CloseHandle(snapshot);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
int ConsoleMain()
|
|||
|
{
|
|||
|
LOG(DEBUG) << "SimpleService: Service is running..." ;
|
|||
|
Packet* pk = new Packet();
|
|||
|
LOG(DEBUG) << "packet new" << std::endl;
|
|||
|
pk->Init();
|
|||
|
pk->Run();
|
|||
|
LOG(DEBUG) << "packet end" << std::endl;
|
|||
|
delete pk;
|
|||
|
pk = nullptr;
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
VOID WINAPI ServiceMain(DWORD argc, LPWSTR* argv)
|
|||
|
{
|
|||
|
LOG(DEBUG) << "ServiceMain START...";
|
|||
|
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
|
|||
|
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
|||
|
// 注册服务控制处理函数
|
|||
|
g_ServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
|
|||
|
if (g_ServiceStatusHandle == NULL)
|
|||
|
{
|
|||
|
LOG(ERROR) << "Handler not install";
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
|
|||
|
|
|||
|
g_ServiceStatus.dwWin32ExitCode = S_OK;
|
|||
|
g_ServiceStatus.dwCheckPoint = 0;
|
|||
|
g_ServiceStatus.dwWaitHint = 0;
|
|||
|
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
|
|||
|
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
|
|||
|
|
|||
|
// 在 ServiceMain 中调用控制台程序的主函数
|
|||
|
ConsoleMain();
|
|||
|
|
|||
|
// 设置服务状态为停止
|
|||
|
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
|||
|
g_ServiceStatus.dwCheckPoint = 0;
|
|||
|
g_ServiceStatus.dwWaitHint = 0;
|
|||
|
|
|||
|
if (!SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus)){
|
|||
|
LOG(ERROR) << "SetServiceStatus failed, error code: " << GetLastError();
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
void Init()
|
|||
|
{
|
|||
|
g_ServiceStatusHandle = NULL;
|
|||
|
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
|
|||
|
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
|
|||
|
g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
|||
|
g_ServiceStatus.dwWin32ExitCode = 0;
|
|||
|
g_ServiceStatus.dwServiceSpecificExitCode = 0;
|
|||
|
g_ServiceStatus.dwCheckPoint = 0;
|
|||
|
g_ServiceStatus.dwWaitHint = 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
bool IsInstalled()
|
|||
|
{
|
|||
|
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
|||
|
if (hSCM == NULL) {
|
|||
|
LOG(ERROR) << "OpenSCManager error..."<<GetLastError();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
SC_HANDLE hService = ::OpenService(hSCM, SERVICE_NAME, SERVICE_QUERY_CONFIG);
|
|||
|
if (hService == NULL) {
|
|||
|
::CloseServiceHandle(hSCM);
|
|||
|
LOG(ERROR) << "OpenService error..."<<GetLastError() ;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
::CloseServiceHandle(hService);
|
|||
|
::CloseServiceHandle(hSCM);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
bool Install()
|
|||
|
{
|
|||
|
if (IsInstalled())return true;
|
|||
|
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
|||
|
if (hSCM == NULL)return false;
|
|||
|
TCHAR szFilePath[MAX_PATH];
|
|||
|
::GetModuleFileName(NULL, szFilePath, MAX_PATH);
|
|||
|
|
|||
|
SC_HANDLE hService = ::CreateService(hSCM, SERVICE_NAME, SERVICE_NAME, SERVICE_ALL_ACCESS,
|
|||
|
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
|
|||
|
szFilePath, NULL, NULL, _T(""), NULL, NULL);
|
|||
|
if (hService == NULL) {
|
|||
|
::CloseServiceHandle(hSCM);
|
|||
|
LOG(ERROR) << "CreateService false...";
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// 创建服务后立即启动
|
|||
|
if (!StartService(hService, 0, NULL)){
|
|||
|
LOG(ERROR) << " StartService false...";
|
|||
|
}
|
|||
|
else {
|
|||
|
printf("服务启动成功...");
|
|||
|
LOG(DEBUG) << " 服务启动成功...";
|
|||
|
}
|
|||
|
|
|||
|
// 设置延迟自动启动信息
|
|||
|
SERVICE_DELAYED_AUTO_START_INFO delayedStartInfo{};
|
|||
|
delayedStartInfo.fDelayedAutostart = TRUE;
|
|||
|
|
|||
|
// 修改服务配置 设置为延迟启动(开机1-2分钟内启动,否则自动启动会报错)
|
|||
|
if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &delayedStartInfo)) {
|
|||
|
LOG(ERROR) << "Failed to change service configuration";
|
|||
|
}
|
|||
|
|
|||
|
::CloseServiceHandle(hService);
|
|||
|
::CloseServiceHandle(hSCM);
|
|||
|
LOG(DEBUG) << "Install end...";
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
bool Uninstall()
|
|||
|
{
|
|||
|
SC_HANDLE schSCManager;
|
|||
|
SC_HANDLE schService;
|
|||
|
|
|||
|
schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
|||
|
if (schSCManager == NULL){
|
|||
|
std::cout << "打开SCManager失败:" << GetLastError() << std::endl;
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
schService = OpenService(schSCManager, TEXT("MyPcap"), SERVICE_ALL_ACCESS);
|
|||
|
if (schService == NULL) {
|
|||
|
std::cout << "打开服务失败:" << GetLastError() << std::endl;
|
|||
|
CloseServiceHandle(schSCManager);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool result = true;
|
|||
|
SERVICE_STATUS status;
|
|||
|
::ControlService(schService, SERVICE_CONTROL_STOP, &status);
|
|||
|
if (!DeleteService(schService)){
|
|||
|
std::cout << "删除服务失败:" << GetLastError() << std::endl;
|
|||
|
result = false;
|
|||
|
}
|
|||
|
else{
|
|||
|
printf("服务删除成功");
|
|||
|
}
|
|||
|
|
|||
|
CloseServiceHandle(schService);
|
|||
|
CloseServiceHandle(schSCManager);
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
|
|||
|
{
|
|||
|
switch (CtrlCode)
|
|||
|
{
|
|||
|
case SERVICE_CONTROL_STOP:
|
|||
|
//设置服务状态为停止
|
|||
|
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
|
|||
|
g_ServiceStatus.dwCheckPoint = 1;
|
|||
|
|
|||
|
if (!SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus))
|
|||
|
{
|
|||
|
std::cerr << "SetServiceStatus failed, error code: " << GetLastError() << std::endl;
|
|||
|
}
|
|||
|
Sleep(500);
|
|||
|
// 设置服务状态为停止
|
|||
|
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
|
|||
|
g_ServiceStatus.dwCheckPoint = 0;
|
|||
|
g_ServiceStatus.dwWaitHint = 0;
|
|||
|
|
|||
|
if (!SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus))
|
|||
|
{
|
|||
|
std::cerr << "SetServiceStatus failed, error code: " << GetLastError() << std::endl;
|
|||
|
}
|
|||
|
|
|||
|
PostThreadMessage(g_ThreadID, WM_CLOSE, 0, 0);
|
|||
|
break;
|
|||
|
case SERVICE_CONTROL_SHUTDOWN:
|
|||
|
exit(0);
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
int APIENTRY _tWinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){
|
|||
|
EasyLogConf(); //easylog配置
|
|||
|
|
|||
|
Init();
|
|||
|
g_ThreadID = ::GetCurrentThreadId();
|
|||
|
SERVICE_TABLE_ENTRY ServiceTable[] =
|
|||
|
{
|
|||
|
{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTIONW)ServiceMain },
|
|||
|
{ NULL, NULL }
|
|||
|
};
|
|||
|
|
|||
|
if (_wcsicmp(lpCmdLine, _T("/install")) == 0)
|
|||
|
{
|
|||
|
LOG(DEBUG) << "install start...";
|
|||
|
Install();
|
|||
|
}
|
|||
|
else if (_wcsicmp(lpCmdLine, _T("/uninstall")) == 0)
|
|||
|
{
|
|||
|
LOG(DEBUG) << "uninstall start...";
|
|||
|
if (!Uninstall()) {
|
|||
|
LOG(DEBUG) << "uninstall error(" << GetLastError() << ")...";
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
LOG(DEBUG) << "start...";
|
|||
|
if (!::StartServiceCtrlDispatcher(ServiceTable))
|
|||
|
{
|
|||
|
LOG(DEBUG) << "start error(" << GetLastError() << ")...";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
}
|